mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2025-12-09 04:53:30 +08:00
WIP
This commit is contained in:
@@ -61,8 +61,7 @@ public static class BuildPatch
|
||||
{
|
||||
if (_noConditionPatch != null)
|
||||
{
|
||||
_noConditionPatch.UnpatchSelf();
|
||||
_noConditionPatch = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_noConditionPatch = Harmony.CreateAndPatchAll(typeof(NoConditionBuild));
|
||||
@@ -128,8 +127,7 @@ public static class BuildPatch
|
||||
{
|
||||
if (_immediatePatch != null)
|
||||
{
|
||||
_immediatePatch.UnpatchSelf();
|
||||
_immediatePatch = null;
|
||||
return;
|
||||
}
|
||||
|
||||
var factory = GameMain.mainPlayer?.factory;
|
||||
@@ -178,8 +176,7 @@ public static class BuildPatch
|
||||
{
|
||||
if (_noCostPatch != null)
|
||||
{
|
||||
_noCostPatch.UnpatchSelf();
|
||||
_noCostPatch = null;
|
||||
return;
|
||||
}
|
||||
|
||||
var factory = GameMain.mainPlayer?.factory;
|
||||
@@ -223,6 +220,13 @@ public static class BuildPatch
|
||||
}
|
||||
if (itemId < 10000 && _canBuildItems[itemId]) __result = 100;
|
||||
}
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(PlayerAction_Inspect), nameof(PlayerAction_Inspect.GetObjectSelectDistance))]
|
||||
private static IEnumerable<CodeInstruction> PlayerAction_Inspect_GetObjectSelectDistance_Transpiler(IEnumerable<CodeInstruction> instructions)
|
||||
{
|
||||
yield return new CodeInstruction(OpCodes.Ldc_R4, 10000f);
|
||||
yield return new CodeInstruction(OpCodes.Ret);
|
||||
}
|
||||
|
||||
private static void DoInit()
|
||||
{
|
||||
|
||||
@@ -33,6 +33,8 @@ public class CheatEnabler : BaseUnityPlugin
|
||||
DevShortcuts.Enabled = Config.Bind("General", "DevShortcuts", false, "Enable DevMode shortcuts");
|
||||
AbnormalDisabler.Enabled = Config.Bind("General", "DisableAbnormalChecks", false,
|
||||
"disable all abnormal checks");
|
||||
TechPatch.Enabled = Config.Bind("General", "UnlockTech", false,
|
||||
"Unlock clicked tech by holding key-modifilers(Shift/Alt/Ctrl)");
|
||||
BuildPatch.ImmediateEnabled = Config.Bind("Build", "ImmediateBuild", false,
|
||||
"Build immediately");
|
||||
BuildPatch.NoCostEnabled = Config.Bind("Build", "InfiniteBuildings", false,
|
||||
@@ -57,6 +59,10 @@ public class CheatEnabler : BaseUnityPlugin
|
||||
"Quick absorb");
|
||||
DysonSpherePatch.EjectAnywayEnabled = Config.Bind("DysonSphere", "EjectAnyway", false,
|
||||
"Eject anyway");
|
||||
DysonSpherePatch.OverclockEjectorEnabled = Config.Bind("DysonSphere", "OverclockEjector", false,
|
||||
"Overclock ejector");
|
||||
DysonSpherePatch.OverclockSiloEnabled = Config.Bind("DysonSphere", "OverclockSilo", false,
|
||||
"Overclock silo");
|
||||
BirthPlanetPatch.SitiVeinsOnBirthPlanet = Config.Bind("Birth", "SiTiVeinsOnBirthPlanet", false,
|
||||
"Silicon/Titanium on birth planet");
|
||||
BirthPlanetPatch.FireIceOnBirthPlanet = Config.Bind("Birth", "FireIceOnBirthPlanet", false,
|
||||
@@ -77,8 +83,6 @@ 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;
|
||||
|
||||
I18N.Init();
|
||||
I18N.Add("CheatEnabler Config", "CheatEnabler Config", "CheatEnabler设置");
|
||||
@@ -90,23 +94,13 @@ public class CheatEnabler : BaseUnityPlugin
|
||||
|
||||
DevShortcuts.Init();
|
||||
AbnormalDisabler.Init();
|
||||
TechPatch.Init();
|
||||
BuildPatch.Init();
|
||||
ResourcePatch.Init();
|
||||
WaterPumperPatch.Init();
|
||||
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));
|
||||
// }
|
||||
}
|
||||
|
||||
public void OnDestroy()
|
||||
@@ -117,6 +111,7 @@ public class CheatEnabler : BaseUnityPlugin
|
||||
WaterPumperPatch.Uninit();
|
||||
ResourcePatch.Uninit();
|
||||
BuildPatch.Uninit();
|
||||
TechPatch.Uninit();
|
||||
AbnormalDisabler.Uninit();
|
||||
DevShortcuts.Uninit();
|
||||
_patch?.UnpatchSelf();
|
||||
@@ -229,94 +224,4 @@ public class CheatEnabler : BaseUnityPlugin
|
||||
_configWin.Open();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private class UnlockTechOnGameStart
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameScenarioLogic), "NotifyOnGameBegin")]
|
||||
private static void UnlockTechPatch()
|
||||
{
|
||||
var history = GameMain.history;
|
||||
if (GameMain.mainPlayer == null || GameMain.mainPlayer.mecha == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var currentTech in TechToUnlock)
|
||||
{
|
||||
UnlockTechRecursive(history, currentTech, currentTech == 3606 ? 7000 : 10000);
|
||||
}
|
||||
|
||||
var techQueue = history.techQueue;
|
||||
if (techQueue == null || techQueue.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
history.VarifyTechQueue();
|
||||
if (history.currentTech > 0 && history.currentTech != techQueue[0])
|
||||
{
|
||||
history.AlterCurrentTech(techQueue[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void UnlockTechRecursive(GameHistoryData history, int currentTech, int maxLevel = 10000)
|
||||
{
|
||||
var techStates = history.techStates;
|
||||
if (techStates == null || !techStates.ContainsKey(currentTech))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var techProto = LDB.techs.Select(currentTech);
|
||||
if (techProto == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var value = techStates[currentTech];
|
||||
var maxLvl = Math.Min(maxLevel, value.maxLevel);
|
||||
if (value.unlocked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var preid in techProto.PreTechs)
|
||||
{
|
||||
UnlockTechRecursive(history, preid, maxLevel);
|
||||
}
|
||||
|
||||
var techQueue = history.techQueue;
|
||||
if (techQueue != null)
|
||||
{
|
||||
for (var i = 0; i < techQueue.Length; i++)
|
||||
{
|
||||
if (techQueue[i] == currentTech)
|
||||
{
|
||||
techQueue[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value.curLevel < techProto.Level) value.curLevel = techProto.Level;
|
||||
while (value.curLevel <= maxLvl)
|
||||
{
|
||||
for (var j = 0; j < techProto.UnlockFunctions.Length; j++)
|
||||
{
|
||||
history.UnlockTechFunction(techProto.UnlockFunctions[j], techProto.UnlockValues[j], value.curLevel);
|
||||
}
|
||||
|
||||
value.curLevel++;
|
||||
}
|
||||
|
||||
value.unlocked = maxLvl >= value.maxLevel;
|
||||
value.curLevel = value.unlocked ? maxLvl : maxLvl + 1;
|
||||
value.hashNeeded = techProto.GetHashNeeded(value.curLevel);
|
||||
value.hashUploaded = value.unlocked ? value.hashNeeded : 0;
|
||||
techStates[currentTech] = value;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,14 @@ public static class DysonSpherePatch
|
||||
public static ConfigEntry<bool> SkipAbsorbEnabled;
|
||||
public static ConfigEntry<bool> QuickAbsortEnabled;
|
||||
public static ConfigEntry<bool> EjectAnywayEnabled;
|
||||
public static ConfigEntry<bool> OverclockEjectorEnabled;
|
||||
public static ConfigEntry<bool> OverclockSiloEnabled;
|
||||
private static Harmony _skipBulletPatch;
|
||||
private static Harmony _skipAbsorbPatch;
|
||||
private static Harmony _quickAbsortPatch;
|
||||
private static Harmony _ejectAnywayPatch;
|
||||
private static Harmony _overclockEjector;
|
||||
private static Harmony _overclockSilo;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
@@ -23,10 +27,14 @@ public static class DysonSpherePatch
|
||||
SkipAbsorbEnabled.SettingChanged += (_, _) => SkipAbsorbValueChanged();
|
||||
QuickAbsortEnabled.SettingChanged += (_, _) => QuickAbsortValueChanged();
|
||||
EjectAnywayEnabled.SettingChanged += (_, _) => EjectAnywayValueChanged();
|
||||
OverclockEjectorEnabled.SettingChanged += (_, _) => OverclockEjectorValueChanged();
|
||||
OverclockSiloEnabled.SettingChanged += (_, _) => OverclockSiloValueChanged();
|
||||
SkipBulletValueChanged();
|
||||
SkipAbsorbValueChanged();
|
||||
QuickAbsortValueChanged();
|
||||
EjectAnywayValueChanged();
|
||||
OverclockEjectorValueChanged();
|
||||
OverclockSiloValueChanged();
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
@@ -51,6 +59,16 @@ public static class DysonSpherePatch
|
||||
_ejectAnywayPatch.UnpatchSelf();
|
||||
_ejectAnywayPatch = null;
|
||||
}
|
||||
if (_overclockEjector != null)
|
||||
{
|
||||
_overclockEjector.UnpatchSelf();
|
||||
_overclockEjector = null;
|
||||
}
|
||||
if (_overclockSilo != null)
|
||||
{
|
||||
_overclockSilo.UnpatchSelf();
|
||||
_overclockSilo = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SkipBulletValueChanged()
|
||||
@@ -59,10 +77,8 @@ public static class DysonSpherePatch
|
||||
{
|
||||
if (_skipBulletPatch != null)
|
||||
{
|
||||
_skipBulletPatch.UnpatchSelf();
|
||||
_skipBulletPatch = null;
|
||||
return;
|
||||
}
|
||||
|
||||
SkipBulletPatch.UpdateSailLifeTime();
|
||||
SkipBulletPatch.UpdateSailsCacheForThisGame();
|
||||
_skipBulletPatch = Harmony.CreateAndPatchAll(typeof(SkipBulletPatch));
|
||||
@@ -80,8 +96,7 @@ public static class DysonSpherePatch
|
||||
{
|
||||
if (_skipAbsorbPatch != null)
|
||||
{
|
||||
_skipAbsorbPatch.UnpatchSelf();
|
||||
_skipAbsorbPatch = null;
|
||||
return;
|
||||
}
|
||||
_skipAbsorbPatch = Harmony.CreateAndPatchAll(typeof(SkipAbsorbPatch));
|
||||
}
|
||||
@@ -98,8 +113,7 @@ public static class DysonSpherePatch
|
||||
{
|
||||
if (_quickAbsortPatch != null)
|
||||
{
|
||||
_quickAbsortPatch.UnpatchSelf();
|
||||
_quickAbsortPatch = null;
|
||||
return;
|
||||
}
|
||||
_quickAbsortPatch = Harmony.CreateAndPatchAll(typeof(QuickAbsortPatch));
|
||||
}
|
||||
@@ -116,8 +130,7 @@ public static class DysonSpherePatch
|
||||
{
|
||||
if (_ejectAnywayPatch != null)
|
||||
{
|
||||
_ejectAnywayPatch.UnpatchSelf();
|
||||
_ejectAnywayPatch = null;
|
||||
return;
|
||||
}
|
||||
_ejectAnywayPatch = Harmony.CreateAndPatchAll(typeof(EjectAnywayPatch));
|
||||
}
|
||||
@@ -127,6 +140,40 @@ public static class DysonSpherePatch
|
||||
_ejectAnywayPatch = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void OverclockEjectorValueChanged()
|
||||
{
|
||||
if (OverclockEjectorEnabled.Value)
|
||||
{
|
||||
if (_overclockEjector != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_overclockEjector = Harmony.CreateAndPatchAll(typeof(OverclockEjector));
|
||||
}
|
||||
else if (_overclockEjector != null)
|
||||
{
|
||||
_overclockEjector.UnpatchSelf();
|
||||
_overclockEjector = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void OverclockSiloValueChanged()
|
||||
{
|
||||
if (OverclockSiloEnabled.Value)
|
||||
{
|
||||
if (_overclockSilo != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_overclockSilo = Harmony.CreateAndPatchAll(typeof(OverclockSilo));
|
||||
}
|
||||
else if (_overclockSilo != null)
|
||||
{
|
||||
_overclockSilo.UnpatchSelf();
|
||||
_overclockSilo = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void InitCurrentDysonSphere(int index)
|
||||
{
|
||||
@@ -431,4 +478,110 @@ public static class DysonSpherePatch
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
}
|
||||
|
||||
private static class OverclockEjector
|
||||
{
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(EjectorComponent), nameof(EjectorComponent.InternalUpdate))]
|
||||
private static IEnumerable<CodeInstruction> EjectAndSiloComponent_InternalUpdate_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
/* Add a multiply to ejector speed */
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Stloc_1)
|
||||
).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldc_I4_S, 10),
|
||||
new CodeInstruction(OpCodes.Mul)
|
||||
).Advance(1);
|
||||
|
||||
/* remove boost part of Sandbox Mode for better performance */
|
||||
var pos = matcher.Pos;
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Stloc_1)
|
||||
).Advance(1);
|
||||
var end = matcher.Pos;
|
||||
matcher.Start().Advance(pos).RemoveInstructions(end - pos);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(UIEjectorWindow), nameof(UIEjectorWindow._OnUpdate))]
|
||||
private static IEnumerable<CodeInstruction> UIEjectAndSiloWindow__OnUpdate_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
/* Add a multiply to ejector speed */
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(typeof(Cargo), nameof(Cargo.accTableMilli)))
|
||||
).Advance(-1);
|
||||
var operand = matcher.Operand;
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Stloc_S, operand)
|
||||
).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldc_R4, 10f),
|
||||
new CodeInstruction(OpCodes.Mul)
|
||||
).Advance(1);
|
||||
|
||||
/* remove boost part of Sandbox Mode for better performance */
|
||||
var pos = matcher.Pos;
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Stloc_S, operand)
|
||||
).Advance(1);
|
||||
var end = matcher.Pos;
|
||||
matcher.Start().Advance(pos).RemoveInstructions(end - pos);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
}
|
||||
|
||||
private static class OverclockSilo
|
||||
{
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(SiloComponent), nameof(SiloComponent.InternalUpdate))]
|
||||
private static IEnumerable<CodeInstruction> EjectAndSiloComponent_InternalUpdate_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
/* Add a multiply to ejector speed */
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Stloc_1)
|
||||
).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldc_I4_S, 10),
|
||||
new CodeInstruction(OpCodes.Mul)
|
||||
).Advance(1);
|
||||
|
||||
/* remove boost part of Sandbox Mode for better performance */
|
||||
var pos = matcher.Pos;
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Stloc_1)
|
||||
).Advance(1);
|
||||
var end = matcher.Pos;
|
||||
matcher.Start().Advance(pos).RemoveInstructions(end - pos);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(UISiloWindow), nameof(UISiloWindow._OnUpdate))]
|
||||
private static IEnumerable<CodeInstruction> UIEjectAndSiloWindow__OnUpdate_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
/* Add a multiply to ejector speed */
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(typeof(Cargo), nameof(Cargo.accTableMilli)))
|
||||
).Advance(-1);
|
||||
var operand = matcher.Operand;
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Stloc_S, operand)
|
||||
).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldc_R4, 10f),
|
||||
new CodeInstruction(OpCodes.Mul)
|
||||
).Advance(1);
|
||||
|
||||
/* remove boost part of Sandbox Mode for better performance */
|
||||
var pos = matcher.Pos;
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Stloc_S, operand)
|
||||
).Advance(1);
|
||||
var end = matcher.Pos;
|
||||
matcher.Start().Advance(pos).RemoveInstructions(end - pos);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,11 +8,14 @@
|
||||
* Press `` LAlt+`(BackQuote) `` to call up the config panel. You can change the shortcut on the panel.
|
||||
* There are also buttons on title screen and planet minimap area to call up the config panel.
|
||||
* Features:
|
||||
+ Enable Dev Shortcuts (check config panel for usage)
|
||||
+ Disable Abnormal Checks
|
||||
+ Strict hotkey dectection for build menu, thus building hotkeys(0~9, F1~F10, X, U) are not triggered while holding Ctrl/Alt/Shift.
|
||||
+ General:
|
||||
+ Enable Dev Shortcuts (check config panel for usage)
|
||||
+ Disable Abnormal Checks
|
||||
+ Unlock techs with key-modifiers (Ctrl/Alt/Shift)
|
||||
+ Build:
|
||||
+ Finish build immediately
|
||||
+ Infinite buildings
|
||||
+ Architect mode (Infinite buildings + Interactive without distance limit)
|
||||
+ Build without condition
|
||||
+ No collision
|
||||
+ Planet:
|
||||
@@ -34,16 +37,25 @@
|
||||
+ Solid flat on birth planet
|
||||
+ High luminosity for birth star
|
||||
|
||||
## CREDITS
|
||||
* [Dyson Sphere Program](https://store.steampowered.com/app/1366540): The great game
|
||||
* [BepInEx](https://bepinex.dev/): Base modding framework
|
||||
* [Multifunction_mod](https://github.com/blacksnipebiu/Multifunction_mod): Some cheat functions
|
||||
* [LSTM](https://github.com/hetima/DSP_LSTM) & [PlanetFinder](https://github.com/hetima/DSP_PlanetFinder): UI implemnetations
|
||||
|
||||
## 使用说明
|
||||
|
||||
* 按 `` 左Alt+`(反引号) `` 键呼出主面板,可以在面板上修改快捷键。
|
||||
* 标题界面和行星小地图旁也有按钮呼出主面板。
|
||||
* 功能:
|
||||
+ 启用开发模式快捷键(使用说明见设置面板)
|
||||
+ 屏蔽异常检测
|
||||
+ 更严格的建造菜单热键检测,因此在按住Ctrl/Alt/Shift时不再会触发建造热键(0~9, F1~F10, X, U)。
|
||||
+ 常规:
|
||||
+ 启用开发模式快捷键(使用说明见设置面板)
|
||||
+ 屏蔽异常检测
|
||||
+ 使用组合键解锁科技(Ctrl/Alt/Shift)
|
||||
+ 建造:
|
||||
+ 建造秒完成
|
||||
+ 无限建筑
|
||||
+ 建筑师模式(无限建筑+无视距离操作)
|
||||
+ 无条件建造
|
||||
+ 无碰撞
|
||||
+ 行星:
|
||||
@@ -63,4 +75,10 @@
|
||||
+ 母星系:
|
||||
+ 母星有稀有资源
|
||||
+ 母星是纯平的
|
||||
+ 母星系恒星高亮
|
||||
+ 母星系恒星高亮
|
||||
|
||||
## 鸣谢
|
||||
* [戴森球计划](https://store.steampowered.com/app/1366540): 伟大的游戏
|
||||
* [BepInEx](https://bepinex.dev/): 基础模组框架
|
||||
* [Multifunction_mod](https://github.com/blacksnipebiu/Multifunction_mod): 一些作弊功能
|
||||
* [LSTM](https://github.com/hetima/DSP_LSTM) & [PlanetFinder](https://github.com/hetima/DSP_PlanetFinder): UI实现
|
||||
|
||||
@@ -41,8 +41,7 @@ public static class ResourcePatch
|
||||
{
|
||||
if (_infinitePatch != null)
|
||||
{
|
||||
_infinitePatch.UnpatchSelf();
|
||||
_infinitePatch = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_infinitePatch = Harmony.CreateAndPatchAll(typeof(InfiniteResource));
|
||||
@@ -59,8 +58,7 @@ public static class ResourcePatch
|
||||
{
|
||||
if (_fastPatch != null)
|
||||
{
|
||||
_fastPatch.UnpatchSelf();
|
||||
_fastPatch = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_fastPatch = Harmony.CreateAndPatchAll(typeof(FastMining));
|
||||
|
||||
161
CheatEnabler/TechPatch.cs
Normal file
161
CheatEnabler/TechPatch.cs
Normal file
@@ -0,0 +1,161 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection.Emit;
|
||||
using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace CheatEnabler;
|
||||
|
||||
public static class TechPatch
|
||||
{
|
||||
public static ConfigEntry<bool> Enabled;
|
||||
private static Harmony _patch;
|
||||
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
Enabled.SettingChanged += (_, _) => ValueChanged();
|
||||
ValueChanged();
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
{
|
||||
if (_patch == null) return;
|
||||
_patch.UnpatchSelf();
|
||||
_patch = null;
|
||||
}
|
||||
|
||||
private static void ValueChanged()
|
||||
{
|
||||
if (Enabled.Value)
|
||||
{
|
||||
if (_patch != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_patch = Harmony.CreateAndPatchAll(typeof(TechPatch));
|
||||
}
|
||||
else if (_patch != null)
|
||||
{
|
||||
_patch.UnpatchSelf();
|
||||
_patch = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void UnlockTechRecursive(TechProto proto, int maxLevel = 10000)
|
||||
{
|
||||
var history = GameMain.history;
|
||||
var techStates = history.techStates;
|
||||
var techID = proto.ID;
|
||||
if (techStates == null || !techStates.ContainsKey(techID))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var techProto = LDB.techs.Select(techID);
|
||||
if (techProto == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var value = techStates[techID];
|
||||
if (value.unlocked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var maxLvl = Math.Min(maxLevel < 0 ? value.curLevel - maxLevel - 1 : maxLevel, value.maxLevel);
|
||||
|
||||
foreach (var preid in techProto.PreTechs)
|
||||
{
|
||||
var preProto = LDB.techs.Select(preid);
|
||||
if (preProto != null)
|
||||
UnlockTechRecursive(preProto, maxLevel);
|
||||
}
|
||||
|
||||
var techQueue = history.techQueue;
|
||||
if (techQueue != null)
|
||||
{
|
||||
for (var i = 0; i < techQueue.Length; i++)
|
||||
{
|
||||
if (techQueue[i] == techID)
|
||||
{
|
||||
techQueue[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value.curLevel < techProto.Level) value.curLevel = techProto.Level;
|
||||
while (value.curLevel <= maxLvl)
|
||||
{
|
||||
if (value.curLevel == 0)
|
||||
{
|
||||
foreach (var recipe in techProto.UnlockRecipes)
|
||||
{
|
||||
history.UnlockRecipe(recipe);
|
||||
}
|
||||
}
|
||||
for (var j = 0; j < techProto.UnlockFunctions.Length; j++)
|
||||
{
|
||||
history.UnlockTechFunction(techProto.UnlockFunctions[j], techProto.UnlockValues[j], value.curLevel);
|
||||
}
|
||||
for (var k = 0; k < techProto.AddItems.Length; k++)
|
||||
{
|
||||
history.GainTechAwards(techProto.AddItems[k], techProto.AddItemCounts[k]);
|
||||
}
|
||||
value.curLevel++;
|
||||
}
|
||||
|
||||
value.unlocked = maxLvl >= value.maxLevel;
|
||||
value.curLevel = value.unlocked ? maxLvl : maxLvl + 1;
|
||||
value.hashNeeded = techProto.GetHashNeeded(value.curLevel);
|
||||
value.hashUploaded = value.unlocked ? value.hashNeeded : 0;
|
||||
techStates[techID] = value;
|
||||
history.RegFeatureKey(1000100);
|
||||
history.NotifyTechUnlock(techID, maxLvl, true);
|
||||
}
|
||||
|
||||
private static void OnClickTech(UITechNode node)
|
||||
{
|
||||
if (VFInput.shift)
|
||||
{
|
||||
if (VFInput.alt) return;
|
||||
if (VFInput.control)
|
||||
UnlockTechRecursive(node.techProto, -100);
|
||||
else
|
||||
UnlockTechRecursive(node.techProto, -1);
|
||||
return;
|
||||
}
|
||||
if (VFInput.control)
|
||||
{
|
||||
if (!VFInput.alt)
|
||||
UnlockTechRecursive(node.techProto, -10);
|
||||
}
|
||||
else if (VFInput.alt)
|
||||
{
|
||||
UnlockTechRecursive(node.techProto, node.techProto.ID == 3606 ? 7200 : 10000);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(UITechNode), nameof(UITechNode.OnPointerDown))]
|
||||
private static IEnumerable<CodeInstruction> UITechNode_OnPointerDown_Transpiler(
|
||||
IEnumerable<CodeInstruction> instructions)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions);
|
||||
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"))
|
||||
);
|
||||
var labels = matcher.Labels;
|
||||
matcher.Labels = null;
|
||||
matcher.Insert(
|
||||
new CodeInstruction(OpCodes.Ldarg_0).WithLabels(labels),
|
||||
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(TechPatch), nameof(TechPatch.OnClickTech)))
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,8 +29,7 @@ public static class TerraformPatch
|
||||
{
|
||||
if (_patch != null)
|
||||
{
|
||||
_patch.UnpatchSelf();
|
||||
_patch = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_patch = Harmony.CreateAndPatchAll(typeof(TerraformPatch));
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Steamworks;
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace CheatEnabler;
|
||||
|
||||
@@ -15,12 +14,15 @@ public class UIConfigWindow : UI.MyWindowWithTabs
|
||||
I18N.Add("Enable Dev Shortcuts", "Enable Dev Shortcuts", "启用开发模式快捷键");
|
||||
I18N.Add("Disable Abnormal Checks", "Disable Abnormal Checks", "关闭数据异常检查");
|
||||
I18N.Add("Hotkey", "Hotkey", "快捷键");
|
||||
I18N.Add("Unlock Tech with Key-Modifiers", "Unlock Tech with Key-Modifiers", "使用组合键解锁科技");
|
||||
I18N.Add("Dev Shortcuts", "Dev Shortcuts", "开发模式快捷键");
|
||||
I18N.Add("Dev Shortcuts Tips", "Caution: Some function may trigger abnormal check!\nNumpad 1: Gets all items and extends bag.\nNumpad 2: Boosts walk speed, gathering speed and mecha energy restoration.\nNumpad 3: Fills planet with foundations and bury all veins.\nNumpad 4: +1 construction drone.\nNumpad 5: Upgrades drone engine tech to full.\nNumpad 6: Unlocks researching tech.\nNumpad 7: Unlocks Drive Engine 1.\nNumpad 8: Unlocks Drive Engine 2 and maximize energy.\nNumpad 9: Unlocks ability to warp.\nNumpad 0: No costs for Logistic Storages' output.\nLCtrl + T: Unlocks all techs (not upgrades).\nLCtrl + A: Resets all local achievements.\nLCtrl + Q: Adds 10000 to every metadata.\nLCtrl + W: Enters Sandbox Mode.\nLCtrl + Shift + W: Leaves Sandbox Mode.\nNumpad *: Proliferates items on hand.\nNumpad /: Removes proliferations from items on hand.\nPageDown: Remembers Pose of game camera.\nPageUp: Locks game camera using remembered Pose.",
|
||||
"警告:某些功能可能触发异常检查!\n小键盘1:获得所有物品并扩展背包\n小键盘2:加快行走速度及采集速度,加快能量恢复速度\n小键盘3:将地基铺设整个星球并掩埋所有矿物\n小键盘4:建设机器人 +1\n小键盘5:建设机器人满级\n小键盘6:解锁当前科技\n小键盘7:解锁驱动技术I\n小键盘8:解锁驱动技术II 最大化能量\n小键盘9:机甲曲速解锁\n小键盘0:物流站通过传送带出物品无消耗\n左Ctrl + T:解锁所有非升级科技\n左Ctrl + A:重置所有本地成就\n左Ctrl + Q:增加各项元数据10000点\n左Ctrl + W:进入沙盒模式\n左Ctrl + Shift + W:离开沙盒模式\n小键盘乘号 *:给手上物品喷涂增产剂\n小键盘除号 /:清除手上物品的增产剂\nPageDown:记录摄像机当前的Pose\nPageUp:用记录的Pose锁定摄像机");
|
||||
I18N.Add("Unlock Tech with Key-Modifiers Tips", "Click tech on tree while holding:\n Shift: Tech level + 1\n Ctrl: Tech level + 10\n Ctrl + Shift: Tech level + 100\n Alt: Tech level to MAX\n\nNote: all direct prerequisites will be unlocked as well.",
|
||||
"按住以下组合键点击科技树:\n Shift:科技等级+1\n Ctrl:科技等级+10\n Ctrl+Shift:科技等级+100\n Alt:科技等级升到最大\n\n注意:所有直接前置科技也会被解锁");
|
||||
I18N.Add("Build", "Build", "建造");
|
||||
I18N.Add("Finish build immediately", "Finish build immediately", "建造秒完成");
|
||||
I18N.Add("Infinite buildings", "Infinite buildings", "无限建筑");
|
||||
I18N.Add("Architect mode", "Architect mode", "建筑师模式");
|
||||
I18N.Add("Build without condition", "Build without condition", "无条件建造");
|
||||
I18N.Add("No collision", "No collision", "无碰撞");
|
||||
I18N.Add("Planet", "Planet", "行星");
|
||||
@@ -34,6 +36,8 @@ public class UIConfigWindow : UI.MyWindowWithTabs
|
||||
I18N.Add("Skip absorption period", "Skip absorption period", "跳过吸收阶段");
|
||||
I18N.Add("Quick absorb", "Quick absorb", "快速吸收");
|
||||
I18N.Add("Eject anyway", "Eject anyway", "全球弹射");
|
||||
I18N.Add("Overclock Ejectors", "Overclock Ejectors (10x)", "高速弹射器(10倍射速)");
|
||||
I18N.Add("Overclock Silos", "Overclock Silos (10x)", "高速发射井(10倍射速)");
|
||||
I18N.Add("Terraform without enough sands", "Terraform without enough sands", "沙土不够时依然可以整改地形");
|
||||
I18N.Add("Initialize Dyson Sphere", "Initialize Dyson Sphere", "初始化戴森球");
|
||||
I18N.Add("Click to dismantle selected layer", "Click to dismantle selected layer", "点击拆除对应的戴森壳");
|
||||
@@ -73,11 +77,15 @@ public class UIConfigWindow : UI.MyWindowWithTabs
|
||||
UI.MyCheckBox.CreateCheckBox(x, y, tab1, DevShortcuts.Enabled, "Enable Dev Shortcuts");
|
||||
y += 36f;
|
||||
UI.MyCheckBox.CreateCheckBox(x, y, tab1, AbnormalDisabler.Enabled, "Disable Abnormal Checks");
|
||||
y += 86f;
|
||||
y += 36f;
|
||||
UI.MyCheckBox.CreateCheckBox(x, y, tab1, TechPatch.Enabled, "Unlock Tech with Key-Modifiers");
|
||||
y += 50f;
|
||||
UI.MyKeyBinder.CreateKeyBinder(x, y, tab1, CheatEnabler.Hotkey, "Hotkey");
|
||||
x = 180f;
|
||||
y = 16f;
|
||||
AddTipsButton(x, y, tab1, "Dev Shortcuts", "Dev Shortcuts Tips", "dev-shortcuts-tips");
|
||||
y += 72f;
|
||||
AddTipsButton(x, y, tab1, "Unlock Tech with Key-Modifiers", "Unlock Tech with Key-Modifiers Tips", "unlock-tech-tips");
|
||||
|
||||
var tab2 = AddTab(136f, 1, _windowTrans, "Build");
|
||||
x = 0f;
|
||||
@@ -150,6 +158,10 @@ public class UIConfigWindow : UI.MyWindowWithTabs
|
||||
UI.MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.QuickAbsortEnabled, "Quick absorb");
|
||||
y += 36f;
|
||||
UI.MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.EjectAnywayEnabled, "Eject anyway");
|
||||
y += 36f;
|
||||
UI.MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.OverclockEjectorEnabled, "Overclock Ejectors");
|
||||
y += 36f;
|
||||
UI.MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.OverclockSiloEnabled, "Overclock Silos");
|
||||
x = 300f;
|
||||
y = 10f;
|
||||
AddButton(x, y, tab4, "Initialize Dyson Sphere", 16, "init-dyson-sphere", () =>
|
||||
@@ -199,37 +211,40 @@ public class UIConfigWindow : UI.MyWindowWithTabs
|
||||
UI.MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.FlatBirthPlanet, "Birth planet is solid flat (no water at all)");
|
||||
y += 36f;
|
||||
UI.MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.HighLuminosityBirthStar, "Birth star has high luminosity");
|
||||
SetCurrentTab(0);
|
||||
|
||||
SetCurrentTab(0);
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
public void UpdateUI()
|
||||
{
|
||||
if (Tabs[3].Item1.gameObject.activeSelf)
|
||||
UpdateDysonShells();
|
||||
}
|
||||
|
||||
private void UpdateDysonShells()
|
||||
{
|
||||
if (!Tabs[3].Item1.gameObject.activeSelf) return;
|
||||
var star = GameMain.localStar;
|
||||
if (star != null)
|
||||
{
|
||||
var star = GameMain.localStar;
|
||||
if (star != null)
|
||||
var dysonSpheres = GameMain.data?.dysonSpheres;
|
||||
if (dysonSpheres?[star.index] != null)
|
||||
{
|
||||
var dysonSpheres = GameMain.data?.dysonSpheres;
|
||||
if (dysonSpheres?[star.index] != null)
|
||||
var ds = dysonSpheres[star.index];
|
||||
for (var i = 1; i <= 10; i++)
|
||||
{
|
||||
var ds = dysonSpheres[star.index];
|
||||
for (var i = 1; i <= 10; i++)
|
||||
{
|
||||
var layer = ds.layersIdBased[i];
|
||||
_dysonLayerBtn[i - 1].button.interactable = layer != null && layer.id == i;
|
||||
}
|
||||
|
||||
return;
|
||||
var layer = ds.layersIdBased[i];
|
||||
_dysonLayerBtn[i - 1].button.interactable = layer != null && layer.id == i;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
_dysonLayerBtn[i].button.interactable = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
_dysonLayerBtn[i].button.interactable = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void _OnDestroy()
|
||||
|
||||
@@ -28,8 +28,7 @@ public static class WaterPumperPatch
|
||||
{
|
||||
if (_patch != null)
|
||||
{
|
||||
_patch.UnpatchSelf();
|
||||
_patch = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_patch = Harmony.CreateAndPatchAll(typeof(WaterPumperPatch));
|
||||
|
||||
Reference in New Issue
Block a user