diff --git a/src/engine/CheatManager.cs b/src/engine/CheatManager.cs
index e94e8fe51ab..0117b616783 100644
--- a/src/engine/CheatManager.cs
+++ b/src/engine/CheatManager.cs
@@ -259,4 +259,30 @@ public static void OnCheatsDisabled()
DisableAllCheats();
HideCheatMenus();
}
+
+ ///
+ /// Captures the current state of all cheats for saving
+ ///
+ public static CheatManagerState CaptureState()
+ {
+ return new CheatManagerState(InfiniteCompounds, GodMode, NoAI, UnlimitedGrowthSpeed,
+ LockTime, ManuallySetTime, Speed, InfiniteMP, MoveToAnyPatch, DayNightFraction);
+ }
+
+ ///
+ /// Restores cheat state from saved data
+ ///
+ public static void RestoreState(CheatManagerState state)
+ {
+ InfiniteCompounds = state.InfiniteCompounds;
+ GodMode = state.GodMode;
+ NoAI = state.NoAI;
+ UnlimitedGrowthSpeed = state.UnlimitedGrowthSpeed;
+ LockTime = state.LockTime;
+ ManuallySetTime = state.ManuallySetTime;
+ Speed = state.Speed;
+ InfiniteMP = state.InfiniteMP;
+ MoveToAnyPatch = state.MoveToAnyPatch;
+ DayNightFraction = state.DayNightFraction;
+ }
}
diff --git a/src/engine/CheatManagerState.cs b/src/engine/CheatManagerState.cs
new file mode 100644
index 00000000000..dede86d0ea5
--- /dev/null
+++ b/src/engine/CheatManagerState.cs
@@ -0,0 +1,80 @@
+using SharedBase.Archive;
+
+///
+/// Serializable state of all cheats managed by
+///
+public class CheatManagerState : IArchivable
+{
+ public const ushort SERIALIZATION_VERSION = 1;
+
+ public CheatManagerState()
+ {
+ }
+
+ public CheatManagerState(bool infiniteCompounds, bool godMode, bool noAI, bool unlimitedGrowthSpeed,
+ bool lockTime, bool manuallySetTime, float speed, bool infiniteMP, bool moveToAnyPatch,
+ float dayNightFraction)
+ {
+ InfiniteCompounds = infiniteCompounds;
+ GodMode = godMode;
+ NoAI = noAI;
+ UnlimitedGrowthSpeed = unlimitedGrowthSpeed;
+ LockTime = lockTime;
+ ManuallySetTime = manuallySetTime;
+ Speed = speed;
+ InfiniteMP = infiniteMP;
+ MoveToAnyPatch = moveToAnyPatch;
+ DayNightFraction = dayNightFraction;
+ }
+
+ public bool InfiniteCompounds { get; set; }
+ public bool GodMode { get; set; }
+ public bool NoAI { get; set; }
+ public bool UnlimitedGrowthSpeed { get; set; }
+ public bool LockTime { get; set; }
+ public bool ManuallySetTime { get; set; }
+ public float Speed { get; set; } = 1.0f;
+ public bool InfiniteMP { get; set; }
+ public bool MoveToAnyPatch { get; set; }
+ public float DayNightFraction { get; set; }
+
+ public ushort CurrentArchiveVersion => SERIALIZATION_VERSION;
+ public ArchiveObjectType ArchiveObjectType => (ArchiveObjectType)ThriveArchiveObjectType.CheatManagerState;
+ public bool CanBeReferencedInArchive => false;
+
+ public static CheatManagerState ReadFromArchive(ISArchiveReader reader, ushort version, int referenceId)
+ {
+ if (version is > SERIALIZATION_VERSION or <= 0)
+ throw new InvalidArchiveVersionException(version, SERIALIZATION_VERSION);
+
+ var instance = new CheatManagerState
+ {
+ InfiniteCompounds = reader.ReadBool(),
+ GodMode = reader.ReadBool(),
+ NoAI = reader.ReadBool(),
+ UnlimitedGrowthSpeed = reader.ReadBool(),
+ LockTime = reader.ReadBool(),
+ ManuallySetTime = reader.ReadBool(),
+ Speed = reader.ReadFloat(),
+ InfiniteMP = reader.ReadBool(),
+ MoveToAnyPatch = reader.ReadBool(),
+ DayNightFraction = reader.ReadFloat(),
+ };
+
+ return instance;
+ }
+
+ public void WriteToArchive(ISArchiveWriter writer)
+ {
+ writer.Write(InfiniteCompounds);
+ writer.Write(GodMode);
+ writer.Write(NoAI);
+ writer.Write(UnlimitedGrowthSpeed);
+ writer.Write(LockTime);
+ writer.Write(ManuallySetTime);
+ writer.Write(Speed);
+ writer.Write(InfiniteMP);
+ writer.Write(MoveToAnyPatch);
+ writer.Write(DayNightFraction);
+ }
+}
diff --git a/src/engine/CheatManagerState.cs.uid b/src/engine/CheatManagerState.cs.uid
new file mode 100644
index 00000000000..fb8a63cfa0b
--- /dev/null
+++ b/src/engine/CheatManagerState.cs.uid
@@ -0,0 +1 @@
+uid://bdt6hwmh2mt8y
diff --git a/src/general/GameProperties.cs b/src/general/GameProperties.cs
index 58df26a5dde..5a72606c52b 100644
--- a/src/general/GameProperties.cs
+++ b/src/general/GameProperties.cs
@@ -11,7 +11,7 @@
///
public class GameProperties : IArchivable
{
- public const int SERIALIZATION_VERSION = 2;
+ public const int SERIALIZATION_VERSION = 3;
private readonly Dictionary setBoolStatuses;
@@ -47,6 +47,11 @@ private GameProperties(GameWorld gameWorld, TutorialState tutorialState, Diction
///
public bool CheatsUsed { get; private set; }
+ ///
+ /// Holds the state of all cheats used in this game
+ ///
+ public CheatManagerState SavedCheats { get; set; } = new();
+
///
/// True when the player is currently ascended and should be allowed to do anything
///
@@ -324,6 +329,12 @@ public static GameProperties ReadFromArchive(ISArchiveReader reader, ushort vers
if (version > 1)
instance.ThriveopediaData = reader.ReadObject();
+ if (version > 2)
+ {
+ instance.SavedCheats = reader.ReadObject();
+ CheatManager.RestoreState(instance.SavedCheats);
+ }
+
return instance;
}
@@ -345,6 +356,9 @@ public void WriteToArchive(ISArchiveWriter writer)
// writer.WriteObject(TechWeb);
writer.WriteObject(ThriveopediaData);
+
+ SavedCheats = CheatManager.CaptureState();
+ writer.WriteObject(SavedCheats);
}
///
diff --git a/src/general/MainMenu.cs b/src/general/MainMenu.cs
index a52aaa0e900..c903e81d56e 100644
--- a/src/general/MainMenu.cs
+++ b/src/general/MainMenu.cs
@@ -176,7 +176,6 @@ public partial class MainMenu : NodeWithInput
public static void OnEnteringGame(bool cheatsUsed, bool freebuild)
{
- CheatManager.OnCheatsDisabled();
SaveHelper.ClearLastSaveTime();
LastPlayedVersion.MarkCurrentVersionAsPlayed();
AchievementsManager.ReportNewGameStarted(cheatsUsed);
diff --git a/src/microbe_stage/editor/MicrobeEditorCheatMenu.cs b/src/microbe_stage/editor/MicrobeEditorCheatMenu.cs
index 5253ba66d11..b09fa867e91 100644
--- a/src/microbe_stage/editor/MicrobeEditorCheatMenu.cs
+++ b/src/microbe_stage/editor/MicrobeEditorCheatMenu.cs
@@ -8,11 +8,15 @@ public partial class MicrobeEditorCheatMenu : CheatMenu
#pragma warning disable CA2213
[Export]
private CheckBox infiniteMp = null!;
+
+ [Export]
+ private CheckBox moveToAnyPatch = null!;
#pragma warning restore CA2213
public override void ReloadGUI()
{
infiniteMp.ButtonPressed = CheatManager.InfiniteMP;
+ moveToAnyPatch.ButtonPressed = CheatManager.MoveToAnyPatch;
}
private void OnRevealAllPatchesPressed()
diff --git a/src/microbe_stage/editor/MicrobeEditorCheatMenu.tscn b/src/microbe_stage/editor/MicrobeEditorCheatMenu.tscn
index 52cb38f8663..d3bebfeea10 100644
--- a/src/microbe_stage/editor/MicrobeEditorCheatMenu.tscn
+++ b/src/microbe_stage/editor/MicrobeEditorCheatMenu.tscn
@@ -3,11 +3,12 @@
[ext_resource type="PackedScene" uid="uid://du8sc8kjirguk" path="res://src/gui_common/dialogs/CustomWindow.tscn" id="1"]
[ext_resource type="Script" uid="uid://b8pglhtmiphys" path="res://src/microbe_stage/editor/MicrobeEditorCheatMenu.cs" id="2"]
-[node name="MicrobeEditorCheatMenu" unique_id=1599049517 node_paths=PackedStringArray("infiniteMp") instance=ExtResource("1")]
+[node name="MicrobeEditorCheatMenu" unique_id=1599049517 node_paths=PackedStringArray("infiniteMp", "moveToAnyPatch") instance=ExtResource("1")]
offset_right = 0.0
offset_bottom = 0.0
script = ExtResource("2")
infiniteMp = NodePath("VBoxContainer/InfiniteMP")
+moveToAnyPatch = NodePath("VBoxContainer/MoveToAnyPatch")
WindowTitle = "CHEATS"
Resizable = true
diff --git a/src/saving/ThriveArchiveObjectType.cs b/src/saving/ThriveArchiveObjectType.cs
index 1e1c65e77eb..4bcde0063ee 100644
--- a/src/saving/ThriveArchiveObjectType.cs
+++ b/src/saving/ThriveArchiveObjectType.cs
@@ -322,6 +322,7 @@ public enum ThriveArchiveObjectType : uint
TutorialMicrobeSpecializationTutorial = 4402,
TutorialMulticellularSpecializationTutorial = 4403,
MassBuddingCellCountActionData = 4404,
+ CheatManagerState = 4405,
// Special flag types
ExtendedOrganelleLayout = OrganelleLayout | ArchiveObjectType.ExtendedTypeFlag,
diff --git a/src/saving/serializers/ThriveArchiveManager.cs b/src/saving/serializers/ThriveArchiveManager.cs
index 8a80cf6dd7d..003d3044bde 100644
--- a/src/saving/serializers/ThriveArchiveManager.cs
+++ b/src/saving/serializers/ThriveArchiveManager.cs
@@ -183,8 +183,10 @@ private void RegisterOtherObjects()
{
RegisterObjectType((ArchiveObjectType)ThriveArchiveObjectType.GameProperties, typeof(GameProperties),
GameProperties.ReadFromArchive);
+ RegisterObjectType((ArchiveObjectType)ThriveArchiveObjectType.CheatManagerState, typeof(CheatManagerState),
+ CheatManagerState.ReadFromArchive);
RegisterObjectType((ArchiveObjectType)ThriveArchiveObjectType.GameWorld, typeof(GameWorld),
- GameWorld.ReadFromArchive);
+ GameWorld.ReadFromArchive);
RegisterObjectType((ArchiveObjectType)ThriveArchiveObjectType.WorldGenerationSettings,
typeof(WorldGenerationSettings),