From 5622e9eb8e4501ea558ea27dbfd36666fa751e02 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Mon, 11 Jan 2021 14:11:21 +0100 Subject: [PATCH 01/91] porting over savestates from decompiled version --- Source/BindableFunctions.cs | 74 +++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 9b78e52..11c67e8 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -154,6 +154,80 @@ public static void TimescaleUp() #endregion + #region SaveStates + + [BindableMethod(name = "Make Savestate", category = "Savestates")] + public static void SaveState() + { + BindableFunctions._saveStateIdentifier = "(tmp)_" + BindableFunctions._saveScene + "-" + DateTime.Now.ToString("H:mm d/MMM"); + BindableFunctions.cameraLockArea = (BindableFunctions.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); + BindableFunctions._savedPd = JsonUtility.FromJson(JsonUtility.ToJson(PlayerData.instance)); + BindableFunctions._savedSd = JsonUtility.FromJson(JsonUtility.ToJson(SceneData.instance)); + BindableFunctions._savePos = HeroController.instance.gameObject.transform.position; + BindableFunctions._saveScene = GameManager.instance.GetSceneNameString(); + BindableFunctions._lockArea = BindableFunctions.cameraLockArea.GetValue(GameManager.instance.cameraCtrl); + } + + [BindableMethod(name = "Load SaveState", category = "Savestates")] + public static void LoadState() + { + HeroController.instance.StartCoroutine(BindableFunctions.LoadStateCoro()); + } + + public static IEnumerator LoadStateCoro() + { + BindableFunctions.cameraLockArea = (BindableFunctions.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); + GameManager.instance.ChangeToScene("Room_Sly_Storeroom", "", 0f); + while (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != "Room_Sly_Storeroom") + { + yield return null; + } + GameManager.instance.sceneData = (SceneData.instance = JsonUtility.FromJson(JsonUtility.ToJson(BindableFunctions._savedSd))); + //if (!BindableFunctions.preserveThroughStates) + //{ + GameManager.instance.ResetSemiPersistentItems(); + //} + yield return null; + HeroController.instance.gameObject.transform.position = BindableFunctions._savePos; + PlayerData.instance = (GameManager.instance.playerData = (HeroController.instance.playerData = JsonUtility.FromJson(JsonUtility.ToJson(BindableFunctions._savedPd)))); + GameManager.instance.ChangeToScene(BindableFunctions._saveScene, "", 0.4f); + try + { + BindableFunctions.cameraLockArea.SetValue(GameManager.instance.cameraCtrl, BindableFunctions._lockArea); + GameManager.instance.cameraCtrl.LockToArea(BindableFunctions._lockArea as CameraLockArea); + BindableFunctions.cameraGameplayScene.SetValue(GameManager.instance.cameraCtrl, true); + } + catch (Exception message) + { + Debug.LogError(message); + } + yield return new WaitUntil(() => UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == BindableFunctions._saveScene); + HeroController.instance.playerData = PlayerData.instance; + if (PlayerData.instance.MPCharge >= 99) + { + HeroController.instance.AddMPChargeSpa(1); + HeroController.instance.TakeMP(1); + } + else if (PlayerData.instance.maxMP <= 99) + { + HeroController.instance.TakeMP(1); + HeroController.instance.AddMPChargeSpa(1); + } + HeroController.instance.proxyFSM.SendEvent("HeroCtrl-HeroDamaged"); + HeroController.instance.geoCounter.playerData = PlayerData.instance; + HeroController.instance.geoCounter.TakeGeo(0); + HeroAnimationController component = HeroController.instance.GetComponent(); + typeof(HeroAnimationController).GetField("pd", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(component, PlayerData.instance); + HeroController.instance.TakeHealth(1); + HeroController.instance.AddHealth(1); + GameCameras.instance.hudCanvas.gameObject.SetActive(true); + HeroController.instance.TakeHealth(1); + HeroController.instance.AddHealth(1); + yield break; + } + + #endregion + #region Visual [BindableMethod(name = "Toggle Vignette", category = "Visual")] From 048eef3faf8c10eacc0e839f486d58845212b6b8 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Wed, 13 Jan 2021 03:13:00 +0100 Subject: [PATCH 02/91] Save state porting Savestates ported from other debug versions Skeleton class to handle multiple states from/to file Use `Source/References` for game files/dependencies --- Source/BindableFunctions.cs | 81 ++++++------------ Source/DebugMod.csproj | 1 + Source/SaveState.cs | 164 ++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+), 57 deletions(-) create mode 100644 Source/SaveState.cs diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 11c67e8..0917c01 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -10,6 +10,9 @@ public static class BindableFunctions { private static readonly FieldInfo TimeSlowed = typeof(GameManager).GetField("timeSlowed", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); private static readonly FieldInfo IgnoreUnpause = typeof(UIManager).GetField("ignoreUnpause", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); + private static SaveStateHelper tmpSaveState; + internal static SaveStateHelper[] SaveStates; + internal static int CurrentSlot = -1; internal static readonly FieldInfo cameraGameplayScene = typeof(CameraController).GetField("isGameplayScene", BindingFlags.Instance | BindingFlags.NonPublic); @@ -159,73 +162,37 @@ public static void TimescaleUp() [BindableMethod(name = "Make Savestate", category = "Savestates")] public static void SaveState() { - BindableFunctions._saveStateIdentifier = "(tmp)_" + BindableFunctions._saveScene + "-" + DateTime.Now.ToString("H:mm d/MMM"); - BindableFunctions.cameraLockArea = (BindableFunctions.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); - BindableFunctions._savedPd = JsonUtility.FromJson(JsonUtility.ToJson(PlayerData.instance)); - BindableFunctions._savedSd = JsonUtility.FromJson(JsonUtility.ToJson(SceneData.instance)); - BindableFunctions._savePos = HeroController.instance.gameObject.transform.position; - BindableFunctions._saveScene = GameManager.instance.GetSceneNameString(); - BindableFunctions._lockArea = BindableFunctions.cameraLockArea.GetValue(GameManager.instance.cameraCtrl); + tmpSaveState = new SaveStateHelper(); + tmpSaveState.SaveState(SaveStateType.ToMemory); } [BindableMethod(name = "Load SaveState", category = "Savestates")] public static void LoadState() { - HeroController.instance.StartCoroutine(BindableFunctions.LoadStateCoro()); + if (tmpSaveState.IsSet()) + { + tmpSaveState.LoadState(); + } } - public static IEnumerator LoadStateCoro() + [BindableMethod(name = "Save current to file", category = "Savestates")] + public static void CurrentSaveStateToFile() { - BindableFunctions.cameraLockArea = (BindableFunctions.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); - GameManager.instance.ChangeToScene("Room_Sly_Storeroom", "", 0f); - while (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != "Room_Sly_Storeroom") - { - yield return null; - } - GameManager.instance.sceneData = (SceneData.instance = JsonUtility.FromJson(JsonUtility.ToJson(BindableFunctions._savedSd))); - //if (!BindableFunctions.preserveThroughStates) - //{ - GameManager.instance.ResetSemiPersistentItems(); - //} - yield return null; - HeroController.instance.gameObject.transform.position = BindableFunctions._savePos; - PlayerData.instance = (GameManager.instance.playerData = (HeroController.instance.playerData = JsonUtility.FromJson(JsonUtility.ToJson(BindableFunctions._savedPd)))); - GameManager.instance.ChangeToScene(BindableFunctions._saveScene, "", 0.4f); - try - { - BindableFunctions.cameraLockArea.SetValue(GameManager.instance.cameraCtrl, BindableFunctions._lockArea); - GameManager.instance.cameraCtrl.LockToArea(BindableFunctions._lockArea as CameraLockArea); - BindableFunctions.cameraGameplayScene.SetValue(GameManager.instance.cameraCtrl, true); - } - catch (Exception message) - { - Debug.LogError(message); - } - yield return new WaitUntil(() => UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == BindableFunctions._saveScene); - HeroController.instance.playerData = PlayerData.instance; - if (PlayerData.instance.MPCharge >= 99) - { - HeroController.instance.AddMPChargeSpa(1); - HeroController.instance.TakeMP(1); - } - else if (PlayerData.instance.maxMP <= 99) - { - HeroController.instance.TakeMP(1); - HeroController.instance.AddMPChargeSpa(1); - } - HeroController.instance.proxyFSM.SendEvent("HeroCtrl-HeroDamaged"); - HeroController.instance.geoCounter.playerData = PlayerData.instance; - HeroController.instance.geoCounter.TakeGeo(0); - HeroAnimationController component = HeroController.instance.GetComponent(); - typeof(HeroAnimationController).GetField("pd", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(component, PlayerData.instance); - HeroController.instance.TakeHealth(1); - HeroController.instance.AddHealth(1); - GameCameras.instance.hudCanvas.gameObject.SetActive(true); - HeroController.instance.TakeHealth(1); - HeroController.instance.AddHealth(1); - yield break; + if (tmpSaveState) { tmpSaveState.SaveState(SaveStateType.ToMemory); } + } + + [BindableMethod(name = "Make Savestate (file)", category = "Savestates")] + public static void NewSaveStateToFile() + { + tmpSaveState = new SaveStateHelper(); + tmpSaveState.SaveState(SaveStateType.ToMemory); + } + [BindableMethod(name = "Load Savestate (file)", category = "Savestates")] + public static void LoadFromFile() + { + } #endregion #region Visual diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 0693ca6..f029ea3 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -72,6 +72,7 @@ True Resources.resx + diff --git a/Source/SaveState.cs b/Source/SaveState.cs new file mode 100644 index 0000000..94be4df --- /dev/null +++ b/Source/SaveState.cs @@ -0,0 +1,164 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using UnityEngine; + +namespace DebugMod +{ + public enum SaveStateType { + ToMemory, + ToFile, + CurrentMemoryToFile + } + + internal class SaveStateHelper : MonoBehaviour + { + private static string _saveScene; + private static PlayerData _savedPd; + private static object _lockArea; + private static SceneData _savedSd; + private static Vector3 _savePos; + private static FieldInfo cameraLockArea; + public static int currentStateSlot = -1; + public static bool preserveThroughStates = false; + public static string[] saveStateFiles = new string[10]; + private static string _saveStateIdentifier = ""; + public static bool saveStateHUD = false; + public static bool minimalInfoHUD = false; + private static bool autoSlotSelect = true; + + #region saving + public void SaveState(SaveStateType stateType) + { + switch (stateType) + { + case SaveStateType.ToMemory: + TempSaveState(); + break; + case SaveStateType.ToFile: + ConvertTempToFile(); + break; + case SaveStateType.CurrentMemoryToFile: + ConvertTempToFile(); + break; + default: break; + } + } + + private void TempSaveState() + { + _saveScene = GameManager.instance.GetSceneNameString(); + _saveStateIdentifier = "(tmp)_" + _saveScene + "-" + DateTime.Now.ToString("H:mm_d-MMM"); + _savedPd = JsonUtility.FromJson(JsonUtility.ToJson(PlayerData.instance)); + _savedSd = JsonUtility.FromJson(JsonUtility.ToJson(SceneData.instance)); + _savePos = HeroController.instance.gameObject.transform.position; + cameraLockArea = (cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); + _lockArea = cameraLockArea.GetValue(GameManager.instance.cameraCtrl); + } + + private void ConvertTempToFile() + { + + } + + private void SaveStateToFile() + { + + } + #endregion + + #region loading + public void LoadState() + { + HeroController.instance.StartCoroutine(LoadStateCoro()); + } + + private void PrepareFileStateToMemory() + { + + } + + private void LoadStateFromFile() + { + + } + + private IEnumerator LoadStateCoro() + { + cameraLockArea = (cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); + GameManager.instance.ChangeToScene("Room_Sly_Storeroom", "", 0f); + while (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != "Room_Sly_Storeroom") + { + yield return null; + } + GameManager.instance.sceneData = (SceneData.instance = JsonUtility.FromJson(JsonUtility.ToJson(_savedSd))); + //if (!BindableFunctions.preserveThroughStates) + //{ + GameManager.instance.ResetSemiPersistentItems(); + //} + yield return null; + HeroController.instance.gameObject.transform.position = _savePos; + PlayerData.instance = (GameManager.instance.playerData = (HeroController.instance.playerData = JsonUtility.FromJson(JsonUtility.ToJson(_savedPd)))); + GameManager.instance.ChangeToScene(_saveScene, "", 0.4f); + try + { + cameraLockArea.SetValue(GameManager.instance.cameraCtrl, _lockArea); + GameManager.instance.cameraCtrl.LockToArea(_lockArea as CameraLockArea); + BindableFunctions.cameraGameplayScene.SetValue(GameManager.instance.cameraCtrl, true); + } + catch (Exception message) + { + Debug.LogError(message); + } + yield return new WaitUntil(() => UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == _saveScene); + HeroController.instance.playerData = PlayerData.instance; + if (PlayerData.instance.MPCharge >= 99) + { + HeroController.instance.AddMPChargeSpa(1); + HeroController.instance.TakeMP(1); + } + else if (PlayerData.instance.maxMP <= 99) + { + HeroController.instance.TakeMP(1); + HeroController.instance.AddMPChargeSpa(1); + } + HeroController.instance.proxyFSM.SendEvent("HeroCtrl-HeroDamaged"); + HeroController.instance.geoCounter.playerData = PlayerData.instance; + HeroController.instance.geoCounter.TakeGeo(0); + HeroAnimationController component = HeroController.instance.GetComponent(); + typeof(HeroAnimationController).GetField("pd", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(component, PlayerData.instance); + HeroController.instance.TakeHealth(1); + HeroController.instance.AddHealth(1); + GameCameras.instance.hudCanvas.gameObject.SetActive(true); + HeroController.instance.TakeHealth(1); + HeroController.instance.AddHealth(1); + yield break; + } + + private void LoadFromFile() + { + + } + #endregion + + #region helper functionality + public bool IsSet() + { + bool isSet = false; + if (String.IsNullOrEmpty(_saveStateIdentifier)) + { + isSet = true; + } + return isSet; + } + + public void ToggleAutoSlot() + { + autoSlotSelect = !autoSlotSelect; + } + #endregion + } +} From 35d1ec5d776878fff7ad74447b1bd23ba2780dd0 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Wed, 13 Jan 2021 03:17:42 +0100 Subject: [PATCH 03/91] ignore references/dependencies folder --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 940794e..b67ec55 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,9 @@ # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs +# Dependencies +Source/References/ + # Build results [Dd]ebug/ [Dd]ebugPublic/ From 1cbe154d750a9c3160e00f70b42a976492daa201 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Thu, 14 Jan 2021 01:40:57 +0100 Subject: [PATCH 04/91] Savestate code --- Source/BindableFunctions.cs | 26 ++--- Source/SaveState.cs | 227 +++++++++++++++++++++++++++++------- 2 files changed, 199 insertions(+), 54 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 0917c01..7ed039a 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -10,8 +10,8 @@ public static class BindableFunctions { private static readonly FieldInfo TimeSlowed = typeof(GameManager).GetField("timeSlowed", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); private static readonly FieldInfo IgnoreUnpause = typeof(UIManager).GetField("ignoreUnpause", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); - private static SaveStateHelper tmpSaveState; - internal static SaveStateHelper[] SaveStates; + private static SaveStateHandler tmpSaveState; + //public static string[] saveStateFiles = new string[10]; internal static int CurrentSlot = -1; internal static readonly FieldInfo cameraGameplayScene = typeof(CameraController).GetField("isGameplayScene", BindingFlags.Instance | BindingFlags.NonPublic); @@ -162,8 +162,8 @@ public static void TimescaleUp() [BindableMethod(name = "Make Savestate", category = "Savestates")] public static void SaveState() { - tmpSaveState = new SaveStateHelper(); - tmpSaveState.SaveState(SaveStateType.ToMemory); + tmpSaveState = new SaveStateHandler(); + tmpSaveState.SaveState(SaveStateType.Memory); } [BindableMethod(name = "Load SaveState", category = "Savestates")] @@ -171,21 +171,21 @@ public static void LoadState() { if (tmpSaveState.IsSet()) { - tmpSaveState.LoadState(); + tmpSaveState.LoadState(SaveStateType.Memory); } } [BindableMethod(name = "Save current to file", category = "Savestates")] public static void CurrentSaveStateToFile() { - if (tmpSaveState) { tmpSaveState.SaveState(SaveStateType.ToMemory); } + if (tmpSaveState) { tmpSaveState.SaveState(SaveStateType.Memory); } } [BindableMethod(name = "Make Savestate (file)", category = "Savestates")] public static void NewSaveStateToFile() { - tmpSaveState = new SaveStateHelper(); - tmpSaveState.SaveState(SaveStateType.ToMemory); + tmpSaveState = new SaveStateHandler(); + tmpSaveState.SaveState(SaveStateType.Memory); } [BindableMethod(name = "Load Savestate (file)", category = "Savestates")] @@ -513,11 +513,11 @@ public static void ToggleNoclip() public static void KillSelf() { if (DebugMod.GM.isPaused) UIManager.instance.TogglePauseGame(); - HeroController.instance.TakeHealth(9999); - HeroController.instance.heroDeathPrefab.SetActive(true); - DebugMod.GM.ReadyForRespawn(); - GameCameras.instance.hudCanvas.gameObject.SetActive(false); - GameCameras.instance.hudCanvas.gameObject.SetActive(true); + HeroController.instance.TakeHealth(PlayerData.instance.health); + //HeroController.instance.heroDeathPrefab.SetActive(true); + //DebugMod.GM.ReadyForRespawn(); + //GameCameras.instance.hudCanvas.gameObject.SetActive(false); + //GameCameras.instance.hudCanvas.gameObject.SetActive(true); } #endregion diff --git a/Source/SaveState.cs b/Source/SaveState.cs index 94be4df..cdcc59b 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Reflection; using System.Text; @@ -9,40 +10,58 @@ namespace DebugMod { public enum SaveStateType { - ToMemory, - ToFile, + Memory, + File, CurrentMemoryToFile } - internal class SaveStateHelper : MonoBehaviour + internal class SaveStateHandler : MonoBehaviour { - private static string _saveScene; - private static PlayerData _savedPd; - private static object _lockArea; - private static SceneData _savedSd; - private static Vector3 _savePos; - private static FieldInfo cameraLockArea; + private string saveStateIdentifier = ""; + private string saveScene; + private PlayerData savedPd; + private object lockArea; + private SceneData savedSd; + private Vector3 savePos; + private FieldInfo cameraLockArea; + public static int currentStateSlot = -1; - public static bool preserveThroughStates = false; + //public static bool preserveThroughStates = false; public static string[] saveStateFiles = new string[10]; - private static string _saveStateIdentifier = ""; + //private bool exists; + public static bool saveStateHUD = false; public static bool minimalInfoHUD = false; private static bool autoSlotSelect = true; + internal SaveStateHandler() + { + + } + + private SaveStateHandler(string _scene, string _identifier, PlayerData _pd, SceneData _sd, Vector3 _pos, FieldInfo _cameraLockArea, object _paramLockArea) { + saveScene = _scene; + saveStateIdentifier = _identifier; + savedPd = _pd; + savedSd = _sd; + savePos = _pos; + cameraLockArea = _cameraLockArea; + lockArea = _paramLockArea; + } + #region saving public void SaveState(SaveStateType stateType) { switch (stateType) { - case SaveStateType.ToMemory: + case SaveStateType.Memory: TempSaveState(); break; - case SaveStateType.ToFile: - ConvertTempToFile(); + case SaveStateType.File: + ConvertTempSaveToFile(); break; case SaveStateType.CurrentMemoryToFile: - ConvertTempToFile(); + ConvertTempSaveToFile(); break; default: break; } @@ -50,40 +69,165 @@ public void SaveState(SaveStateType stateType) private void TempSaveState() { - _saveScene = GameManager.instance.GetSceneNameString(); - _saveStateIdentifier = "(tmp)_" + _saveScene + "-" + DateTime.Now.ToString("H:mm_d-MMM"); - _savedPd = JsonUtility.FromJson(JsonUtility.ToJson(PlayerData.instance)); - _savedSd = JsonUtility.FromJson(JsonUtility.ToJson(SceneData.instance)); - _savePos = HeroController.instance.gameObject.transform.position; + saveScene = GameManager.instance.GetSceneNameString(); + saveStateIdentifier = "(tmp)_" + saveScene + "-" + DateTime.Now.ToString("H:mm_d-MMM"); + savedPd = JsonUtility.FromJson(JsonUtility.ToJson(PlayerData.instance)); + savedSd = JsonUtility.FromJson(JsonUtility.ToJson(SceneData.instance)); + savePos = HeroController.instance.gameObject.transform.position; cameraLockArea = (cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); - _lockArea = cameraLockArea.GetValue(GameManager.instance.cameraCtrl); + lockArea = cameraLockArea.GetValue(GameManager.instance.cameraCtrl); } - private void ConvertTempToFile() + private void ConvertTempSaveToFile() { - + if(autoSlotSelect) { + int i = 0; + int slotAtEntry = currentStateSlot; + while (++currentStateSlot != slotAtEntry || i++ < 10) + { + if (currentStateSlot < 10) + { + if (String.IsNullOrEmpty(saveStateFiles[currentStateSlot])) + { + SaveStateToFile(); + } + } + else + { + currentStateSlot = -1; + } + } + } } private void SaveStateToFile() { + try + { + int slotAtEntry = currentStateSlot; + if (slotAtEntry < 0 || slotAtEntry >= 10) + { + throw new Exception("No savestate slot index set, abort making file"); + } + Directory.CreateDirectory(Application.persistentDataPath + "/Savestates-1221"); + + if (saveStateIdentifier.StartsWith("(tmp)_")) + { + saveStateIdentifier = saveStateIdentifier.Substring(6); + saveStateFiles[currentStateSlot] = saveStateIdentifier; + } + else + { // This is bad + saveStateFiles[currentStateSlot] = saveScene + "-" + DateTime.Now.ToString("H:mm_d-MMM"); + } + + File.WriteAllText(string.Concat(new object[] + { + Application.persistentDataPath, + "/Savestates-1221/savestate", + currentStateSlot, + ".json" + }), JsonUtility.ToJson(obj: new SaveStateHandler + ( + saveScene, + saveStateIdentifier, + savedPd, + savedSd, + savePos, + cameraLockArea, + lockArea + ), prettyPrint: true)); + } + catch (Exception ex) + { + Debug.Log("SaveStateToFile(): " + ex.Message); + } } #endregion #region loading - public void LoadState() + public void LoadState(SaveStateType stateType) { - HeroController.instance.StartCoroutine(LoadStateCoro()); + switch (stateType) + { + case SaveStateType.Memory: + if (!String.IsNullOrEmpty(saveStateIdentifier)) + { + HeroController.instance.StartCoroutine(LoadStateCoro()); + } + else + { + Console.AddLine("No save state in current memory"); + } + break; + case SaveStateType.File: + PrepareFileStateToMemory(); + // Implement slot controls + break; + case SaveStateType.CurrentMemoryToFile: + LoadStateFromFile(); + // Implement slot controls + break; + default: + break; + } + + + //HeroController.instance.StartCoroutine(LoadStateCoro()); + } private void PrepareFileStateToMemory() { + try + { + int slot = currentStateSlot; + SaveStateHandler tmpData = new SaveStateHandler(); + if (slot < 0 || slot >= 10) + { + Console.AddLine("No slot selected, aborting prep"); + return; + } + string path = string.Concat(new object[] + { + Application.persistentDataPath, + "/Savestates-1221/savestate", + slot, + ".json" + }); + + if (File.Exists(path)) + { + tmpData = JsonUtility.FromJson(File.ReadAllText(path)); + try + { + saveStateIdentifier = tmpData.saveStateIdentifier; + cameraLockArea = tmpData.cameraLockArea; + savedPd = tmpData.savedPd; + savedSd = tmpData.savedSd; + savePos = tmpData.savePos; + saveScene = tmpData.saveScene; + lockArea = tmpData.lockArea; + Console.AddLine("Load SaveState ready:" + saveStateIdentifier); + } + catch (Exception) + { + Console.AddLine("Save prep failed"); + } + } + } + catch (Exception ex) + { + Debug.Log("SaveStateToFile() error: " + ex.Message); + } } private void LoadStateFromFile() { - + PrepareFileStateToMemory(); + HeroController.instance.StartCoroutine(LoadStateCoro()); } private IEnumerator LoadStateCoro() @@ -94,37 +238,43 @@ private IEnumerator LoadStateCoro() { yield return null; } - GameManager.instance.sceneData = (SceneData.instance = JsonUtility.FromJson(JsonUtility.ToJson(_savedSd))); + GameManager.instance.sceneData = (SceneData.instance = JsonUtility.FromJson(JsonUtility.ToJson(savedSd))); //if (!BindableFunctions.preserveThroughStates) //{ GameManager.instance.ResetSemiPersistentItems(); //} yield return null; - HeroController.instance.gameObject.transform.position = _savePos; - PlayerData.instance = (GameManager.instance.playerData = (HeroController.instance.playerData = JsonUtility.FromJson(JsonUtility.ToJson(_savedPd)))); - GameManager.instance.ChangeToScene(_saveScene, "", 0.4f); + HeroController.instance.gameObject.transform.position = savePos; + PlayerData.instance = (GameManager.instance.playerData = (HeroController.instance.playerData = JsonUtility.FromJson(JsonUtility.ToJson(savedPd)))); + GameManager.instance.ChangeToScene(saveScene, "", 0.4f); try { - cameraLockArea.SetValue(GameManager.instance.cameraCtrl, _lockArea); - GameManager.instance.cameraCtrl.LockToArea(_lockArea as CameraLockArea); + cameraLockArea.SetValue(GameManager.instance.cameraCtrl, lockArea); + GameManager.instance.cameraCtrl.LockToArea(lockArea as CameraLockArea); BindableFunctions.cameraGameplayScene.SetValue(GameManager.instance.cameraCtrl, true); } catch (Exception message) { Debug.LogError(message); } - yield return new WaitUntil(() => UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == _saveScene); + yield return new WaitUntil(() => UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == saveScene); HeroController.instance.playerData = PlayerData.instance; if (PlayerData.instance.MPCharge >= 99) { - HeroController.instance.AddMPChargeSpa(1); + if (PlayerData.instance.MPReserve > 0) + { + HeroController.instance.TakeReserveMP(1); + HeroController.instance.AddMPChargeSpa(1); + } HeroController.instance.TakeMP(1); + HeroController.instance.AddMPChargeSpa(1); } - else if (PlayerData.instance.maxMP <= 99) + else { HeroController.instance.TakeMP(1); HeroController.instance.AddMPChargeSpa(1); } + HeroController.instance.SetHazardRespawn(savedPd.hazardRespawnLocation, savedPd.hazardRespawnFacingRight); HeroController.instance.proxyFSM.SendEvent("HeroCtrl-HeroDamaged"); HeroController.instance.geoCounter.playerData = PlayerData.instance; HeroController.instance.geoCounter.TakeGeo(0); @@ -137,18 +287,13 @@ private IEnumerator LoadStateCoro() HeroController.instance.AddHealth(1); yield break; } - - private void LoadFromFile() - { - - } #endregion #region helper functionality public bool IsSet() { bool isSet = false; - if (String.IsNullOrEmpty(_saveStateIdentifier)) + if (String.IsNullOrEmpty(saveStateIdentifier)) { isSet = true; } From 494766b9aa935b51807a47df45344617fe56e442 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Thu, 14 Jan 2021 02:27:33 +0100 Subject: [PATCH 05/91] project builds:) added barebone build instructions --- DebugMod.sln | 9 +++++++-- README.md | 5 ++++- Source/DebugMod.csproj | 5 +++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/DebugMod.sln b/DebugMod.sln index 75072fc..bc2b6ce 100644 --- a/DebugMod.sln +++ b/DebugMod.sln @@ -1,9 +1,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Express 2013 for Windows Desktop -VisualStudioVersion = 12.0.21005.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.1340 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DebugMod", "Source\DebugMod.csproj", "{E3E4D0B7-656C-6C50-7567-696E2E57696E}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NewFolder1", "NewFolder1", "{E83EF7B4-FB77-4F28-9984-790847A82818}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -18,4 +20,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3A3F4FD5-C58A-44B9-88F8-1970BD2A3530} + EndGlobalSection EndGlobal diff --git a/README.md b/README.md index 2b30b8b..02397fa 100644 --- a/README.md +++ b/README.md @@ -1 +1,4 @@ -Original mod by KeinZantezuken. Remaking using canvas instead of imgui and the modding framework created by myself and MyEyes/Firzen. \ No newline at end of file +Original mod by KeinZantezuken. Remaking using canvas instead of imgui and the modding framework created by myself and MyEyes/Firzen. + +# How to build: +Make a folder `Source/References/`, and add `Assembly-CSharp.dll` (with modding-api), `PlayMaker.dll`, `UnityEngine.dll`, and `UnityEngine.UI.dll` from your `Hollow Knight/hollow_knight_Data/Managed/`-folder \ No newline at end of file diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index f029ea3..3a5890f 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -30,6 +30,7 @@ false default 1591 + false true @@ -42,6 +43,9 @@ 4 false + + true + False @@ -52,6 +56,7 @@ ..\..\Steam\steamapps\common\Hollow Knight\hollow_knight_Data\Managed\PlayMaker.dll + ..\..\Steam\steamapps\common\Hollow Knight\hollow_knight_Data\Managed\UnityEngine.dll From c184bfd9b615dc3cd3107bb396465d41388eb925 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Thu, 14 Jan 2021 13:16:33 +0100 Subject: [PATCH 06/91] prev binds function --- .gitignore | 1 + Source/Images/ScrollBarArrowLeft.png | Bin 0 -> 843 bytes Source/Images/ScrollBarArrowRight.png | Bin 0 -> 836 bytes Source/KeyBindPanel.cs | 31 +++++++++++++++-- Source/SaveState.cs | 46 ++++++++++++++++---------- 5 files changed, 57 insertions(+), 21 deletions(-) create mode 100644 Source/Images/ScrollBarArrowLeft.png create mode 100644 Source/Images/ScrollBarArrowRight.png diff --git a/.gitignore b/.gitignore index b67ec55..ee1c53a 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,7 @@ artifacts/ *.pidb *.svclog *.scc +*.kra # Chutzpah Test files _Chutzpah* diff --git a/Source/Images/ScrollBarArrowLeft.png b/Source/Images/ScrollBarArrowLeft.png new file mode 100644 index 0000000000000000000000000000000000000000..a151f77cf184b177e9b9a3520e9ff51c8c38a81e GIT binary patch literal 843 zcmV-R1GM~!P)el1esxlN%(+7oWh!+Xzrxc6MZpVFCOcf|q2ba*^6TLduwT)n2wHe^+C7xv#cZlbSQ(KNDc#n9P z73Dnf32~Iu0f}#gu6X<=xZv@ZV4h7c0DjR^DzvcD!mP**;z{C&p_f_XJmMxH)m+I? z9;Gz~8)+nwfCL3)Y(j^F7-f@Y*4`Jd`<78652L?@3OG3mD3UiyYMHvKlr_>-`gByp z-2czh)@G)??x6(G{pz}(<3P_oP^-G`@2Tt7&VaxRaBVjIC7RRRH|f=;7C8pOJHX{l zQ&SFrt6gB^*^;?jmjbl>ng)Da0R1^&=pN`>_h!}D$N3YG-KHnH0}hXX391io`~lwL zXZx^^4m$t<010qNS#tmY4#NNd4#NS*Z>VGd00DnVL_t(I%e9oxD}+H9$6r|`%7x;f zNOHm5uMT3(A(>@qO%f7}IFS z_Im2GJJ0j8*G3a;XmsQTbaz3Kf z;7xto6DT$Ei;S{#Pg~6=JgeN60UO}niVuSUj;}zaOL)^L*yYN*z?owrIUU`g6I`+_ zx6F-!5-ohh;0>s7Y^woGgBeiI*a~a5>9-maOS?J(#8mB`4pZFX% zp_eNbYXO5CC&FCbKF1kfVNIENLGs+Z!@mgoz7el1esxlN%(+7oWh!+Xzrxc6MZpVFCOcf|q2ba*^6TLduwT)n2wHe^+C7xv#cZlbSQ(KNDc#n9P z73Dnf32~Iu0f}#gu6X<=xZv@ZV4h7c0DjR^DzvcD!mP**;z{C&p_f_XJmMxH)m+I? z9;Gz~8)+nwfCL3)Y(j^F7-f@Y*4`Jd`<78652L?@3OG3mD3UiyYMHvKlr_>-`gByp z-2czh)@G)??x6(G{pz}(<3P_oP^-G`@2Tt7&VaxRaBVjIC7RRRH|f=;7C8pOJHX{l zQ&SFrt6gB^*^;?jmjbl>ng)Da0R1^&=pN`>_h!}D$N3YG-KHnH0}hXX391io`~lwL zXZx^^4m$t<010qNS#tmY4#NNd4#NS*Z>VGd00DSOL_t(I%e9oxD@0Kg#~((CvZ2_K zg$?!?3sGccC;kGX6s1@w3n`*(EN07MHmuDo^%hEL%8!KdYcVTigJScp?`gg-$MqWT z@qFtu@7{CYeDAsUoqHW)i~|y21~jt&XUgP%<{7%aAE*Eg%CKI|lopD@?|A zV3X#{Dpm!a%%|Q!LsVnIrGcvqG9U#8IX3+pV^Bl0s*c9K}0pn4OH_TVP zgBP}MKs{Jg;|0)J%D4_(^W|YMW=(Jpwm{wlYu+}l1QQ&*Qff{C&Q5nl}pTQF7=Mr<^0z86KRz?L) z<-|^^1YLX9BtMjBfrsJ2+JbYM8y=dhHJ&O}6(_11{O2p%^5NR7eH9&mrk~0!|E-RT zalej7Ks(!#@j#e5J`8d4`~y-Q^{!Zn^R9^XcKf&cxSY=fNP|%)CVc>PxT~K{;+FgX O0000= pageKeys.Count) page = 0; panel.GetText("Category").UpdateText(pageKeys[page]); - panel.GetButton("Next").UpdateText((page + 1) + " / " + pageKeys.Count); + panel.GetButton("Page").UpdateText((page + 1) + " / " + pageKeys.Count); + UpdateHelpText(); + } + + private static void PrevClicked(string buttonName) + { + page--; + if (page < 0) page = pageKeys.Count - 1; + + panel.GetText("Category").UpdateText(pageKeys[page]); + panel.GetButton("Page").UpdateText((page + 1) + " / " + pageKeys.Count); UpdateHelpText(); } diff --git a/Source/SaveState.cs b/Source/SaveState.cs index cdcc59b..b45f441 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -80,24 +80,34 @@ private void TempSaveState() private void ConvertTempSaveToFile() { - if(autoSlotSelect) { - int i = 0; - int slotAtEntry = currentStateSlot; - while (++currentStateSlot != slotAtEntry || i++ < 10) + if (autoSlotSelect) + + switch (autoSlotSelect) { - if (currentStateSlot < 10) - { - if (String.IsNullOrEmpty(saveStateFiles[currentStateSlot])) + case true: + int i = 0; + int slotAtEntry = currentStateSlot; + while (++currentStateSlot != slotAtEntry || i++ < 10) { - SaveStateToFile(); + if (currentStateSlot < 10) + { + if (String.IsNullOrEmpty(saveStateFiles[currentStateSlot])) + { + SaveStateToFile(); + } + } + else + { + currentStateSlot = -1; + } } - } - else - { - currentStateSlot = -1; - } + break; + case false: + saveStateHUD = true; + break; + default: + break; } - } } private void SaveStateToFile() @@ -115,12 +125,12 @@ private void SaveStateToFile() if (saveStateIdentifier.StartsWith("(tmp)_")) { saveStateIdentifier = saveStateIdentifier.Substring(6); - saveStateFiles[currentStateSlot] = saveStateIdentifier; } - else - { // This is bad + else if (String.IsNullOrEmpty(saveStateIdentifier)) + { saveStateFiles[currentStateSlot] = saveScene + "-" + DateTime.Now.ToString("H:mm_d-MMM"); } + saveStateFiles[currentStateSlot] = saveStateIdentifier; File.WriteAllText(string.Concat(new object[] { @@ -158,7 +168,7 @@ public void LoadState(SaveStateType stateType) } else { - Console.AddLine("No save state in current memory"); + Console.AddLine("No save state active"); } break; case SaveStateType.File: From e67b7c7b350b52f3037924e6461b7a25fe0fb1aa Mon Sep 17 00:00:00 2001 From: cerpintext Date: Mon, 18 Jan 2021 03:43:22 +0100 Subject: [PATCH 07/91] refactored for handling multiple savestates --- DebugMod.sln | 2 - Source/BindableFunctions.cs | 16 +- Source/DebugMod.cs | 160 ++++++++------ Source/DebugMod.csproj | 24 ++- Source/GUIController.cs | 5 + Source/Images/BlankBox.png | Bin 0 -> 795 bytes Source/Images/BlankVertical.png | Bin 0 -> 1414 bytes Source/InfoPanel.cs | 3 + Source/KeyBindPanel.cs | 82 +++---- Source/MinimalInfoPanel.cs | 131 ++++++++++++ Source/{SaveState.cs => SaveStateHandler.cs} | 194 +++++------------ Source/SaveStateManager.cs | 181 ++++++++++++++++ Source/SaveStatesPanel.cs | 213 +++++++++++++++++++ Source/Settings.cs | 18 ++ 14 files changed, 783 insertions(+), 246 deletions(-) create mode 100644 Source/Images/BlankBox.png create mode 100644 Source/Images/BlankVertical.png create mode 100644 Source/MinimalInfoPanel.cs rename Source/{SaveState.cs => SaveStateHandler.cs} (55%) create mode 100644 Source/SaveStateManager.cs create mode 100644 Source/SaveStatesPanel.cs diff --git a/DebugMod.sln b/DebugMod.sln index bc2b6ce..3d5b1bd 100644 --- a/DebugMod.sln +++ b/DebugMod.sln @@ -4,8 +4,6 @@ VisualStudioVersion = 15.0.28307.1340 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DebugMod", "Source\DebugMod.csproj", "{E3E4D0B7-656C-6C50-7567-696E2E57696E}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NewFolder1", "NewFolder1", "{E83EF7B4-FB77-4F28-9984-790847A82818}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 7ed039a..b602952 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -10,7 +10,7 @@ public static class BindableFunctions { private static readonly FieldInfo TimeSlowed = typeof(GameManager).GetField("timeSlowed", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); private static readonly FieldInfo IgnoreUnpause = typeof(UIManager).GetField("ignoreUnpause", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); - private static SaveStateHandler tmpSaveState; + private static SaveState tmpSaveState; //public static string[] saveStateFiles = new string[10]; internal static int CurrentSlot = -1; @@ -162,7 +162,7 @@ public static void TimescaleUp() [BindableMethod(name = "Make Savestate", category = "Savestates")] public static void SaveState() { - tmpSaveState = new SaveStateHandler(); + tmpSaveState = new SaveState(); tmpSaveState.SaveState(SaveStateType.Memory); } @@ -184,7 +184,7 @@ public static void CurrentSaveStateToFile() [BindableMethod(name = "Make Savestate (file)", category = "Savestates")] public static void NewSaveStateToFile() { - tmpSaveState = new SaveStateHandler(); + tmpSaveState = new SaveState(); tmpSaveState.SaveState(SaveStateType.Memory); } @@ -312,7 +312,7 @@ public static void ToggleInfoPanel() DebugMod.settings.InfoPanelVisible = !DebugMod.settings.InfoPanelVisible; } - [BindableMethod(name = "Toggle Menu", category = "Mod UI")] + [BindableMethod(name = "Toggle Top Menu", category = "Mod UI")] public static void ToggleTopRightPanel() { DebugMod.settings.TopMenuVisible = !DebugMod.settings.TopMenuVisible; @@ -334,6 +334,14 @@ public static void ToggleEnemyPanel() } } + // A variant of info panel. View handled in the two InfoPanel classes + // Probably some race-condition potential here :) + [BindableMethod(name = "Full/Min Info Switch", category = "Mod UI")] + public static void ToggleFullInfo() + { + DebugMod.settings.MinInfoPanelVisible = !DebugMod.settings.MinInfoPanelVisible; + } + #endregion #region Enemies diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index ae00844..7f27b89 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -43,93 +43,129 @@ public class DebugMod : Mod internal static bool cameraFollow; internal static Dictionary bindMethods = new Dictionary(); + internal static Dictionary alphaKeyDict = new Dictionary(); + + static int alphaStart; + static int alphaEnd; public override void Initialize() { - instance = this; - - instance.Log("Initializing"); + try + { + instance = this; - float startTime = Time.realtimeSinceStartup; - instance.Log("Building MethodInfo dict..."); + instance.Log("Initializing"); - bindMethods.Clear(); - foreach (MethodInfo method in typeof(BindableFunctions).GetMethods(BindingFlags.Public | BindingFlags.Static)) - { - object[] attributes = method.GetCustomAttributes(typeof(BindableMethod), false); + float startTime = Time.realtimeSinceStartup; + instance.Log("Building MethodInfo dict..."); - if (attributes.Any()) + bindMethods.Clear(); + foreach (MethodInfo method in typeof(BindableFunctions).GetMethods(BindingFlags.Public | BindingFlags.Static)) { - BindableMethod attr = (BindableMethod)attributes[0]; - string name = attr.name; - string cat = attr.category; + object[] attributes = method.GetCustomAttributes(typeof(BindableMethod), false); + + if (attributes.Any()) + { + BindableMethod attr = (BindableMethod)attributes[0]; + string name = attr.name; + string cat = attr.category; - bindMethods.Add(name, new Pair(cat, method)); + bindMethods.Add(name, new Pair(cat, method)); + } } - } - instance.Log("Done! Time taken: " + (Time.realtimeSinceStartup - startTime) + "s. Found " + bindMethods.Count + " methods"); + instance.Log("Done! Time taken: " + (Time.realtimeSinceStartup - startTime) + "s. Found " + bindMethods.Count + " methods"); - settings = GlobalSettings; + settings = GlobalSettings; - if (settings.FirstRun) - { - instance.Log("First run detected, setting default binds"); - - settings.FirstRun = false; - settings.binds.Clear(); - - settings.binds.Add("Toggle All UI", (int)KeyCode.F1); - settings.binds.Add("Toggle Info", (int)KeyCode.F2); - settings.binds.Add("Toggle Menu", (int)KeyCode.F3); - settings.binds.Add("Toggle Console", (int)KeyCode.F4); - settings.binds.Add("Force Pause", (int)KeyCode.F5); - settings.binds.Add("Hazard Respawn", (int)KeyCode.F6); - settings.binds.Add("Set Respawn", (int)KeyCode.F7); - settings.binds.Add("Force Camera Follow", (int)KeyCode.F8); - settings.binds.Add("Toggle Enemy Panel", (int)KeyCode.F9); - settings.binds.Add("Self Damage", (int)KeyCode.F10); - settings.binds.Add("Toggle Binds", (int)KeyCode.BackQuote); - settings.binds.Add("Nail Damage +4", (int)KeyCode.Equals); - settings.binds.Add("Nail Damage -4", (int)KeyCode.Minus); - settings.binds.Add("Increase Timescale", (int)KeyCode.KeypadPlus); - settings.binds.Add("Decrease Timescale", (int)KeyCode.KeypadMinus); - settings.binds.Add("Toggle Hero Light", (int)KeyCode.Home); - settings.binds.Add("Toggle Vignette", (int)KeyCode.Insert); - settings.binds.Add("Zoom In", (int)KeyCode.PageUp); - settings.binds.Add("Zoom Out", (int)KeyCode.PageDown); - settings.binds.Add("Reset Camera Zoom", (int)KeyCode.End); - settings.binds.Add("Toggle HUD", (int)KeyCode.Delete); - settings.binds.Add("Hide Hero", (int)KeyCode.Backspace); - } + if (settings.FirstRun) + { + instance.Log("First run detected, setting default binds"); + + settings.FirstRun = false; + settings.binds.Clear(); + + settings.binds.Add("Toggle All UI", (int)KeyCode.F1); + settings.binds.Add("Toggle Info", (int)KeyCode.F2); + settings.binds.Add("Toggle Top Menu", (int)KeyCode.F3); + settings.binds.Add("Toggle Console", (int)KeyCode.F4); + settings.binds.Add("Force Pause", (int)KeyCode.F5); + settings.binds.Add("Hazard Respawn", (int)KeyCode.F6); + settings.binds.Add("Set Respawn", (int)KeyCode.F7); + settings.binds.Add("Force Camera Follow", (int)KeyCode.F8); + settings.binds.Add("Toggle Enemy Panel", (int)KeyCode.F9); + settings.binds.Add("Self Damage", (int)KeyCode.F10); + settings.binds.Add("Toggle Binds", (int)KeyCode.BackQuote); + settings.binds.Add("Nail Damage +4", (int)KeyCode.Equals); + settings.binds.Add("Nail Damage -4", (int)KeyCode.Minus); + settings.binds.Add("Increase Timescale", (int)KeyCode.KeypadPlus); + settings.binds.Add("Decrease Timescale", (int)KeyCode.KeypadMinus); + settings.binds.Add("Toggle Hero Light", (int)KeyCode.Home); + settings.binds.Add("Toggle Vignette", (int)KeyCode.Insert); + settings.binds.Add("Zoom In", (int)KeyCode.PageUp); + settings.binds.Add("Zoom Out", (int)KeyCode.PageDown); + settings.binds.Add("Reset Camera Zoom", (int)KeyCode.End); + settings.binds.Add("Toggle HUD", (int)KeyCode.Delete); + settings.binds.Add("Hide Hero", (int)KeyCode.Backspace); + } - UnityEngine.SceneManagement.SceneManager.activeSceneChanged += LevelActivated; - GameObject UIObj = new GameObject(); - UIObj.AddComponent(); - GameObject.DontDestroyOnLoad(UIObj); + if (settings.NumPadForSaveStates) + { + alphaStart = (int)KeyCode.Keypad0; + alphaEnd = (int)KeyCode.Keypad9; + } + else + { + alphaStart = (int)KeyCode.Alpha0; + alphaEnd = (int)KeyCode.Alpha9; + } + + int alphaInt = 0; + alphaKeyDict.Clear(); + for (int i = alphaStart; i <= alphaEnd; i++) + { + KeyCode tmpKeyCode = (KeyCode)i; + alphaKeyDict.Add(tmpKeyCode, alphaInt++); + } + + UnityEngine.SceneManagement.SceneManager.activeSceneChanged += LevelActivated; + GameObject UIObj = new GameObject(); + UIObj.AddComponent(); + GameObject.DontDestroyOnLoad(UIObj); - ModHooks.Instance.SavegameLoadHook += LoadCharacter; - ModHooks.Instance.NewGameHook += NewCharacter; - ModHooks.Instance.BeforeSceneLoadHook += OnLevelUnload; - ModHooks.Instance.TakeHealthHook += PlayerDamaged; - ModHooks.Instance.ApplicationQuitHook += SaveSettings; + ModHooks.Instance.SavegameLoadHook += LoadCharacter; + ModHooks.Instance.NewGameHook += NewCharacter; + ModHooks.Instance.BeforeSceneLoadHook += OnLevelUnload; + ModHooks.Instance.TakeHealthHook += PlayerDamaged; + ModHooks.Instance.ApplicationQuitHook += SaveSettings; - BossHandler.PopulateBossLists(); - GUIController.Instance.BuildMenus(); + BossHandler.PopulateBossLists(); + GUIController.Instance.BuildMenus(); - Console.AddLine("New session started " + DateTime.Now); + Console.AddLine("New session started " + DateTime.Now); + } + catch (Exception e) { + DebugMod.instance.Log(String.Concat( + "\n - Source: ", e.Source, + "\n - Message: ", e.Message, + "\n - InnerException: ", e.InnerException, + "\n - RuntimeType:", e.GetType(), + "\n - StackTrace:", e.StackTrace) + ); + } } public override string GetVersion() { - return "1.3.3"; + return "1.4.0"; } public override bool IsCurrent() { + /* try { - GithubVersionHelper helper = new GithubVersionHelper("seanpr96/DebugMod"); + GithubVersionHelper helper = new GithubVersionHelper("seresharp/DebugMod"); Log("Github = " + helper.GetVersion()); return helper.GetVersion() == GetVersion(); } @@ -137,6 +173,8 @@ public override bool IsCurrent() { return true; } + */ + return true; } private void SaveSettings() diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 3a5890f..64ff515 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -31,6 +31,7 @@ default 1591 false + false true @@ -46,6 +47,9 @@ true + + + False @@ -69,6 +73,9 @@ + + + @@ -77,7 +84,7 @@ True Resources.resx - + @@ -149,11 +156,26 @@ + + + + + + + + + + + + <_PostBuildHookTimestamp>@(IntermediateAssembly->'%(FullPath).timestamp') <_PostBuildHookHostPlatform>$(Platform) + + XCOPY "$(TargetDir)DebugMod.dll" "D:\GOG Galaxy\Games\Hollow Knight\hollow_knight_Data\Managed\Mods\" /y + diff --git a/Source/GUIController.cs b/Source/GUIController.cs index 5a8183f..d1521ab 100644 --- a/Source/GUIController.cs +++ b/Source/GUIController.cs @@ -37,6 +37,8 @@ public void BuildMenus() scaler.referenceResolution = new Vector2(1920f, 1080f); canvas.AddComponent(); + MinimalInfoPanel.BuildMenu(canvas); + SaveStatesPanel.BuildMenu(canvas); InfoPanel.BuildMenu(canvas); TopMenu.BuildMenu(canvas); EnemiesPanel.BuildMenu(canvas); @@ -82,6 +84,7 @@ private void LoadResources() foreach (string res in resourceNames) { + //DebugMod.instance.Log(res + "\n\n"); if (res.StartsWith("DebugMod.Images.")) { try @@ -109,7 +112,9 @@ private void LoadResources() public void Update() { + MinimalInfoPanel.Update(); InfoPanel.Update(); + SaveStatesPanel.Update(); TopMenu.Update(); EnemiesPanel.Update(); Console.Update(); diff --git a/Source/Images/BlankBox.png b/Source/Images/BlankBox.png new file mode 100644 index 0000000000000000000000000000000000000000..acca5ef7068f5e703880f9b822773213f3237fa8 GIT binary patch literal 795 zcmeAS@N?(olHy`uVBq!ia0y~yV4MPEpWt8vlIQ=4&j1P(W;#0uWF{vwFlbCHooMTQ zI6$QB{x+|r+e$7t9#M1_Z4c{evhZTv9n!w7DRlZ1v&>c%UUSW$7*_H2rsfxqu0OE9 z5Lyr_z~U-U_>up|R*%l-X02kG{yQxB-`l=_c(0hT-YvcD?sOKO%MWjsctz>1@jO`m zL%@|KnB(M`ZPSXnE5G#2cVD%v!lNT@@9SO15(2kMK9E+Jmnv4?@x0SGx=*#DzhcJJ zr%E3=3+G&B?96XnSMf(}$CHoK6Xu=QW2n0rtW~<<(!n)ncprH_nz1lE^0mz)wZyA2 zCj;e{nzBhpE}7WG!Wx?6)ZWaJIyvpy-RU{MrUfeUFW%oOWnt;1G1=TNYwE65Q%o;~ z{wle0@QW( z-LlLVWgmQ6wpNqU^2)^cp-EC3dkpy}q|5>bFHb)2G{CT*?nT z6f|)Bda>93-jDR(9A0^Sz&PM6@Q5sCV30cm!i;$rO6`C#65#3L7*cWT?Lk9Epprui lzWV3#$S(jgM*%q@P$Bicg@Msm>dkqOZckS~mvv4FO#p32)6@U} literal 0 HcmV?d00001 diff --git a/Source/Images/BlankVertical.png b/Source/Images/BlankVertical.png new file mode 100644 index 0000000000000000000000000000000000000000..f8e3b3fd644782ccd9dfdd3b815c66145ed73a20 GIT binary patch literal 1414 zcmeAS@N?(olHy`uVBq!ia0y~yV4T3fz!bs31{Cpmv!MehP?YKH9FUou%)p>Av2>!X z_u&AMw)@+>T(w0@1PVI>jxKCnrO+32Q19x(wFy^Mclt&tdLH)e5(z(ebm0SqT|Z2J z@Rx|jh_W~ey2SipuG0;Aw9|K?>n-8DbBC+XSMT^9b720ZnTh2`84s6KSk0UeR-7I5 zLDr5(p~cYWLjJhLBdgi;YT2|4~88`R!Ew}i%t&$I3E6z(5EAM#T864fGTG3z8 zA^OzjBWK~1%Z#1*t?MfOsO@<0aeBf$UwwwUi@{o3He5Qi<^=B}&qo~#r$;`vd8DRz zHRfc1+(J_>=}eW04J@pwIZo}(5~-8ZuH6$~|9e`X693};ty~tCTpE+iy|QNRS~bP= zQs}RekRx~gpTB%9ZQ0&;3t2AweYI=;V}}Cy6``@;zh5cMPIq{~y2EVtKcTak?`D6= z3htI+ekl9k)3TMC><6yu8T`pP8MDrtF{;j&*-o$FpNv5T|Ce>uo3q|L{=<19@3Qb+ z#&-7uELYpj|1pS5W{6tO6}|?H1kM7F$YKTtxkDh#n0KMnj)8%Bm#2$kNX4zU2Mrm4 vN)9df>YvLIzW~S_1*0J_8Ulkh1RAb0tkhy)wA-^f6y!!vS3j3^P6> bindPages = new Dictionary>(); private static List pageKeys; - + public static KeyCode keyWarning = KeyCode.None; + // TODO: Refactor to allow rotating images public static void BuildMenu(GameObject canvas) { - panel = new CanvasPanel(canvas, GUIController.Instance.images["HelpBG"], new Vector2(1123, 456), Vector2.zero, new Rect(0, 0, GUIController.Instance.images["HelpBG"].width, GUIController.Instance.images["HelpBG"].height)); - panel.AddText("Label", "Binds", new Vector2(130f, -25f), Vector2.zero, GUIController.Instance.trajanBold, 30); - - panel.AddText("Category", "", new Vector2(25f, 25f), Vector2.zero, GUIController.Instance.trajanNormal, 20); - panel.AddText("Help", "", new Vector2(25f, 50f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddButton("Page", GUIController.Instance.images["ButtonRect"], new Vector2(125, 250), Vector2.zero, NextClicked, new Rect(0, 0, GUIController.Instance.images["ButtonRect"].width, GUIController.Instance.images["ButtonRect"].height), GUIController.Instance.trajanBold, "# / #"); - panel.AddButton( - "NextPage", - GUIController.Instance.images["ScrollBarArrowRight"], - new Vector2(223, 250), - Vector2.zero, - NextClicked, - new Rect(0, 0, GUIController.Instance.images["ScrollBarArrowRight"].width, GUIController.Instance.images["ScrollBarArrowRight"].height) - ); - panel.AddButton( - "PrevPage", - GUIController.Instance.images["ScrollBarArrowLeft"], - new Vector2(95, 250), - Vector2.zero, - PrevClicked, - new Rect(0, 0, GUIController.Instance.images["ScrollBarArrowLeft"].width, GUIController.Instance.images["ScrollBarArrowLeft"].height) - ); + panel = new CanvasPanel(canvas, GUIController.Instance.images["HelpBG"], new Vector2(1123, 456), Vector2.zero, new Rect(0, 0, GUIController.Instance.images["HelpBG"].width, GUIController.Instance.images["HelpBG"].height)); + panel.AddText("Label", "Binds", new Vector2(130f, -25f), Vector2.zero, GUIController.Instance.trajanBold, 30); + + panel.AddText("Category", "", new Vector2(25f, 25f), Vector2.zero, GUIController.Instance.trajanNormal, 20); + panel.AddText("Help", "", new Vector2(25f, 50f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddButton("Page", GUIController.Instance.images["ButtonRect"], new Vector2(125, 250), Vector2.zero, NextClicked, new Rect(0, 0, GUIController.Instance.images["ButtonRect"].width, GUIController.Instance.images["ButtonRect"].height), GUIController.Instance.trajanBold, "# / #"); + + + panel.AddButton( + "NextPage", + GUIController.Instance.images["ScrollBarArrowRight"], + new Vector2(223, 254), + Vector2.zero, + NextClicked, + new Rect( + 0, + 0, + GUIController.Instance.images["ScrollBarArrowRight"].width, + GUIController.Instance.images["ScrollBarArrowRight"].height) + ); + panel.AddButton( + "PrevPage", + GUIController.Instance.images["ScrollBarArrowLeft"], + new Vector2(95, 254), + Vector2.zero, + NextClicked, + new Rect( + 0, + 0, + GUIController.Instance.images["ScrollBarArrowLeft"].width, + GUIController.Instance.images["ScrollBarArrowLeft"].height) + ); + for (int i = 0; i < 11; i++) { panel.AddButton(i.ToString(), GUIController.Instance.images["Scrollbar_point"], new Vector2(300f, 45f + 17.5f * i), Vector2.zero, ChangeBind, new Rect(0, 0, GUIController.Instance.images["Scrollbar_point"].width, GUIController.Instance.images["Scrollbar_point"].height)); @@ -57,7 +69,7 @@ public static void BuildMenu(GameObject canvas) pageKeys = bindPages.Keys.ToList(); panel.GetText("Category").UpdateText(pageKeys[page]); - panel.GetButton("Next").UpdateText((page + 1) + " / " + pageKeys.Count); + panel.GetButton("Page").UpdateText((page + 1) + " / " + pageKeys.Count); UpdateHelpText(); } @@ -100,19 +112,17 @@ public static void UpdateHelpText() private static void NextClicked(string buttonName) { - page++; - if (page >= pageKeys.Count) page = 0; - - panel.GetText("Category").UpdateText(pageKeys[page]); - panel.GetButton("Page").UpdateText((page + 1) + " / " + pageKeys.Count); - UpdateHelpText(); - } + if (buttonName.StartsWith("Prev")) + { + page--; + if (page < 0) page = pageKeys.Count - 1; + } + else + { + page++; + if (page >= pageKeys.Count) page = 0; + } - private static void PrevClicked(string buttonName) - { - page--; - if (page < 0) page = pageKeys.Count - 1; - panel.GetText("Category").UpdateText(pageKeys[page]); panel.GetButton("Page").UpdateText((page + 1) + " / " + pageKeys.Count); UpdateHelpText(); diff --git a/Source/MinimalInfoPanel.cs b/Source/MinimalInfoPanel.cs new file mode 100644 index 0000000..2a519de --- /dev/null +++ b/Source/MinimalInfoPanel.cs @@ -0,0 +1,131 @@ +using UnityEngine; +using InControl; + +namespace DebugMod +{ + public static class MinimalInfoPanel + { + private static CanvasPanel panel; + private static CanvasPanel panelCurrentSaveState; + + public static void BuildMenu(GameObject canvas) + { + panel = new CanvasPanel( + canvas, + GUIController.Instance.images["BlankBox"], + new Vector2(130f, 230f), + Vector2.zero, + new Rect( + 0f, + 0f, + GUIController.Instance.images["BlankBox"].width, + GUIController.Instance.images["BlankBox"].height + ) + ); + panelCurrentSaveState = new CanvasPanel( + canvas, + GUIController.Instance.images["BlankBox"], + new Vector2(140f, 340f), + Vector2.zero, + new Rect( + 0f, + 0f, + GUIController.Instance.images["BlankBox"].width, + GUIController.Instance.images["BlankBox"].height + ) + ); + + //Labels + panel.AddText("Velocity Label", "Vel", new Vector2(10f, 10f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Position Label", "Hero Pos", new Vector2(70f, 10f), Vector2.zero, GUIController.Instance.arial); + panel.AddText("Move Label", "Move (Raw)", new Vector2(130f, 10f), Vector2.zero, GUIController.Instance.arial); + + panel.AddText("MP Label", "MP", new Vector2(10f, 30f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Nail Damage Label", "Naildmg", new Vector2(70f, 30f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("canSuperdash Label", "CanCdash", new Vector2(130f, 30f), Vector2.zero, GUIController.Instance.arial, 15); + + panel.AddText("Completion Label", "Completion", new Vector2(10f, 50f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Grubs Label", "Grubs", new Vector2(90f, 50f), Vector2.zero, GUIController.Instance.arial, 15); + + panel.AddText("Scene Name Label", "Scene Name", new Vector2(10f, 70f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Current Save State Lable", "Current", new Vector2(10f, 90f), Vector2.zero, GUIController.Instance.arial, 15); + + panelCurrentSaveState.AddText("Current Save State Lable", "Current", new Vector2(10f, 10f), Vector2.zero, GUIController.Instance.arial, 15); + + //Values + panel.AddText("Vel", "", new Vector2(40f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Hero Pos", "", new Vector2(120f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Move (Raw)", "", new Vector2(200f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); + + panel.AddText("MP", "", new Vector2(50f, 50f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Naildmg", "", new Vector2(50f, 30f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("CanCdash", "", new Vector2(440f, 30f), Vector2.zero, GUIController.Instance.trajanNormal); + + panel.AddText("Completion", "", new Vector2(60f, 50f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Grubs", "", new Vector2(120f, 50f), Vector2.zero, GUIController.Instance.trajanNormal); + + panel.AddText("Scene Name", "", new Vector2(50f, 70f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Current", "", new Vector2(50f, 90f), Vector2.zero, GUIController.Instance.trajanNormal); + // Current SaveState might work better as a panel? + + panel.FixRenderOrder(); + } + + public static void Update() + { + + + if (panel == null || panelCurrentSaveState == null) + { + return; + } + + if (DebugMod.GM.IsNonGameplayScene()) + { + if (panel.active) + { + panel.SetActive(false, true); + } + return; + } + + // Not intended min/full info panel logic, but should show the two panels one at a time + if (DebugMod.settings.MinInfoPanelVisible && !panel.active) + { + panel.SetActive(true, false); + if (DebugMod.settings.InfoPanelVisible) { + DebugMod.settings.InfoPanelVisible = false; + } + } + else if (!DebugMod.settings.MinInfoPanelVisible && panel.active) + { + panel.SetActive(false, true); + } + + if (panel.active) + { + PlayerData.instance.CountGameCompletion(); + + panel.GetText("Vel").UpdateText(HeroController.instance.current_velocity.ToString()); + panel.GetText("Hero Pos").UpdateText(DebugMod.RefKnight.transform.position.ToString()); + panel.GetText("Move (Raw)").UpdateText(string.Format("L: {0} R: {1}", DebugMod.IH.inputActions.left.RawValue, DebugMod.IH.inputActions.right.RawValue)); + + panel.GetText("NailDmg").UpdateText(DebugMod.RefKnightSlash.FsmVariables.GetFsmInt("damageDealt").Value + " (Flat " + PlayerData.instance.nailDamage + ", x" + DebugMod.RefKnightSlash.FsmVariables.GetFsmFloat("Multiplier").Value + ")"); + + panel.GetText("MP").UpdateText((PlayerData.instance.MPCharge + PlayerData.instance.MPReserve).ToString()); + panel.GetText("CanCdash").UpdateText(GetStringForBool(HeroController.instance.CanSuperDash())); + + panel.GetText("Completion").UpdateText(PlayerData.instance.completionPercentage.ToString()); + panel.GetText("Grubs").UpdateText(PlayerData.instance.grubsCollected + " / 46"); + + panel.GetText("Scene Name").UpdateText(DebugMod.GetSceneName()); + panel.GetText("Current").UpdateText(); + } + } + + private static string GetStringForBool(bool b) + { + return b ? "✓" : "X"; + } + } +} diff --git a/Source/SaveState.cs b/Source/SaveStateHandler.cs similarity index 55% rename from Source/SaveState.cs rename to Source/SaveStateHandler.cs index b45f441..efcf0fa 100644 --- a/Source/SaveState.cs +++ b/Source/SaveStateHandler.cs @@ -9,13 +9,10 @@ namespace DebugMod { - public enum SaveStateType { - Memory, - File, - CurrentMemoryToFile - } - - internal class SaveStateHandler : MonoBehaviour + /// + /// Saves and loads states from runtime data in Hollow Knight + /// + internal class SaveState : MonoBehaviour { private string saveStateIdentifier = ""; private string saveScene; @@ -24,22 +21,20 @@ internal class SaveStateHandler : MonoBehaviour private SceneData savedSd; private Vector3 savePos; private FieldInfo cameraLockArea; + private string filePath = ""; + - public static int currentStateSlot = -1; - //public static bool preserveThroughStates = false; - public static string[] saveStateFiles = new string[10]; - //private bool exists; - - public static bool saveStateHUD = false; - public static bool minimalInfoHUD = false; - private static bool autoSlotSelect = true; + internal SaveState() + { + + } - internal SaveStateHandler() + internal SaveState(SaveState saveState) { } - private SaveStateHandler(string _scene, string _identifier, PlayerData _pd, SceneData _sd, Vector3 _pos, FieldInfo _cameraLockArea, object _paramLockArea) { + private SaveState(string _scene, string _identifier, PlayerData _pd, SceneData _sd, Vector3 _pos, FieldInfo _cameraLockArea, object _paramLockArea) { saveScene = _scene; saveStateIdentifier = _identifier; savedPd = _pd; @@ -50,24 +45,8 @@ private SaveStateHandler(string _scene, string _identifier, PlayerData _pd, Scen } #region saving - public void SaveState(SaveStateType stateType) - { - switch (stateType) - { - case SaveStateType.Memory: - TempSaveState(); - break; - case SaveStateType.File: - ConvertTempSaveToFile(); - break; - case SaveStateType.CurrentMemoryToFile: - ConvertTempSaveToFile(); - break; - default: break; - } - } - private void TempSaveState() + public void SaveTempState() { saveScene = GameManager.instance.GetSceneNameString(); saveStateIdentifier = "(tmp)_" + saveScene + "-" + DateTime.Now.ToString("H:mm_d-MMM"); @@ -78,76 +57,21 @@ private void TempSaveState() lockArea = cameraLockArea.GetValue(GameManager.instance.cameraCtrl); } - private void ConvertTempSaveToFile() - { - if (autoSlotSelect) - - switch (autoSlotSelect) - { - case true: - int i = 0; - int slotAtEntry = currentStateSlot; - while (++currentStateSlot != slotAtEntry || i++ < 10) - { - if (currentStateSlot < 10) - { - if (String.IsNullOrEmpty(saveStateFiles[currentStateSlot])) - { - SaveStateToFile(); - } - } - else - { - currentStateSlot = -1; - } - } - break; - case false: - saveStateHUD = true; - break; - default: - break; - } - } - - private void SaveStateToFile() + public void SaveStateToFile(SaveState paramSave, int paramSlot) { try { - int slotAtEntry = currentStateSlot; - if (slotAtEntry < 0 || slotAtEntry >= 10) - { - throw new Exception("No savestate slot index set, abort making file"); - } - Directory.CreateDirectory(Application.persistentDataPath + "/Savestates-1221"); - - if (saveStateIdentifier.StartsWith("(tmp)_")) { saveStateIdentifier = saveStateIdentifier.Substring(6); } else if (String.IsNullOrEmpty(saveStateIdentifier)) { - saveStateFiles[currentStateSlot] = saveScene + "-" + DateTime.Now.ToString("H:mm_d-MMM"); + throw new Exception("No temp save state set"); } - saveStateFiles[currentStateSlot] = saveStateIdentifier; - File.WriteAllText(string.Concat(new object[] - { - Application.persistentDataPath, - "/Savestates-1221/savestate", - currentStateSlot, - ".json" - }), JsonUtility.ToJson(obj: new SaveStateHandler - ( - saveScene, - saveStateIdentifier, - savedPd, - savedSd, - savePos, - cameraLockArea, - lockArea - ), prettyPrint: true)); + filePath = SaveStateManager.path + paramSlot + ".json"; + File.WriteAllText(string.Concat(new object[]{filePath}), JsonUtility.ToJson(paramSave, prettyPrint: true)); } catch (Exception ex) { @@ -157,60 +81,35 @@ private void SaveStateToFile() #endregion #region loading - public void LoadState(SaveStateType stateType) - { - switch (stateType) - { - case SaveStateType.Memory: - if (!String.IsNullOrEmpty(saveStateIdentifier)) - { - HeroController.instance.StartCoroutine(LoadStateCoro()); - } - else - { - Console.AddLine("No save state active"); - } - break; - case SaveStateType.File: - PrepareFileStateToMemory(); - // Implement slot controls - break; - case SaveStateType.CurrentMemoryToFile: - LoadStateFromFile(); - // Implement slot controls - break; - default: - break; - } - - //HeroController.instance.StartCoroutine(LoadStateCoro()); + public void LoadTempState() + { + HeroController.instance.StartCoroutine(LoadStateCoro()); + } + public void LoadStateFromFile() + { + PrepareFileStateToMemory(SaveStateManager.currentStateSlot); + HeroController.instance.StartCoroutine(LoadStateCoro()); } - private void PrepareFileStateToMemory() + public void PrepareFileStateToMemory(int paramSlot) { try { + SaveState tmpData = new SaveState(); - int slot = currentStateSlot; - SaveStateHandler tmpData = new SaveStateHandler(); - if (slot < 0 || slot >= 10) - { - Console.AddLine("No slot selected, aborting prep"); - return; - } - string path = string.Concat(new object[] + filePath = string.Concat(new object[] { Application.persistentDataPath, "/Savestates-1221/savestate", - slot, + paramSlot, ".json" }); - if (File.Exists(path)) + if (File.Exists(filePath)) { - tmpData = JsonUtility.FromJson(File.ReadAllText(path)); + tmpData = JsonUtility.FromJson(File.ReadAllText(filePath)); try { saveStateIdentifier = tmpData.saveStateIdentifier; @@ -234,14 +133,9 @@ private void PrepareFileStateToMemory() } } - private void LoadStateFromFile() - { - PrepareFileStateToMemory(); - HeroController.instance.StartCoroutine(LoadStateCoro()); - } - private IEnumerator LoadStateCoro() { + Console.AddLine("LoadStateCoro line1: " + savedPd.hazardRespawnLocation.ToString()); cameraLockArea = (cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); GameManager.instance.ChangeToScene("Room_Sly_Storeroom", "", 0f); while (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != "Room_Sly_Storeroom") @@ -251,6 +145,7 @@ private IEnumerator LoadStateCoro() GameManager.instance.sceneData = (SceneData.instance = JsonUtility.FromJson(JsonUtility.ToJson(savedSd))); //if (!BindableFunctions.preserveThroughStates) //{ + Console.AddLine("Before ResetSemiPersistentItems(): " + savedPd.hazardRespawnLocation.ToString()); GameManager.instance.ResetSemiPersistentItems(); //} yield return null; @@ -284,7 +179,8 @@ private IEnumerator LoadStateCoro() HeroController.instance.TakeMP(1); HeroController.instance.AddMPChargeSpa(1); } - HeroController.instance.SetHazardRespawn(savedPd.hazardRespawnLocation, savedPd.hazardRespawnFacingRight); + Console.AddLine("LoadStateCoro end of func: " + savedPd.hazardRespawnLocation.ToString()); + //HeroController.instance.SetHazardRespawn(savedPd.hazardRespawnLocation, savedPd.hazardRespawnFacingRight); HeroController.instance.proxyFSM.SendEvent("HeroCtrl-HeroDamaged"); HeroController.instance.geoCounter.playerData = PlayerData.instance; HeroController.instance.geoCounter.TakeGeo(0); @@ -300,20 +196,34 @@ private IEnumerator LoadStateCoro() #endregion #region helper functionality + public bool IsSet() { bool isSet = false; - if (String.IsNullOrEmpty(saveStateIdentifier)) + if (!String.IsNullOrEmpty(saveStateIdentifier)) { isSet = true; } return isSet; } - public void ToggleAutoSlot() + public string GetSaveStateID() + { + return saveStateIdentifier; + } + + public string[] GetSaveStateInfo() { - autoSlotSelect = !autoSlotSelect; + return new string[] + { + filePath, + saveScene, + saveStateIdentifier, + savedPd.ToString(), + savedSd.ToString() + }; } + #endregion } } diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs new file mode 100644 index 0000000..a5691d0 --- /dev/null +++ b/Source/SaveStateManager.cs @@ -0,0 +1,181 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using UnityEngine; + +namespace DebugMod +{ + public enum SaveStateType { + Memory, + File, + SkipOne + } + + /// + /// Handles organisation of SaveState-s + /// memoryState replicating legacy behaviour of only stored in RAM. + /// Dictionary(int slot : file). Might change to HashMap(?) + /// if: memory requirement too high: array for limiting savestates? hashmap as all states should logically be unique? + /// HUD for viewing necessary info for UX. + /// AutoSlotSelect to iterate over slots, eventually overwrite when circled and no free slots. + /// + internal class SaveStateManager : MonoBehaviour + { + public static SaveState memoryState; + private static Dictionary saveStateFiles = new Dictionary(); + + public static int currentStateSlot = -1; + public static string path = Application.persistentDataPath + "/Savestates-1221"; + public const int maxSaveStates = 10; + public static bool saveStateHUD = false; + public static bool autoSlotSelect = true; + //public static bool preserveThroughStates = false; + + internal SaveStateManager() + { + try + { + saveStateHUD = false; + memoryState = new SaveState(); + if (Directory.Exists(SaveStateManager.path)) + { + Directory.CreateDirectory(path); + } + } + catch (Exception) + { + throw; + } + } + + #region saving + public void SaveState(SaveStateType stateType) + { + switch (stateType) + { + case SaveStateType.Memory: + if (!memoryState.IsSet()) memoryState.SaveTempState(); + memoryState.SaveTempState(); + break; + case SaveStateType.File: + if (memoryState.IsSet()) + { + if (autoSlotSelect) + { + int i = 0; + int initSlot = currentStateSlot; + + // Refactor using dict.keys()? + while (++currentStateSlot != initSlot && ++i < maxSaveStates) + { + if (currentStateSlot == maxSaveStates) + { + currentStateSlot = 0; + } + if (!saveStateFiles.ContainsKey(currentStateSlot)) + { + saveStateFiles.Add(currentStateSlot, new SaveState()); + } + } + if (currentStateSlot == initSlot) + { + // TODO: Inquire if want to overwrite + if (--currentStateSlot < 0) currentStateSlot = maxSaveStates - 1; + saveStateFiles.Remove(currentStateSlot); + saveStateFiles.Add(currentStateSlot, new SaveState()); + } + } + else + { + // slot selection algo: + // ++current + // if (open slot[current]) states[current] = new Obj() return? + // if oob current = 0 + // loop + } + + if (!memoryState.IsSet()) memoryState.SaveTempState(); + saveStateFiles[currentStateSlot].SaveStateToFile(memoryState, currentStateSlot); + } + break; + case SaveStateType.SkipOne: + + break; + default: break; + } + } + + + + #endregion + + #region loading + public void LoadState(SaveStateType stateType) + { + switch (stateType) + { + case SaveStateType.Memory: + if (memoryState.IsSet()) + { + memoryState.LoadTempState(); + } + else + { + Console.AddLine("No save state active"); + } + break; + case SaveStateType.File: + if (!saveStateFiles.ContainsKey(currentStateSlot)) + { + // change currentStateSlot + } + saveStateFiles[currentStateSlot].PrepareFileStateToMemory(currentStateSlot); + break; + case SaveStateType.SkipOne: + if (!saveStateFiles.ContainsKey(currentStateSlot)) + { + // change currentStateSlot + } + saveStateFiles[currentStateSlot].LoadStateFromFile(); + break; + default: + break; + } + } + + #endregion + + #region helper functionality + private IEnumerator SelectSlot() + { + saveStateHUD = false; + yield return null; + + foreach (KeyValuePair entry in DebugMod.alphaKeyDict) + { + if (Input.GetKeyDown(entry.Key)) + { + if (DebugMod.alphaKeyDict.TryGetValue(entry.Key, out int keyInt)) + { + // keyInt should be between 0-9 + currentStateSlot = keyInt; + } + } + + } + // ui hud to select slot + saveStateHUD = false; + yield return null; + } + + public void ToggleAutoSlot() + { + autoSlotSelect = !autoSlotSelect; + } + #endregion + } +} diff --git a/Source/SaveStatesPanel.cs b/Source/SaveStatesPanel.cs new file mode 100644 index 0000000..36c8419 --- /dev/null +++ b/Source/SaveStatesPanel.cs @@ -0,0 +1,213 @@ +using UnityEngine; +using InControl; + +namespace DebugMod +{ + public static class SaveStatesPanel + { + private static CanvasPanel panel; + + public static void BuildMenu(GameObject canvas) + { + panel = new CanvasPanel( + canvas, + GUIController.Instance.images["BlankVertical"], + new Vector2(570f, 230f), + Vector2.zero, + new Rect( + 0f, + 0f, + GUIController.Instance.images["BlankVertical"].width, + GUIController.Instance.images["BlankVertical"].height + ) + ); + + //Labels + panel.AddText("Hero State Label", "Hero State", new Vector2(10f, 20f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Velocity Label", "Velocity", new Vector2(10f, 40f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Nail Damage Label", "Naildmg", new Vector2(10f, 60f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("HP Label", "HP", new Vector2(10f, 80f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("MP Label", "MP", new Vector2(10f, 100f), Vector2.zero, GUIController.Instance.arial, 15); + + + panel.AddText("Grubs Label", "Grubs", new Vector2(10f, 198f), Vector2.zero, GUIController.Instance.arial, 15); + + + panel.AddText("Scene Name Label", "Scene Name", new Vector2(10f, 454), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Transition Label", "Transition", new Vector2(10f, 474f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Trans State Label", "Trans State", new Vector2(10f, 494f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("is Gameplay Label", "Is Gameplay", new Vector2(10f, 514f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Game State Label", "Game State", new Vector2(10f, 534f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("UI State Label", "UI State", new Vector2(10f, 554f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Hero Paused Label", "Hero Paused", new Vector2(10f, 574f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Camera Mode Label", "Camera Mode", new Vector2(10f, 594f), Vector2.zero, GUIController.Instance.arial, 15); + + panel.AddText("Accept Input Label", "Accept Input", new Vector2(300f, 30f), Vector2.zero, GUIController.Instance.arial, 15); + + panel.AddText("Falling Label", "Falling", new Vector2(300f, 180f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Hardland Label", "Hardland", new Vector2(300f, 200f), Vector2.zero, GUIController.Instance.arial, 15); + + panel.AddText("Wall lock Label", "Wall lock", new Vector2(300f, 290f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Wall jumping Label", "Wall jumping", new Vector2(300f, 310f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Wall touching Label", "Wall touching", new Vector2(300f, 330f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Wall sliding Label", "Wall sliding", new Vector2(300f, 350f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Wall left Label", "Wall left", new Vector2(300f, 370f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Wall right Label", "Wall right", new Vector2(300f, 390f), Vector2.zero, GUIController.Instance.arial, 15); + + panel.AddText("Attacking Label", "Attacking", new Vector2(300f, 440f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("canCast Label", "canCast", new Vector2(300f, 460f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("canSuperdash Label", "canSuperdash", new Vector2(300f, 480f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("canQuickmap Label", "canQuickmap", new Vector2(300f, 500f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("canInventory Label", "canInventory", new Vector2(300f, 520f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("canWarp Label", "canWarp", new Vector2(300f, 540f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("canDGate Label", "canDGate", new Vector2(300f, 560f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("gateAllow Label", "gateAllow", new Vector2(300f, 580f), Vector2.zero, GUIController.Instance.arial, 15); + + //Values + panel.AddText("Hero State", "", new Vector2(150f, 20f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Velocity", "", new Vector2(150f, 40f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Nail Damage", "", new Vector2(150f, 60f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("HP", "", new Vector2(150f, 80f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("MP", "", new Vector2(150f, 100f), Vector2.zero, GUIController.Instance.trajanNormal); + + panel.AddText("Completion", "", new Vector2(150f, 178f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Grubs", "", new Vector2(150f, 198f), Vector2.zero, GUIController.Instance.trajanNormal); + + panel.AddText("Scene Name", "", new Vector2(150f, 454), Vector2.zero, GUIController.Instance.trajanNormal); + + panel.AddText("Dashing", "", new Vector2(440f, 120f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Jumping", "", new Vector2(440f, 140f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Superdashing", "", new Vector2(440f, 160f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Falling", "", new Vector2(440f, 180f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Hardland", "", new Vector2(440f, 200f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Swimming", "", new Vector2(440f, 220f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Recoiling", "", new Vector2(440f, 240f), Vector2.zero, GUIController.Instance.trajanNormal); + + panel.AddText("Wall lock", "", new Vector2(440f, 290f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Wall jumping", "", new Vector2(440f, 310f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Wall touching", "", new Vector2(440f, 330f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Wall sliding", "", new Vector2(440f, 350f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Wall left", "", new Vector2(440f, 370f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Wall right", "", new Vector2(440f, 390f), Vector2.zero, GUIController.Instance.trajanNormal); + + panel.AddText("Attacking", "", new Vector2(440f, 440f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("canCast", "", new Vector2(440f, 460f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("canSuperdash", "", new Vector2(440f, 480f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("canQuickmap", "", new Vector2(440f, 500f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("canInventory", "", new Vector2(440f, 520f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("canWarp", "", new Vector2(440f, 540f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("canDGate", "", new Vector2(440f, 560f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("gateAllow", "", new Vector2(440f, 580f), Vector2.zero, GUIController.Instance.trajanNormal); + + //Bottom right info + panel.AddText("Right1 Label", "Session Time\nLoad\nHero Pos\nMove Raw", new Vector2(1285, 747), Vector2.zero, GUIController.Instance.arial); + panel.AddText("Right1", "", new Vector2(1385, 747), Vector2.zero, GUIController.Instance.trajanNormal); + + panel.AddText("Right2 Label", "Move Vector\nKey Pressed\nMove Pressed\nInput X", new Vector2(1500, 747), Vector2.zero, GUIController.Instance.arial); + panel.AddText("Right2", "", new Vector2(1600, 747), Vector2.zero, GUIController.Instance.trajanNormal); + + panel.FixRenderOrder(); + } + + public static void Update() + { + if (panel == null) + { + return; + } + + if (DebugMod.GM.IsNonGameplayScene()) + { + if (panel.active) + { + panel.SetActive(false, true); + } + + return; + } + + if (DebugMod.settings.InfoPanelVisible && !panel.active) + { + panel.SetActive(true, false); + } + else if (!DebugMod.settings.InfoPanelVisible && panel.active) + { + panel.SetActive(false, true); + } + + if (panel.active) + { + PlayerData.instance.CountGameCompletion(); + + panel.GetText("Hero State").UpdateText(HeroController.instance.hero_state.ToString()); + panel.GetText("Velocity").UpdateText(HeroController.instance.current_velocity.ToString()); + panel.GetText("Nail Damage").UpdateText(DebugMod.RefKnightSlash.FsmVariables.GetFsmInt("damageDealt").Value + " (Flat " + PlayerData.instance.nailDamage + ", x" + DebugMod.RefKnightSlash.FsmVariables.GetFsmFloat("Multiplier").Value + ")"); + panel.GetText("HP").UpdateText(PlayerData.instance.health + " / " + PlayerData.instance.maxHealth); + panel.GetText("MP").UpdateText((PlayerData.instance.MPCharge + PlayerData.instance.MPReserve).ToString()); + + panel.GetText("Completion").UpdateText(PlayerData.instance.completionPercentage.ToString()); + panel.GetText("Grubs").UpdateText(PlayerData.instance.grubsCollected + " / 46"); + + panel.GetText("isInvuln").UpdateText(GetStringForBool(HeroController.instance.cState.invulnerable)); + panel.GetText("Invincible").UpdateText(GetStringForBool(PlayerData.instance.isInvincible)); + panel.GetText("Invincitest").UpdateText(GetStringForBool(PlayerData.instance.invinciTest)); + panel.GetText("Damage State").UpdateText(HeroController.instance.damageMode.ToString()); + panel.GetText("Dead State").UpdateText(GetStringForBool(HeroController.instance.cState.dead)); + panel.GetText("Hazard Death").UpdateText(HeroController.instance.cState.hazardDeath.ToString()); + + panel.GetText("Scene Name").UpdateText(DebugMod.GetSceneName()); + panel.GetText("Transition").UpdateText(GetStringForBool(HeroController.instance.cState.transitioning)); + + string transState = HeroController.instance.transitionState.ToString(); + if (transState == "WAITING_TO_ENTER_LEVEL") transState = "LOADING"; + if (transState == "WAITING_TO_TRANSITION") transState = "WAITING"; + + panel.GetText("Trans State").UpdateText(transState); + panel.GetText("is Gameplay").UpdateText(GetStringForBool(DebugMod.GM.IsGameplayScene())); + panel.GetText("Game State").UpdateText(GameManager.instance.gameState.ToString()); + panel.GetText("UI State").UpdateText(UIManager.instance.uiState.ToString()); + panel.GetText("Hero Paused").UpdateText(GetStringForBool(HeroController.instance.cState.isPaused)); + panel.GetText("Camera Mode").UpdateText(DebugMod.RefCamera.mode.ToString()); + + panel.GetText("Accept Input").UpdateText(GetStringForBool(HeroController.instance.acceptingInput)); + panel.GetText("Relinquished").UpdateText(GetStringForBool(HeroController.instance.controlReqlinquished)); + panel.GetText("atBench").UpdateText(GetStringForBool(PlayerData.instance.atBench)); + + panel.GetText("Dashing").UpdateText(GetStringForBool(HeroController.instance.cState.dashing)); + panel.GetText("Jumping").UpdateText(GetStringForBool((HeroController.instance.cState.jumping || HeroController.instance.cState.doubleJumping))); + panel.GetText("Superdashing").UpdateText(GetStringForBool(HeroController.instance.cState.superDashing)); + panel.GetText("Falling").UpdateText(GetStringForBool(HeroController.instance.cState.falling)); + panel.GetText("Hardland").UpdateText(GetStringForBool(HeroController.instance.cState.willHardLand)); + panel.GetText("Swimming").UpdateText(GetStringForBool(HeroController.instance.cState.swimming)); + panel.GetText("Recoiling").UpdateText(GetStringForBool(HeroController.instance.cState.recoiling)); + + panel.GetText("Wall lock").UpdateText(GetStringForBool(HeroController.instance.wallLocked)); + panel.GetText("Wall jumping").UpdateText(GetStringForBool(HeroController.instance.cState.wallJumping)); + panel.GetText("Wall touching").UpdateText(GetStringForBool(HeroController.instance.cState.touchingWall)); + panel.GetText("Wall sliding").UpdateText(GetStringForBool(HeroController.instance.cState.wallSliding)); + panel.GetText("Wall left").UpdateText(GetStringForBool(HeroController.instance.touchingWallL)); + panel.GetText("Wall right").UpdateText(GetStringForBool(HeroController.instance.touchingWallR)); + + panel.GetText("Attacking").UpdateText(GetStringForBool(HeroController.instance.cState.attacking)); + panel.GetText("canCast").UpdateText(GetStringForBool(HeroController.instance.CanCast())); + panel.GetText("canSuperdash").UpdateText(GetStringForBool(HeroController.instance.CanSuperDash())); + panel.GetText("canQuickmap").UpdateText(GetStringForBool(HeroController.instance.CanQuickMap())); + panel.GetText("canInventory").UpdateText(GetStringForBool(HeroController.instance.CanOpenInventory())); + panel.GetText("canWarp").UpdateText(GetStringForBool(DebugMod.RefDreamNail.FsmVariables.GetFsmBool("Dream Warp Allowed").Value)); + panel.GetText("canDGate").UpdateText(GetStringForBool(DebugMod.RefDreamNail.FsmVariables.GetFsmBool("Can Dream Gate").Value)); + panel.GetText("gateAllow").UpdateText(GetStringForBool(DebugMod.RefDreamNail.FsmVariables.GetFsmBool("Dream Gate Allowed").Value)); + + int time1 = Mathf.FloorToInt(Time.realtimeSinceStartup / 60f); + int time2 = Mathf.FloorToInt(Time.realtimeSinceStartup - (float)(time1 * 60)); + + panel.GetText("Right1").UpdateText(string.Format("{0:00}:{1:00}", time1, time2) + "\n" + DebugMod.GetLoadTime() + "s\n" + (Vector2)DebugMod.RefKnight.transform.position + "\n" + string.Format("L: {0} R: {1}", DebugMod.IH.inputActions.left.RawValue, DebugMod.IH.inputActions.right.RawValue)); + panel.GetText("Right2").UpdateText(DebugMod.IH.inputActions.moveVector.Vector.x + ", " + DebugMod.IH.inputActions.moveVector.Vector.y + "\n" + GetStringForBool(InputManager.AnyKeyIsPressed) + "\n" + GetStringForBool(DebugMod.IH.inputActions.left.IsPressed || DebugMod.IH.inputActions.right.IsPressed) + "\n" + DebugMod.IH.inputX); + } + } + + private static string GetStringForBool(bool b) + { + return b ? "✓" : "X"; + } + } +} diff --git a/Source/Settings.cs b/Source/Settings.cs index 11bc84d..b7443c0 100644 --- a/Source/Settings.cs +++ b/Source/Settings.cs @@ -34,6 +34,18 @@ public bool InfoPanelVisible set => SetBool(value); } + public bool MinInfoPanelVisible + { + get => GetBool(true); + set => SetBool(value); + } + + public bool SaveStatePanelVisible + { + get => GetBool(true); + set => SetBool(value); + } + public bool TopMenuVisible { get => GetBool(true); @@ -45,5 +57,11 @@ public bool FirstRun get => GetBool(true); set => SetBool(value); } + + public bool NumPadForSaveStates + { + get => GetBool(true); + set => SetBool(value); + } } } From a906b9b86f519e23bb8af80e3adb3d38182fb2a6 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Mon, 18 Jan 2021 21:44:59 +0100 Subject: [PATCH 08/91] In-game testing, currently failing --- Source/BindableFunctions.cs | 28 +-- Source/DebugMod.cs | 4 + Source/DebugMod.csproj | 2 +- Source/InfoPanel.cs | 3 - Source/MinimalInfoPanel.cs | 58 ++++-- Source/{SaveStateHandler.cs => SaveState.cs} | 4 +- Source/SaveStateManager.cs | 100 +++++++--- Source/SaveStatesPanel.cs | 187 ++++--------------- 8 files changed, 183 insertions(+), 203 deletions(-) rename Source/{SaveStateHandler.cs => SaveState.cs} (98%) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index b602952..a313c16 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -10,9 +10,6 @@ public static class BindableFunctions { private static readonly FieldInfo TimeSlowed = typeof(GameManager).GetField("timeSlowed", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); private static readonly FieldInfo IgnoreUnpause = typeof(UIManager).GetField("ignoreUnpause", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); - private static SaveState tmpSaveState; - //public static string[] saveStateFiles = new string[10]; - internal static int CurrentSlot = -1; internal static readonly FieldInfo cameraGameplayScene = typeof(CameraController).GetField("isGameplayScene", BindingFlags.Instance | BindingFlags.NonPublic); @@ -162,36 +159,43 @@ public static void TimescaleUp() [BindableMethod(name = "Make Savestate", category = "Savestates")] public static void SaveState() { - tmpSaveState = new SaveState(); - tmpSaveState.SaveState(SaveStateType.Memory); + DebugMod.saveStateManagers.SaveState(SaveStateType.Memory); } [BindableMethod(name = "Load SaveState", category = "Savestates")] public static void LoadState() { - if (tmpSaveState.IsSet()) - { - tmpSaveState.LoadState(SaveStateType.Memory); - } + DebugMod.saveStateManagers.LoadState(SaveStateType.Memory); } [BindableMethod(name = "Save current to file", category = "Savestates")] public static void CurrentSaveStateToFile() { - if (tmpSaveState) { tmpSaveState.SaveState(SaveStateType.Memory); } + DebugMod.saveStateManagers.SaveState(SaveStateType.File); + } + + [BindableMethod(name = "Load file to current", category = "Savestates")] + public static void CurrentSlotToSaveMemory() + { + DebugMod.saveStateManagers.LoadState(SaveStateType.File); } [BindableMethod(name = "Make Savestate (file)", category = "Savestates")] public static void NewSaveStateToFile() { - tmpSaveState = new SaveState(); - tmpSaveState.SaveState(SaveStateType.Memory); + DebugMod.saveStateManagers.SaveState(SaveStateType.SkipOne); } [BindableMethod(name = "Load Savestate (file)", category = "Savestates")] public static void LoadFromFile() { + DebugMod.saveStateManagers.LoadState(SaveStateType.SkipOne); + } + [BindableMethod(name = "Toggle auto slot", category = "Savestates")] + public static void ToggleAutoSlot() + { + DebugMod.saveStateManagers.ToggleAutoSlot(); } #endregion diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 7f27b89..fd3c7e4 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -42,6 +42,8 @@ public class DebugMod : Mod internal static Vector3 noclipPos; internal static bool cameraFollow; + internal static SaveStateManager saveStateManagers; + internal static Dictionary bindMethods = new Dictionary(); internal static Dictionary alphaKeyDict = new Dictionary(); @@ -133,6 +135,8 @@ public override void Initialize() UIObj.AddComponent(); GameObject.DontDestroyOnLoad(UIObj); + saveStateManagers = new SaveStateManager(); + ModHooks.Instance.SavegameLoadHook += LoadCharacter; ModHooks.Instance.NewGameHook += NewCharacter; ModHooks.Instance.BeforeSceneLoadHook += OnLevelUnload; diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 64ff515..89e33cd 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -73,6 +73,7 @@ + @@ -84,7 +85,6 @@ True Resources.resx - diff --git a/Source/InfoPanel.cs b/Source/InfoPanel.cs index a5b58d9..b899f09 100644 --- a/Source/InfoPanel.cs +++ b/Source/InfoPanel.cs @@ -149,9 +149,6 @@ public static void Update() if (DebugMod.settings.InfoPanelVisible && !panel.active) { panel.SetActive(true, false); - if (DebugMod.settings.MinInfoPanelVisible) { - DebugMod.settings.MinInfoPanelVisible = false; - } } else if (!DebugMod.settings.InfoPanelVisible && panel.active) { diff --git a/Source/MinimalInfoPanel.cs b/Source/MinimalInfoPanel.cs index 2a519de..c45c314 100644 --- a/Source/MinimalInfoPanel.cs +++ b/Source/MinimalInfoPanel.cs @@ -1,5 +1,6 @@ using UnityEngine; using InControl; +using System.Collections.Generic; namespace DebugMod { @@ -25,7 +26,7 @@ public static void BuildMenu(GameObject canvas) panelCurrentSaveState = new CanvasPanel( canvas, GUIController.Instance.images["BlankBox"], - new Vector2(140f, 340f), + new Vector2(500f, 200f), Vector2.zero, new Rect( 0f, @@ -38,8 +39,7 @@ public static void BuildMenu(GameObject canvas) //Labels panel.AddText("Velocity Label", "Vel", new Vector2(10f, 10f), Vector2.zero, GUIController.Instance.arial, 15); panel.AddText("Position Label", "Hero Pos", new Vector2(70f, 10f), Vector2.zero, GUIController.Instance.arial); - panel.AddText("Move Label", "Move (Raw)", new Vector2(130f, 10f), Vector2.zero, GUIController.Instance.arial); - + panel.AddText("MP Label", "MP", new Vector2(10f, 30f), Vector2.zero, GUIController.Instance.arial, 15); panel.AddText("Nail Damage Label", "Naildmg", new Vector2(70f, 30f), Vector2.zero, GUIController.Instance.arial, 15); panel.AddText("canSuperdash Label", "CanCdash", new Vector2(130f, 30f), Vector2.zero, GUIController.Instance.arial, 15); @@ -55,8 +55,7 @@ public static void BuildMenu(GameObject canvas) //Values panel.AddText("Vel", "", new Vector2(40f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); panel.AddText("Hero Pos", "", new Vector2(120f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Move (Raw)", "", new Vector2(200f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); - + panel.AddText("MP", "", new Vector2(50f, 50f), Vector2.zero, GUIController.Instance.trajanNormal); panel.AddText("Naildmg", "", new Vector2(50f, 30f), Vector2.zero, GUIController.Instance.trajanNormal); panel.AddText("CanCdash", "", new Vector2(440f, 30f), Vector2.zero, GUIController.Instance.trajanNormal); @@ -66,6 +65,8 @@ public static void BuildMenu(GameObject canvas) panel.AddText("Scene Name", "", new Vector2(50f, 70f), Vector2.zero, GUIController.Instance.trajanNormal); panel.AddText("Current", "", new Vector2(50f, 90f), Vector2.zero, GUIController.Instance.trajanNormal); + + panelCurrentSaveState.AddText("Current", "", new Vector2(40f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); // Current SaveState might work better as a panel? panel.FixRenderOrder(); @@ -75,7 +76,7 @@ public static void Update() { - if (panel == null || panelCurrentSaveState == null) + if (panel == null /*|| panelCurrentSaveState == null*/) { return; } @@ -86,20 +87,35 @@ public static void Update() { panel.SetActive(false, true); } + if (panelCurrentSaveState.active) + { + panelCurrentSaveState.SetActive(false, true); + } return; } // Not intended min/full info panel logic, but should show the two panels one at a time - if (DebugMod.settings.MinInfoPanelVisible && !panel.active) + if (DebugMod.settings.MinInfoPanelVisible) { - panel.SetActive(true, false); + if (!panel.active) + panel.SetActive(true, false); if (DebugMod.settings.InfoPanelVisible) { DebugMod.settings.InfoPanelVisible = false; } + if (SaveStateManager.HasFiles() && !panelCurrentSaveState.active) + { + panelCurrentSaveState.SetActive(true, false); + } + else + { + panelCurrentSaveState.SetActive(false, true); + } } else if (!DebugMod.settings.MinInfoPanelVisible && panel.active) { panel.SetActive(false, true); + if (panelCurrentSaveState.active) + panelCurrentSaveState.SetActive(false, true); } if (panel.active) @@ -107,8 +123,7 @@ public static void Update() PlayerData.instance.CountGameCompletion(); panel.GetText("Vel").UpdateText(HeroController.instance.current_velocity.ToString()); - panel.GetText("Hero Pos").UpdateText(DebugMod.RefKnight.transform.position.ToString()); - panel.GetText("Move (Raw)").UpdateText(string.Format("L: {0} R: {1}", DebugMod.IH.inputActions.left.RawValue, DebugMod.IH.inputActions.right.RawValue)); + panel.GetText("Pos").UpdateText(DebugMod.RefKnight.transform.position.ToString()); panel.GetText("NailDmg").UpdateText(DebugMod.RefKnightSlash.FsmVariables.GetFsmInt("damageDealt").Value + " (Flat " + PlayerData.instance.nailDamage + ", x" + DebugMod.RefKnightSlash.FsmVariables.GetFsmFloat("Multiplier").Value + ")"); @@ -119,7 +134,28 @@ public static void Update() panel.GetText("Grubs").UpdateText(PlayerData.instance.grubsCollected + " / 46"); panel.GetText("Scene Name").UpdateText(DebugMod.GetSceneName()); - panel.GetText("Current").UpdateText(); + + if (SaveStateManager.memoryState.IsSet()) + { + string[] temp = SaveStateManager.memoryState.GetSaveStateInfo(); + panel.GetText("Current").UpdateText(string.Format("{0}\n{1}", temp[2], temp[1])); + } + else + { + panel.GetText("Current").UpdateText("No savestate"); + } + + if (SaveStateManager.HasFiles()) + { + string slotSet = SaveStateManager.GetCurrentSlot().ToString(); + if (slotSet == "-1") slotSet = "unset"; + + panelCurrentSaveState.GetText("Current").UpdateText( + string.Format( + "Auto-select: {0}/n Current slot: {1}", + GetStringForBool(SaveStateManager.GetAutoSlot()), + slotSet)); + } } } diff --git a/Source/SaveStateHandler.cs b/Source/SaveState.cs similarity index 98% rename from Source/SaveStateHandler.cs rename to Source/SaveState.cs index efcf0fa..9ccdfbb 100644 --- a/Source/SaveStateHandler.cs +++ b/Source/SaveState.cs @@ -218,9 +218,7 @@ public string[] GetSaveStateInfo() { filePath, saveScene, - saveStateIdentifier, - savedPd.ToString(), - savedSd.ToString() + saveStateIdentifier }; } diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index a5691d0..2a9539b 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -30,16 +30,17 @@ internal class SaveStateManager : MonoBehaviour public static int currentStateSlot = -1; public static string path = Application.persistentDataPath + "/Savestates-1221"; - public const int maxSaveStates = 10; - public static bool saveStateHUD = false; - public static bool autoSlotSelect = true; + public const int maxSaveStates = 10; + private static bool autoSlot; + //public static bool preserveThroughStates = false; internal SaveStateManager() { try { - saveStateHUD = false; + DebugMod.settings.SaveStatePanelVisible = false; + autoSlot = false; memoryState = new SaveState(); if (Directory.Exists(SaveStateManager.path)) { @@ -64,7 +65,7 @@ public void SaveState(SaveStateType stateType) case SaveStateType.File: if (memoryState.IsSet()) { - if (autoSlotSelect) + if (autoSlot) { int i = 0; int initSlot = currentStateSlot; @@ -91,11 +92,16 @@ public void SaveState(SaveStateType stateType) } else { - // slot selection algo: - // ++current - // if (open slot[current]) states[current] = new Obj() return? - // if oob current = 0 - // loop + + DebugMod.settings.SaveStatePanelVisible = true; + while (!saveStateFiles.ContainsKey(currentStateSlot)) + { + SelectSlot(); + } + + DebugMod.settings.SaveStatePanelVisible = false; + saveStateFiles[currentStateSlot].LoadStateFromFile(); + break; } if (!memoryState.IsSet()) memoryState.SaveTempState(); @@ -103,8 +109,16 @@ public void SaveState(SaveStateType stateType) } break; case SaveStateType.SkipOne: - - break; + + DebugMod.settings.SaveStatePanelVisible = true; + while (!saveStateFiles.ContainsKey(currentStateSlot)) + { + SelectSlot(); + } + + DebugMod.settings.SaveStatePanelVisible = false; + saveStateFiles[currentStateSlot].LoadStateFromFile(); + break; default: break; } } @@ -130,16 +144,23 @@ public void LoadState(SaveStateType stateType) break; case SaveStateType.File: if (!saveStateFiles.ContainsKey(currentStateSlot)) + DebugMod.settings.SaveStatePanelVisible = true; + while (!saveStateFiles.ContainsKey(currentStateSlot)) { - // change currentStateSlot + SelectSlot(); } + + DebugMod.settings.SaveStatePanelVisible = false; saveStateFiles[currentStateSlot].PrepareFileStateToMemory(currentStateSlot); break; case SaveStateType.SkipOne: - if (!saveStateFiles.ContainsKey(currentStateSlot)) + DebugMod.settings.SaveStatePanelVisible = true; + while (!saveStateFiles.ContainsKey(currentStateSlot)) { - // change currentStateSlot + SelectSlot(); } + + DebugMod.settings.SaveStatePanelVisible = false; saveStateFiles[currentStateSlot].LoadStateFromFile(); break; default: @@ -150,11 +171,8 @@ public void LoadState(SaveStateType stateType) #endregion #region helper functionality - private IEnumerator SelectSlot() + private void SelectSlot() { - saveStateHUD = false; - yield return null; - foreach (KeyValuePair entry in DebugMod.alphaKeyDict) { if (Input.GetKeyDown(entry.Key)) @@ -165,17 +183,51 @@ private IEnumerator SelectSlot() currentStateSlot = keyInt; } } - } - // ui hud to select slot - saveStateHUD = false; - yield return null; } public void ToggleAutoSlot() { - autoSlotSelect = !autoSlotSelect; + autoSlot = !autoSlot; + } + + public static bool GetAutoSlot() + { + return autoSlot; + } + + public static int GetCurrentSlot() + { + return currentStateSlot; + } + + public string[] GetCurrentMemoryState() + { + if (memoryState.IsSet()) + { + return memoryState.GetSaveStateInfo(); + } + return null; + } + + public static bool HasFiles() + { + return (saveStateFiles.Count != 0); + } + + public static Dictionary GetSaveStatesInfo() + { + Dictionary returnData = new Dictionary(); + foreach (KeyValuePair stateData in saveStateFiles) + { + if (stateData.Value.IsSet()) + { + returnData.Add(stateData.Key, stateData.Value.GetSaveStateInfo()); + } + } + return returnData; } + #endregion } } diff --git a/Source/SaveStatesPanel.cs b/Source/SaveStatesPanel.cs index 36c8419..a1fd42c 100644 --- a/Source/SaveStatesPanel.cs +++ b/Source/SaveStatesPanel.cs @@ -1,5 +1,6 @@ using UnityEngine; using InControl; +using System.Collections.Generic; namespace DebugMod { @@ -23,90 +24,29 @@ public static void BuildMenu(GameObject canvas) ); //Labels - panel.AddText("Hero State Label", "Hero State", new Vector2(10f, 20f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Velocity Label", "Velocity", new Vector2(10f, 40f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Nail Damage Label", "Naildmg", new Vector2(10f, 60f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("HP Label", "HP", new Vector2(10f, 80f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("MP Label", "MP", new Vector2(10f, 100f), Vector2.zero, GUIController.Instance.arial, 15); - - - panel.AddText("Grubs Label", "Grubs", new Vector2(10f, 198f), Vector2.zero, GUIController.Instance.arial, 15); - - - panel.AddText("Scene Name Label", "Scene Name", new Vector2(10f, 454), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Transition Label", "Transition", new Vector2(10f, 474f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Trans State Label", "Trans State", new Vector2(10f, 494f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("is Gameplay Label", "Is Gameplay", new Vector2(10f, 514f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Game State Label", "Game State", new Vector2(10f, 534f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("UI State Label", "UI State", new Vector2(10f, 554f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Hero Paused Label", "Hero Paused", new Vector2(10f, 574f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Camera Mode Label", "Camera Mode", new Vector2(10f, 594f), Vector2.zero, GUIController.Instance.arial, 15); - - panel.AddText("Accept Input Label", "Accept Input", new Vector2(300f, 30f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Slot0", "0", new Vector2(10f, 20f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Slot1", "1", new Vector2(10f, 40f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Slot2", "2", new Vector2(10f, 60f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Slot3", "3", new Vector2(10f, 80f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Slot4", "4", new Vector2(10f, 100f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Slot5", "5", new Vector2(10f, 120f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Slot6", "6", new Vector2(10f, 140f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Slot7", "7", new Vector2(10f, 160f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Slot8", "8", new Vector2(10f, 180f), Vector2.zero, GUIController.Instance.arial, 15); + panel.AddText("Slot9", "9", new Vector2(10f, 200f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Falling Label", "Falling", new Vector2(300f, 180f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Hardland Label", "Hardland", new Vector2(300f, 200f), Vector2.zero, GUIController.Instance.arial, 15); - - panel.AddText("Wall lock Label", "Wall lock", new Vector2(300f, 290f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Wall jumping Label", "Wall jumping", new Vector2(300f, 310f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Wall touching Label", "Wall touching", new Vector2(300f, 330f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Wall sliding Label", "Wall sliding", new Vector2(300f, 350f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Wall left Label", "Wall left", new Vector2(300f, 370f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Wall right Label", "Wall right", new Vector2(300f, 390f), Vector2.zero, GUIController.Instance.arial, 15); - - panel.AddText("Attacking Label", "Attacking", new Vector2(300f, 440f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("canCast Label", "canCast", new Vector2(300f, 460f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("canSuperdash Label", "canSuperdash", new Vector2(300f, 480f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("canQuickmap Label", "canQuickmap", new Vector2(300f, 500f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("canInventory Label", "canInventory", new Vector2(300f, 520f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("canWarp Label", "canWarp", new Vector2(300f, 540f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("canDGate Label", "canDGate", new Vector2(300f, 560f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("gateAllow Label", "gateAllow", new Vector2(300f, 580f), Vector2.zero, GUIController.Instance.arial, 15); - //Values - panel.AddText("Hero State", "", new Vector2(150f, 20f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Velocity", "", new Vector2(150f, 40f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Nail Damage", "", new Vector2(150f, 60f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("HP", "", new Vector2(150f, 80f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("MP", "", new Vector2(150f, 100f), Vector2.zero, GUIController.Instance.trajanNormal); - - panel.AddText("Completion", "", new Vector2(150f, 178f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Grubs", "", new Vector2(150f, 198f), Vector2.zero, GUIController.Instance.trajanNormal); - - panel.AddText("Scene Name", "", new Vector2(150f, 454), Vector2.zero, GUIController.Instance.trajanNormal); - - panel.AddText("Dashing", "", new Vector2(440f, 120f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Jumping", "", new Vector2(440f, 140f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Superdashing", "", new Vector2(440f, 160f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Falling", "", new Vector2(440f, 180f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Hardland", "", new Vector2(440f, 200f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Swimming", "", new Vector2(440f, 220f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Recoiling", "", new Vector2(440f, 240f), Vector2.zero, GUIController.Instance.trajanNormal); - - panel.AddText("Wall lock", "", new Vector2(440f, 290f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Wall jumping", "", new Vector2(440f, 310f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Wall touching", "", new Vector2(440f, 330f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Wall sliding", "", new Vector2(440f, 350f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Wall left", "", new Vector2(440f, 370f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Wall right", "", new Vector2(440f, 390f), Vector2.zero, GUIController.Instance.trajanNormal); - - panel.AddText("Attacking", "", new Vector2(440f, 440f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("canCast", "", new Vector2(440f, 460f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("canSuperdash", "", new Vector2(440f, 480f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("canQuickmap", "", new Vector2(440f, 500f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("canInventory", "", new Vector2(440f, 520f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("canWarp", "", new Vector2(440f, 540f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("canDGate", "", new Vector2(440f, 560f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("gateAllow", "", new Vector2(440f, 580f), Vector2.zero, GUIController.Instance.trajanNormal); - - //Bottom right info - panel.AddText("Right1 Label", "Session Time\nLoad\nHero Pos\nMove Raw", new Vector2(1285, 747), Vector2.zero, GUIController.Instance.arial); - panel.AddText("Right1", "", new Vector2(1385, 747), Vector2.zero, GUIController.Instance.trajanNormal); - - panel.AddText("Right2 Label", "Move Vector\nKey Pressed\nMove Pressed\nInput X", new Vector2(1500, 747), Vector2.zero, GUIController.Instance.arial); - panel.AddText("Right2", "", new Vector2(1600, 747), Vector2.zero, GUIController.Instance.trajanNormal); - - panel.FixRenderOrder(); + panel.AddText("0", "", new Vector2(40f, 20f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("1", "", new Vector2(40f, 40f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("2", "", new Vector2(40f, 60f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("3", "", new Vector2(40f, 80f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("4", "", new Vector2(40f, 100f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("5", "", new Vector2(40f, 120f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("6", "", new Vector2(40f, 140f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("7", "", new Vector2(40f, 160f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("8", "", new Vector2(40f, 180f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("9", "", new Vector2(40f, 200f), Vector2.zero, GUIController.Instance.trajanNormal); + } public static void Update() @@ -126,82 +66,31 @@ public static void Update() return; } - if (DebugMod.settings.InfoPanelVisible && !panel.active) + if (DebugMod.settings.SaveStatePanelVisible && !panel.active) { panel.SetActive(true, false); } - else if (!DebugMod.settings.InfoPanelVisible && panel.active) + else if (!DebugMod.settings.SaveStatePanelVisible && panel.active) { panel.SetActive(false, true); } if (panel.active) { - PlayerData.instance.CountGameCompletion(); - - panel.GetText("Hero State").UpdateText(HeroController.instance.hero_state.ToString()); - panel.GetText("Velocity").UpdateText(HeroController.instance.current_velocity.ToString()); - panel.GetText("Nail Damage").UpdateText(DebugMod.RefKnightSlash.FsmVariables.GetFsmInt("damageDealt").Value + " (Flat " + PlayerData.instance.nailDamage + ", x" + DebugMod.RefKnightSlash.FsmVariables.GetFsmFloat("Multiplier").Value + ")"); - panel.GetText("HP").UpdateText(PlayerData.instance.health + " / " + PlayerData.instance.maxHealth); - panel.GetText("MP").UpdateText((PlayerData.instance.MPCharge + PlayerData.instance.MPReserve).ToString()); - - panel.GetText("Completion").UpdateText(PlayerData.instance.completionPercentage.ToString()); - panel.GetText("Grubs").UpdateText(PlayerData.instance.grubsCollected + " / 46"); - - panel.GetText("isInvuln").UpdateText(GetStringForBool(HeroController.instance.cState.invulnerable)); - panel.GetText("Invincible").UpdateText(GetStringForBool(PlayerData.instance.isInvincible)); - panel.GetText("Invincitest").UpdateText(GetStringForBool(PlayerData.instance.invinciTest)); - panel.GetText("Damage State").UpdateText(HeroController.instance.damageMode.ToString()); - panel.GetText("Dead State").UpdateText(GetStringForBool(HeroController.instance.cState.dead)); - panel.GetText("Hazard Death").UpdateText(HeroController.instance.cState.hazardDeath.ToString()); - - panel.GetText("Scene Name").UpdateText(DebugMod.GetSceneName()); - panel.GetText("Transition").UpdateText(GetStringForBool(HeroController.instance.cState.transitioning)); - - string transState = HeroController.instance.transitionState.ToString(); - if (transState == "WAITING_TO_ENTER_LEVEL") transState = "LOADING"; - if (transState == "WAITING_TO_TRANSITION") transState = "WAITING"; - - panel.GetText("Trans State").UpdateText(transState); - panel.GetText("is Gameplay").UpdateText(GetStringForBool(DebugMod.GM.IsGameplayScene())); - panel.GetText("Game State").UpdateText(GameManager.instance.gameState.ToString()); - panel.GetText("UI State").UpdateText(UIManager.instance.uiState.ToString()); - panel.GetText("Hero Paused").UpdateText(GetStringForBool(HeroController.instance.cState.isPaused)); - panel.GetText("Camera Mode").UpdateText(DebugMod.RefCamera.mode.ToString()); - - panel.GetText("Accept Input").UpdateText(GetStringForBool(HeroController.instance.acceptingInput)); - panel.GetText("Relinquished").UpdateText(GetStringForBool(HeroController.instance.controlReqlinquished)); - panel.GetText("atBench").UpdateText(GetStringForBool(PlayerData.instance.atBench)); - - panel.GetText("Dashing").UpdateText(GetStringForBool(HeroController.instance.cState.dashing)); - panel.GetText("Jumping").UpdateText(GetStringForBool((HeroController.instance.cState.jumping || HeroController.instance.cState.doubleJumping))); - panel.GetText("Superdashing").UpdateText(GetStringForBool(HeroController.instance.cState.superDashing)); - panel.GetText("Falling").UpdateText(GetStringForBool(HeroController.instance.cState.falling)); - panel.GetText("Hardland").UpdateText(GetStringForBool(HeroController.instance.cState.willHardLand)); - panel.GetText("Swimming").UpdateText(GetStringForBool(HeroController.instance.cState.swimming)); - panel.GetText("Recoiling").UpdateText(GetStringForBool(HeroController.instance.cState.recoiling)); - - panel.GetText("Wall lock").UpdateText(GetStringForBool(HeroController.instance.wallLocked)); - panel.GetText("Wall jumping").UpdateText(GetStringForBool(HeroController.instance.cState.wallJumping)); - panel.GetText("Wall touching").UpdateText(GetStringForBool(HeroController.instance.cState.touchingWall)); - panel.GetText("Wall sliding").UpdateText(GetStringForBool(HeroController.instance.cState.wallSliding)); - panel.GetText("Wall left").UpdateText(GetStringForBool(HeroController.instance.touchingWallL)); - panel.GetText("Wall right").UpdateText(GetStringForBool(HeroController.instance.touchingWallR)); - - panel.GetText("Attacking").UpdateText(GetStringForBool(HeroController.instance.cState.attacking)); - panel.GetText("canCast").UpdateText(GetStringForBool(HeroController.instance.CanCast())); - panel.GetText("canSuperdash").UpdateText(GetStringForBool(HeroController.instance.CanSuperDash())); - panel.GetText("canQuickmap").UpdateText(GetStringForBool(HeroController.instance.CanQuickMap())); - panel.GetText("canInventory").UpdateText(GetStringForBool(HeroController.instance.CanOpenInventory())); - panel.GetText("canWarp").UpdateText(GetStringForBool(DebugMod.RefDreamNail.FsmVariables.GetFsmBool("Dream Warp Allowed").Value)); - panel.GetText("canDGate").UpdateText(GetStringForBool(DebugMod.RefDreamNail.FsmVariables.GetFsmBool("Can Dream Gate").Value)); - panel.GetText("gateAllow").UpdateText(GetStringForBool(DebugMod.RefDreamNail.FsmVariables.GetFsmBool("Dream Gate Allowed").Value)); - - int time1 = Mathf.FloorToInt(Time.realtimeSinceStartup / 60f); - int time2 = Mathf.FloorToInt(Time.realtimeSinceStartup - (float)(time1 * 60)); - - panel.GetText("Right1").UpdateText(string.Format("{0:00}:{1:00}", time1, time2) + "\n" + DebugMod.GetLoadTime() + "s\n" + (Vector2)DebugMod.RefKnight.transform.position + "\n" + string.Format("L: {0} R: {1}", DebugMod.IH.inputActions.left.RawValue, DebugMod.IH.inputActions.right.RawValue)); - panel.GetText("Right2").UpdateText(DebugMod.IH.inputActions.moveVector.Vector.x + ", " + DebugMod.IH.inputActions.moveVector.Vector.y + "\n" + GetStringForBool(InputManager.AnyKeyIsPressed) + "\n" + GetStringForBool(DebugMod.IH.inputActions.left.IsPressed || DebugMod.IH.inputActions.right.IsPressed) + "\n" + DebugMod.IH.inputX); + panel.GetText("0").UpdateText("Open"); + panel.GetText("1").UpdateText("Open"); + panel.GetText("2").UpdateText("Open"); + panel.GetText("4").UpdateText("Open"); + panel.GetText("5").UpdateText("Open"); + panel.GetText("6").UpdateText("Open"); + panel.GetText("7").UpdateText("Open"); + panel.GetText("8").UpdateText("Open"); + panel.GetText("9").UpdateText("Open"); + + foreach (KeyValuePair entry in SaveStateManager.GetSaveStatesInfo()) + { + panel.GetText(entry.Key.ToString()).UpdateText(string.Format("{0}\n{1}", entry.Value[2], entry.Value[1])); + } } } From 6b46c24e767f1e03ba8abbd014e67132133546a1 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Tue, 19 Jan 2021 00:04:44 +0100 Subject: [PATCH 09/91] TODO: Error handling :woozy: --- Source/BindableFunctions.cs | 18 ++--- Source/DebugMod.cs | 14 ++-- Source/GUIController.cs | 6 +- Source/MinimalInfoPanel.cs | 136 +++++++++++++++++------------------- Source/SaveStateManager.cs | 2 +- Source/SaveStatesPanel.cs | 20 +++--- 6 files changed, 96 insertions(+), 100 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index a313c16..60ab75b 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -159,43 +159,43 @@ public static void TimescaleUp() [BindableMethod(name = "Make Savestate", category = "Savestates")] public static void SaveState() { - DebugMod.saveStateManagers.SaveState(SaveStateType.Memory); + DebugMod.saveStateManager.SaveState(SaveStateType.Memory); } [BindableMethod(name = "Load SaveState", category = "Savestates")] public static void LoadState() { - DebugMod.saveStateManagers.LoadState(SaveStateType.Memory); + DebugMod.saveStateManager.LoadState(SaveStateType.Memory); } [BindableMethod(name = "Save current to file", category = "Savestates")] public static void CurrentSaveStateToFile() { - DebugMod.saveStateManagers.SaveState(SaveStateType.File); + DebugMod.saveStateManager.SaveState(SaveStateType.File); } [BindableMethod(name = "Load file to current", category = "Savestates")] public static void CurrentSlotToSaveMemory() { - DebugMod.saveStateManagers.LoadState(SaveStateType.File); + DebugMod.saveStateManager.LoadState(SaveStateType.File); } [BindableMethod(name = "Make Savestate (file)", category = "Savestates")] public static void NewSaveStateToFile() { - DebugMod.saveStateManagers.SaveState(SaveStateType.SkipOne); + DebugMod.saveStateManager.SaveState(SaveStateType.SkipOne); } [BindableMethod(name = "Load Savestate (file)", category = "Savestates")] public static void LoadFromFile() { - DebugMod.saveStateManagers.LoadState(SaveStateType.SkipOne); + DebugMod.saveStateManager.LoadState(SaveStateType.SkipOne); } [BindableMethod(name = "Toggle auto slot", category = "Savestates")] public static void ToggleAutoSlot() { - DebugMod.saveStateManagers.ToggleAutoSlot(); + DebugMod.saveStateManager.ToggleAutoSlot(); } #endregion @@ -293,7 +293,6 @@ public static void ToggleAllPanels() bool active = !(DebugMod.settings.HelpPanelVisible || DebugMod.settings.InfoPanelVisible || DebugMod.settings.EnemiesPanelVisible || DebugMod.settings.TopMenuVisible || DebugMod.settings.ConsoleVisible); DebugMod.settings.TopMenuVisible = active; - DebugMod.settings.InfoPanelVisible = active; DebugMod.settings.EnemiesPanelVisible = active; DebugMod.settings.ConsoleVisible = active; DebugMod.settings.HelpPanelVisible = active; @@ -340,10 +339,11 @@ public static void ToggleEnemyPanel() // A variant of info panel. View handled in the two InfoPanel classes // Probably some race-condition potential here :) - [BindableMethod(name = "Full/Min Info Switch", category = "Mod UI")] + [BindableMethod(name = "Alt. Info Switch", category = "Mod UI")] public static void ToggleFullInfo() { DebugMod.settings.MinInfoPanelVisible = !DebugMod.settings.MinInfoPanelVisible; + Console.AddLine("MinInfoPanelVisible (bool): " + DebugMod.settings.MinInfoPanelVisible.ToString()); } #endregion diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index fd3c7e4..af5dc96 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -42,7 +42,7 @@ public class DebugMod : Mod internal static Vector3 noclipPos; internal static bool cameraFollow; - internal static SaveStateManager saveStateManagers; + internal static SaveStateManager saveStateManager; internal static Dictionary bindMethods = new Dictionary(); internal static Dictionary alphaKeyDict = new Dictionary(); @@ -91,13 +91,13 @@ public override void Initialize() settings.binds.Add("Toggle Info", (int)KeyCode.F2); settings.binds.Add("Toggle Top Menu", (int)KeyCode.F3); settings.binds.Add("Toggle Console", (int)KeyCode.F4); - settings.binds.Add("Force Pause", (int)KeyCode.F5); - settings.binds.Add("Hazard Respawn", (int)KeyCode.F6); - settings.binds.Add("Set Respawn", (int)KeyCode.F7); + settings.binds.Add("Toggle Binds", (int)KeyCode.F5); + settings.binds.Add("Full/Min Info Switch", (int)KeyCode.F6); + //settings.binds.Add("Hazard Respawn", (int)KeyCode.F6); + //settings.binds.Add("Set Respawn", (int)KeyCode.F7); settings.binds.Add("Force Camera Follow", (int)KeyCode.F8); settings.binds.Add("Toggle Enemy Panel", (int)KeyCode.F9); settings.binds.Add("Self Damage", (int)KeyCode.F10); - settings.binds.Add("Toggle Binds", (int)KeyCode.BackQuote); settings.binds.Add("Nail Damage +4", (int)KeyCode.Equals); settings.binds.Add("Nail Damage -4", (int)KeyCode.Minus); settings.binds.Add("Increase Timescale", (int)KeyCode.KeypadPlus); @@ -135,7 +135,7 @@ public override void Initialize() UIObj.AddComponent(); GameObject.DontDestroyOnLoad(UIObj); - saveStateManagers = new SaveStateManager(); + saveStateManager = new SaveStateManager(); ModHooks.Instance.SavegameLoadHook += LoadCharacter; ModHooks.Instance.NewGameHook += NewCharacter; @@ -161,7 +161,7 @@ public override void Initialize() public override string GetVersion() { - return "1.4.0"; + return "1.3.9b"; } public override bool IsCurrent() diff --git a/Source/GUIController.cs b/Source/GUIController.cs index d1521ab..db0a7dd 100644 --- a/Source/GUIController.cs +++ b/Source/GUIController.cs @@ -112,14 +112,14 @@ private void LoadResources() public void Update() { - MinimalInfoPanel.Update(); - InfoPanel.Update(); SaveStatesPanel.Update(); TopMenu.Update(); EnemiesPanel.Update(); Console.Update(); KeyBindPanel.Update(); - + MinimalInfoPanel.Update(); + InfoPanel.Update(); + if (DebugMod.GetSceneName() != "Menu_Title") { //Handle keybinds diff --git a/Source/MinimalInfoPanel.cs b/Source/MinimalInfoPanel.cs index c45c314..4ff483a 100644 --- a/Source/MinimalInfoPanel.cs +++ b/Source/MinimalInfoPanel.cs @@ -6,12 +6,12 @@ namespace DebugMod { public static class MinimalInfoPanel { - private static CanvasPanel panel; - private static CanvasPanel panelCurrentSaveState; + private static CanvasPanel altPanel; + //private static CanvasPanel panelCurrentSaveState; public static void BuildMenu(GameObject canvas) { - panel = new CanvasPanel( + altPanel = new CanvasPanel( canvas, GUIController.Instance.images["BlankBox"], new Vector2(130f, 230f), @@ -23,9 +23,9 @@ public static void BuildMenu(GameObject canvas) GUIController.Instance.images["BlankBox"].height ) ); + /* panelCurrentSaveState = new CanvasPanel( canvas, - GUIController.Instance.images["BlankBox"], new Vector2(500f, 200f), Vector2.zero, new Rect( @@ -35,127 +35,123 @@ public static void BuildMenu(GameObject canvas) GUIController.Instance.images["BlankBox"].height ) ); + */ //Labels - panel.AddText("Velocity Label", "Vel", new Vector2(10f, 10f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Position Label", "Hero Pos", new Vector2(70f, 10f), Vector2.zero, GUIController.Instance.arial); + altPanel.AddText("Alt vel Label", "Vel", new Vector2(10f, 10f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt pos Label", "Pos", new Vector2(80f, 10f), Vector2.zero, GUIController.Instance.arial); - panel.AddText("MP Label", "MP", new Vector2(10f, 30f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Nail Damage Label", "Naildmg", new Vector2(70f, 30f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("canSuperdash Label", "CanCdash", new Vector2(130f, 30f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt MP Label", "MP", new Vector2(10f, 30f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt Nail Damage Label", "NailDmg", new Vector2(70f, 30f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt canSuperdash Label", "CanCdash", new Vector2(130f, 30f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Completion Label", "Completion", new Vector2(10f, 50f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Grubs Label", "Grubs", new Vector2(90f, 50f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt Completion Label", "Completion", new Vector2(10f, 50f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt Grubs Label", "Grubs", new Vector2(90f, 50f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Scene Name Label", "Scene Name", new Vector2(10f, 70f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Current Save State Lable", "Current", new Vector2(10f, 90f), Vector2.zero, GUIController.Instance.arial, 15); - - panelCurrentSaveState.AddText("Current Save State Lable", "Current", new Vector2(10f, 10f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt Scene Name Label", "Scene Name", new Vector2(10f, 70f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt Current Save State Lable", "Current SaveState", new Vector2(10f, 90f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt SaveState AutoSlot", "Autoslot", new Vector2(10f, 110f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt SaveState CurrentSlot", "Current slot", new Vector2(70f, 110f), Vector2.zero, GUIController.Instance.arial, 15); + //panelCurrentSaveState.AddText("Current Save State Lable", "Current", new Vector2(10f, 10f), Vector2.zero, GUIController.Instance.arial, 15); //Values - panel.AddText("Vel", "", new Vector2(40f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Hero Pos", "", new Vector2(120f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Vel", "", new Vector2(40f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Pos", "", new Vector2(120f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("MP", "", new Vector2(50f, 50f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Naildmg", "", new Vector2(50f, 30f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("CanCdash", "", new Vector2(440f, 30f), Vector2.zero, GUIController.Instance.trajanNormal); - - panel.AddText("Completion", "", new Vector2(60f, 50f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Grubs", "", new Vector2(120f, 50f), Vector2.zero, GUIController.Instance.trajanNormal); - - panel.AddText("Scene Name", "", new Vector2(50f, 70f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Current", "", new Vector2(50f, 90f), Vector2.zero, GUIController.Instance.trajanNormal); - - panelCurrentSaveState.AddText("Current", "", new Vector2(40f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("MP", "", new Vector2(50f, 30f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("NailDmg", "", new Vector2(100f, 30f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("CanCdash", "", new Vector2(160f, 30f), Vector2.zero, GUIController.Instance.trajanNormal); + + altPanel.AddText("Completion", "", new Vector2(60f, 50f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Grubs", "", new Vector2(120f, 50f), Vector2.zero, GUIController.Instance.trajanNormal); + + altPanel.AddText("Scene Name", "", new Vector2(50f, 70f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Current SaveState", "", new Vector2(50f, 90f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Autoslot", "", new Vector2(40f, 110f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Current slot", "", new Vector2(120f, 110f), Vector2.zero, GUIController.Instance.trajanNormal); + //panelCurrentSaveState.AddText("Current", "", new Vector2(40f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); // Current SaveState might work better as a panel? - panel.FixRenderOrder(); + altPanel.FixRenderOrder(); } public static void Update() { - - - if (panel == null /*|| panelCurrentSaveState == null*/) + + if (altPanel == null) { return; } if (DebugMod.GM.IsNonGameplayScene()) { - if (panel.active) + if (altPanel.active) { - panel.SetActive(false, true); - } - if (panelCurrentSaveState.active) - { - panelCurrentSaveState.SetActive(false, true); + altPanel.SetActive(false, true); } return; } // Not intended min/full info panel logic, but should show the two panels one at a time - if (DebugMod.settings.MinInfoPanelVisible) + if (DebugMod.settings.MinInfoPanelVisible && !altPanel.active) { - if (!panel.active) - panel.SetActive(true, false); - if (DebugMod.settings.InfoPanelVisible) { - DebugMod.settings.InfoPanelVisible = false; - } - if (SaveStateManager.HasFiles() && !panelCurrentSaveState.active) - { - panelCurrentSaveState.SetActive(true, false); - } - else - { - panelCurrentSaveState.SetActive(false, true); - } + altPanel.SetActive(true, false); } - else if (!DebugMod.settings.MinInfoPanelVisible && panel.active) + else if (!DebugMod.settings.MinInfoPanelVisible && altPanel.active) { - panel.SetActive(false, true); - if (panelCurrentSaveState.active) - panelCurrentSaveState.SetActive(false, true); + altPanel.SetActive(false, true); } - if (panel.active) + if (altPanel.active) { PlayerData.instance.CountGameCompletion(); - panel.GetText("Vel").UpdateText(HeroController.instance.current_velocity.ToString()); - panel.GetText("Pos").UpdateText(DebugMod.RefKnight.transform.position.ToString()); + altPanel.GetText("Vel").UpdateText(HeroController.instance.current_velocity.ToString()); + altPanel.GetText("Pos").UpdateText(DebugMod.RefKnight.transform.position.ToString()); - panel.GetText("NailDmg").UpdateText(DebugMod.RefKnightSlash.FsmVariables.GetFsmInt("damageDealt").Value + " (Flat " + PlayerData.instance.nailDamage + ", x" + DebugMod.RefKnightSlash.FsmVariables.GetFsmFloat("Multiplier").Value + ")"); + altPanel.GetText("MP").UpdateText((PlayerData.instance.MPCharge + PlayerData.instance.MPReserve).ToString()); + altPanel.GetText("NailDmg").UpdateText(DebugMod.RefKnightSlash.FsmVariables.GetFsmInt("damageDealt").Value + " (Flat " + PlayerData.instance.nailDamage + ", x" + DebugMod.RefKnightSlash.FsmVariables.GetFsmFloat("Multiplier").Value + ")"); + altPanel.GetText("CanCdash").UpdateText(GetStringForBool(HeroController.instance.CanSuperDash())); - panel.GetText("MP").UpdateText((PlayerData.instance.MPCharge + PlayerData.instance.MPReserve).ToString()); - panel.GetText("CanCdash").UpdateText(GetStringForBool(HeroController.instance.CanSuperDash())); + altPanel.GetText("Completion").UpdateText(PlayerData.instance.completionPercentage.ToString()); + altPanel.GetText("Grubs").UpdateText(PlayerData.instance.grubsCollected + " / 46"); - panel.GetText("Completion").UpdateText(PlayerData.instance.completionPercentage.ToString()); - panel.GetText("Grubs").UpdateText(PlayerData.instance.grubsCollected + " / 46"); - - panel.GetText("Scene Name").UpdateText(DebugMod.GetSceneName()); + altPanel.GetText("Scene Name").UpdateText(DebugMod.GetSceneName()); if (SaveStateManager.memoryState.IsSet()) { string[] temp = SaveStateManager.memoryState.GetSaveStateInfo(); - panel.GetText("Current").UpdateText(string.Format("{0}\n{1}", temp[2], temp[1])); + altPanel.GetText("Current SaveState").UpdateText(string.Format("{0}\n{1}", temp[2], temp[1])); } else { - panel.GetText("Current").UpdateText("No savestate"); + altPanel.GetText("Current SaveState").UpdateText("No savestate"); + } + + string slotSet = SaveStateManager.GetCurrentSlot().ToString(); + if (slotSet == "-1") + { + slotSet = "unset"; } + altPanel.GetText("Autoslot").UpdateText(string.Format("Auto-select: {0}", + GetStringForBool(SaveStateManager.GetAutoSlot()))); + altPanel.GetText("Current slot").UpdateText(string.Format("Current slot: {0}", slotSet)); + /* if (SaveStateManager.HasFiles()) { string slotSet = SaveStateManager.GetCurrentSlot().ToString(); if (slotSet == "-1") slotSet = "unset"; - panelCurrentSaveState.GetText("Current").UpdateText( + panel.GetText("Current").UpdateText( string.Format( "Auto-select: {0}/n Current slot: {1}", GetStringForBool(SaveStateManager.GetAutoSlot()), - slotSet)); + slotSet + ) + ); } + */ } } diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index 2a9539b..2f2a64f 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -42,7 +42,7 @@ internal SaveStateManager() DebugMod.settings.SaveStatePanelVisible = false; autoSlot = false; memoryState = new SaveState(); - if (Directory.Exists(SaveStateManager.path)) + if (!Directory.Exists(SaveStateManager.path)) { Directory.CreateDirectory(path); } diff --git a/Source/SaveStatesPanel.cs b/Source/SaveStatesPanel.cs index a1fd42c..fdac231 100644 --- a/Source/SaveStatesPanel.cs +++ b/Source/SaveStatesPanel.cs @@ -36,16 +36,16 @@ public static void BuildMenu(GameObject canvas) panel.AddText("Slot9", "9", new Vector2(10f, 200f), Vector2.zero, GUIController.Instance.arial, 15); //Values - panel.AddText("0", "", new Vector2(40f, 20f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("1", "", new Vector2(40f, 40f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("2", "", new Vector2(40f, 60f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("3", "", new Vector2(40f, 80f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("4", "", new Vector2(40f, 100f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("5", "", new Vector2(40f, 120f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("6", "", new Vector2(40f, 140f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("7", "", new Vector2(40f, 160f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("8", "", new Vector2(40f, 180f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("9", "", new Vector2(40f, 200f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("0", "", new Vector2(50f, 20f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("1", "", new Vector2(50f, 40f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("2", "", new Vector2(50f, 60f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("3", "", new Vector2(50f, 80f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("4", "", new Vector2(50f, 100f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("5", "", new Vector2(50f, 120f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("6", "", new Vector2(50f, 140f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("7", "", new Vector2(50f, 160f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("8", "", new Vector2(50f, 180f), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("9", "", new Vector2(50f, 200f), Vector2.zero, GUIController.Instance.trajanNormal); } From 0dcafbfd95af3c70079a4ce9421edee0df1034fb Mon Sep 17 00:00:00 2001 From: cerpintext Date: Wed, 20 Jan 2021 19:59:54 +0100 Subject: [PATCH 10/91] qol functionality. FileSaveStates not yet working --- Source/BindableFunctions.cs | 78 +++++++++++++++-- Source/DebugMod.cs | 2 +- Source/GUIController.cs | 18 ++++ Source/MinimalInfoPanel.cs | 68 ++++++--------- Source/SaveState.cs | 38 +++++--- Source/SaveStateManager.cs | 169 +++++++++++++++++++++++++----------- Source/SaveStatesPanel.cs | 78 ++++++++--------- 7 files changed, 297 insertions(+), 154 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 60ab75b..25b46dc 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Reflection; +using System.IO; using UnityEngine; using GlobalEnums; @@ -152,6 +153,30 @@ public static void TimescaleUp() } } + [BindableMethod(name = "SceneData to file", category = "Misc")] + public static void SceneDataToFile() + { + File.WriteAllText(string.Concat( + new object[] { Application.persistentDataPath, "SceneData.json" }), + JsonUtility.ToJson( + SceneData.instance, + prettyPrint: true + ) + ); + } + + [BindableMethod(name = "PlayerData to file", category = "Misc")] + public static void PlayerDataToFile() + { + + File.WriteAllText(string.Concat( + new object[] { Application.persistentDataPath, "PlayerData.json" }), + JsonUtility.ToJson( + PlayerData.instance, + prettyPrint: true + ) + ); + } #endregion #region SaveStates @@ -290,12 +315,31 @@ public static void HideHero() [BindableMethod(name = "Toggle All UI", category = "Mod UI")] public static void ToggleAllPanels() { - bool active = !(DebugMod.settings.HelpPanelVisible || DebugMod.settings.InfoPanelVisible || DebugMod.settings.EnemiesPanelVisible || DebugMod.settings.TopMenuVisible || DebugMod.settings.ConsoleVisible); + bool active = !( + DebugMod.settings.HelpPanelVisible || + DebugMod.settings.InfoPanelVisible || + DebugMod.settings.EnemiesPanelVisible || + DebugMod.settings.TopMenuVisible || + DebugMod.settings.ConsoleVisible || + DebugMod.settings.MinInfoPanelVisible || + DebugMod.settings.SaveStatePanelVisible + ); + if (MinimalInfoPanel.minInfo) + { + DebugMod.settings.InfoPanelVisible = false; + DebugMod.settings.MinInfoPanelVisible = active; + } + else + { + DebugMod.settings.InfoPanelVisible = active; + DebugMod.settings.MinInfoPanelVisible = false; + } DebugMod.settings.TopMenuVisible = active; DebugMod.settings.EnemiesPanelVisible = active; DebugMod.settings.ConsoleVisible = active; DebugMod.settings.HelpPanelVisible = active; + DebugMod.settings.SaveStatePanelVisible = active; if (DebugMod.settings.EnemiesPanelVisible) { @@ -312,7 +356,16 @@ public static void ToggleHelpPanel() [BindableMethod(name = "Toggle Info", category = "Mod UI")] public static void ToggleInfoPanel() { - DebugMod.settings.InfoPanelVisible = !DebugMod.settings.InfoPanelVisible; + if (MinimalInfoPanel.minInfo) + { + DebugMod.settings.InfoPanelVisible = false; + DebugMod.settings.MinInfoPanelVisible = !DebugMod.settings.MinInfoPanelVisible; + } + else + { + DebugMod.settings.InfoPanelVisible = !DebugMod.settings.InfoPanelVisible; + DebugMod.settings.MinInfoPanelVisible = false; + } } [BindableMethod(name = "Toggle Top Menu", category = "Mod UI")] @@ -342,8 +395,13 @@ public static void ToggleEnemyPanel() [BindableMethod(name = "Alt. Info Switch", category = "Mod UI")] public static void ToggleFullInfo() { - DebugMod.settings.MinInfoPanelVisible = !DebugMod.settings.MinInfoPanelVisible; - Console.AddLine("MinInfoPanelVisible (bool): " + DebugMod.settings.MinInfoPanelVisible.ToString()); + MinimalInfoPanel.minInfo = !MinimalInfoPanel.minInfo; + } + + [BindableMethod(name = "Toggle SaveState Panel", category = "Mod UI")] + public static void ToggleSaveStatesPanel() + { + DebugMod.settings.SaveStatePanelVisible = !DebugMod.settings.SaveStatePanelVisible; } #endregion @@ -525,11 +583,13 @@ public static void ToggleNoclip() public static void KillSelf() { if (DebugMod.GM.isPaused) UIManager.instance.TogglePauseGame(); - HeroController.instance.TakeHealth(PlayerData.instance.health); - //HeroController.instance.heroDeathPrefab.SetActive(true); - //DebugMod.GM.ReadyForRespawn(); - //GameCameras.instance.hudCanvas.gameObject.SetActive(false); - //GameCameras.instance.hudCanvas.gameObject.SetActive(true); + HeroController.instance.TakeHealth(PlayerData.instance.maxHealth); + + + HeroController.instance.heroDeathPrefab.SetActive(true); + DebugMod.GM.ReadyForRespawn(); + GameCameras.instance.hudCanvas.gameObject.SetActive(false); + GameCameras.instance.hudCanvas.gameObject.SetActive(true); } #endregion diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index af5dc96..6e2e7bc 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -161,7 +161,7 @@ public override void Initialize() public override string GetVersion() { - return "1.3.9b"; + return "1.3.9d"; } public override bool IsCurrent() diff --git a/Source/GUIController.cs b/Source/GUIController.cs index db0a7dd..b7b0a4b 100644 --- a/Source/GUIController.cs +++ b/Source/GUIController.cs @@ -16,6 +16,7 @@ public class GUIController : MonoBehaviour public Dictionary images = new Dictionary(); public Vector3 hazardLocation; public string respawnSceneWatch; + public static bool didInput; private GameObject canvas; private static GUIController _instance; @@ -173,10 +174,27 @@ public void Update() DebugMod.settings.binds.Remove(bind.Key); } } + + if (SaveStateManager.selectSlot && DebugMod.settings.SaveStatePanelVisible) + { + foreach (KeyValuePair entry in DebugMod.alphaKeyDict) + { + if (Input.GetKeyDown(entry.Key)) + { + if (DebugMod.alphaKeyDict.TryGetValue(entry.Key, out int keyInt)) + { + // keyInt should be between 0-9 + SaveStateManager.currentStateSlot = keyInt; + didInput = true; + } + } + } + } if (DebugMod.infiniteSoul && PlayerData.instance.MPCharge < PlayerData.instance.maxMP && PlayerData.instance.health > 0 && !HeroController.instance.cState.dead && GameManager.instance.IsGameplayScene()) { PlayerData.instance.MPCharge = PlayerData.instance.maxMP; + PlayerData.instance.MPReserve = PlayerData.instance.MPReserveMax; } if (DebugMod.playerInvincible && PlayerData.instance != null) diff --git a/Source/MinimalInfoPanel.cs b/Source/MinimalInfoPanel.cs index 4ff483a..4e20476 100644 --- a/Source/MinimalInfoPanel.cs +++ b/Source/MinimalInfoPanel.cs @@ -6,6 +6,7 @@ namespace DebugMod { public static class MinimalInfoPanel { + public static bool minInfo = false; private static CanvasPanel altPanel; //private static CanvasPanel panelCurrentSaveState; @@ -23,54 +24,40 @@ public static void BuildMenu(GameObject canvas) GUIController.Instance.images["BlankBox"].height ) ); - /* - panelCurrentSaveState = new CanvasPanel( - canvas, - new Vector2(500f, 200f), - Vector2.zero, - new Rect( - 0f, - 0f, - GUIController.Instance.images["BlankBox"].width, - GUIController.Instance.images["BlankBox"].height - ) - ); - */ //Labels altPanel.AddText("Alt vel Label", "Vel", new Vector2(10f, 10f), Vector2.zero, GUIController.Instance.arial, 15); - altPanel.AddText("Alt pos Label", "Pos", new Vector2(80f, 10f), Vector2.zero, GUIController.Instance.arial); + altPanel.AddText("Alt pos Label", "Pos", new Vector2(110f, 10f), Vector2.zero, GUIController.Instance.arial, 15); altPanel.AddText("Alt MP Label", "MP", new Vector2(10f, 30f), Vector2.zero, GUIController.Instance.arial, 15); - altPanel.AddText("Alt Nail Damage Label", "NailDmg", new Vector2(70f, 30f), Vector2.zero, GUIController.Instance.arial, 15); - altPanel.AddText("Alt canSuperdash Label", "CanCdash", new Vector2(130f, 30f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt canSuperdash Label", "CanCdash", new Vector2(100f, 30f), Vector2.zero, GUIController.Instance.arial, 15); - altPanel.AddText("Alt Completion Label", "Completion", new Vector2(10f, 50f), Vector2.zero, GUIController.Instance.arial, 15); - altPanel.AddText("Alt Grubs Label", "Grubs", new Vector2(90f, 50f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt Nail Damage Label", "NailDmg", new Vector2(10f, 50f), Vector2.zero, GUIController.Instance.arial, 15); + + altPanel.AddText("Alt Completion Label", "Completion", new Vector2(10f, 70f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt Grubs Label", "Grubs", new Vector2(140f, 70f), Vector2.zero, GUIController.Instance.arial, 15); - altPanel.AddText("Alt Scene Name Label", "Scene Name", new Vector2(10f, 70f), Vector2.zero, GUIController.Instance.arial, 15); - altPanel.AddText("Alt Current Save State Lable", "Current SaveState", new Vector2(10f, 90f), Vector2.zero, GUIController.Instance.arial, 15); - altPanel.AddText("Alt SaveState AutoSlot", "Autoslot", new Vector2(10f, 110f), Vector2.zero, GUIController.Instance.arial, 15); - altPanel.AddText("Alt SaveState CurrentSlot", "Current slot", new Vector2(70f, 110f), Vector2.zero, GUIController.Instance.arial, 15); - //panelCurrentSaveState.AddText("Current Save State Lable", "Current", new Vector2(10f, 10f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt Scene Name Label", "Scene Name", new Vector2(10f, 90f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt Current Save State Lable", "Current SaveState", new Vector2(10f, 110f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt SaveState AutoSlot", "Autoslot", new Vector2(10f, 130f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt SaveState CurrentSlot", "Current slot", new Vector2(110f, 130f), Vector2.zero, GUIController.Instance.arial, 15); //Values - altPanel.AddText("Vel", "", new Vector2(40f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); - altPanel.AddText("Pos", "", new Vector2(120f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Vel", "", new Vector2(40f, 14f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Pos", "", new Vector2(140f, 14f), Vector2.zero, GUIController.Instance.trajanNormal); - altPanel.AddText("MP", "", new Vector2(50f, 30f), Vector2.zero, GUIController.Instance.trajanNormal); - altPanel.AddText("NailDmg", "", new Vector2(100f, 30f), Vector2.zero, GUIController.Instance.trajanNormal); - altPanel.AddText("CanCdash", "", new Vector2(160f, 30f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("MP", "", new Vector2(40f, 34f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("CanCdash", "", new Vector2(190f, 34f), Vector2.zero, GUIController.Instance.trajanNormal); + + altPanel.AddText("NailDmg", "", new Vector2(100f, 54f), Vector2.zero, GUIController.Instance.trajanNormal); - altPanel.AddText("Completion", "", new Vector2(60f, 50f), Vector2.zero, GUIController.Instance.trajanNormal); - altPanel.AddText("Grubs", "", new Vector2(120f, 50f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Completion", "", new Vector2(95f, 74f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Grubs", "", new Vector2(195f, 74f), Vector2.zero, GUIController.Instance.trajanNormal); - altPanel.AddText("Scene Name", "", new Vector2(50f, 70f), Vector2.zero, GUIController.Instance.trajanNormal); - altPanel.AddText("Current SaveState", "", new Vector2(50f, 90f), Vector2.zero, GUIController.Instance.trajanNormal); - altPanel.AddText("Autoslot", "", new Vector2(40f, 110f), Vector2.zero, GUIController.Instance.trajanNormal); - altPanel.AddText("Current slot", "", new Vector2(120f, 110f), Vector2.zero, GUIController.Instance.trajanNormal); - //panelCurrentSaveState.AddText("Current", "", new Vector2(40f, 10f), Vector2.zero, GUIController.Instance.trajanNormal); - // Current SaveState might work better as a panel? + altPanel.AddText("Scene Name", "", new Vector2(140f, 94f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Current SaveState", "", new Vector2(140f, 114f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Autoslot", "", new Vector2(80f, 134f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Current slot", "", new Vector2(200f, 134f), Vector2.zero, GUIController.Instance.trajanNormal); altPanel.FixRenderOrder(); } @@ -113,7 +100,7 @@ public static void Update() altPanel.GetText("NailDmg").UpdateText(DebugMod.RefKnightSlash.FsmVariables.GetFsmInt("damageDealt").Value + " (Flat " + PlayerData.instance.nailDamage + ", x" + DebugMod.RefKnightSlash.FsmVariables.GetFsmFloat("Multiplier").Value + ")"); altPanel.GetText("CanCdash").UpdateText(GetStringForBool(HeroController.instance.CanSuperDash())); - altPanel.GetText("Completion").UpdateText(PlayerData.instance.completionPercentage.ToString()); + altPanel.GetText("Completion").UpdateText(PlayerData.instance.completionPercentage.ToString() + "%"); altPanel.GetText("Grubs").UpdateText(PlayerData.instance.grubsCollected + " / 46"); altPanel.GetText("Scene Name").UpdateText(DebugMod.GetSceneName()); @@ -121,7 +108,8 @@ public static void Update() if (SaveStateManager.memoryState.IsSet()) { string[] temp = SaveStateManager.memoryState.GetSaveStateInfo(); - altPanel.GetText("Current SaveState").UpdateText(string.Format("{0}\n{1}", temp[2], temp[1])); + //altPanel.GetText("Current SaveState").UpdateText(string.Format("{0}\n{1}", temp[2], temp[1])); + altPanel.GetText("Current SaveState").UpdateText(temp[2]); } else { @@ -134,9 +122,9 @@ public static void Update() slotSet = "unset"; } - altPanel.GetText("Autoslot").UpdateText(string.Format("Auto-select: {0}", + altPanel.GetText("Autoslot").UpdateText(string.Format("{0}", GetStringForBool(SaveStateManager.GetAutoSlot()))); - altPanel.GetText("Current slot").UpdateText(string.Format("Current slot: {0}", slotSet)); + altPanel.GetText("Current slot").UpdateText(string.Format("{0}", slotSet)); /* if (SaveStateManager.HasFiles()) { diff --git a/Source/SaveState.cs b/Source/SaveState.cs index 9ccdfbb..becee15 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -26,12 +26,7 @@ internal class SaveState : MonoBehaviour internal SaveState() { - - } - internal SaveState(SaveState saveState) - { - } private SaveState(string _scene, string _identifier, PlayerData _pd, SceneData _sd, Vector3 _pos, FieldInfo _cameraLockArea, object _paramLockArea) { @@ -57,7 +52,7 @@ public void SaveTempState() lockArea = cameraLockArea.GetValue(GameManager.instance.cameraCtrl); } - public void SaveStateToFile(SaveState paramSave, int paramSlot) + public void SaveStateToFile(int paramSlot) { try { @@ -70,12 +65,27 @@ public void SaveStateToFile(SaveState paramSave, int paramSlot) throw new Exception("No temp save state set"); } - filePath = SaveStateManager.path + paramSlot + ".json"; - File.WriteAllText(string.Concat(new object[]{filePath}), JsonUtility.ToJson(paramSave, prettyPrint: true)); + //filePath = SaveStateManager.path + paramSlot + ".json"; + + filePath = string.Concat(new object[] +{ + Application.persistentDataPath, + "/Savestates-1221/savestate", + paramSlot, + ".json" + }); + + File.WriteAllText(string.Concat( + new object[]{ filePath }), + JsonUtility.ToJson( + new SaveState ( saveStateIdentifier, saveScene, savedPd, savedSd, savePos, cameraLockArea, lockArea ), + prettyPrint: true + ) + ); } - catch (Exception ex) + catch (Exception) { - Debug.Log("SaveStateToFile(): " + ex.Message); + throw; } } #endregion @@ -90,7 +100,7 @@ public void LoadTempState() public void LoadStateFromFile() { PrepareFileStateToMemory(SaveStateManager.currentStateSlot); - HeroController.instance.StartCoroutine(LoadStateCoro()); + LoadTempState(); } public void PrepareFileStateToMemory(int paramSlot) @@ -98,7 +108,7 @@ public void PrepareFileStateToMemory(int paramSlot) try { SaveState tmpData = new SaveState(); - + filePath = string.Concat(new object[] { Application.persistentDataPath, @@ -127,9 +137,9 @@ public void PrepareFileStateToMemory(int paramSlot) } } } - catch (Exception ex) + catch (Exception) { - Debug.Log("SaveStateToFile() error: " + ex.Message); + throw; } } diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index 2f2a64f..207b011 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -27,7 +27,10 @@ internal class SaveStateManager : MonoBehaviour { public static SaveState memoryState; private static Dictionary saveStateFiles = new Dictionary(); + private DateTime timeoutHelper; + private double timeoutAmount = 8; + public static bool selectSlot = false; public static int currentStateSlot = -1; public static string path = Application.persistentDataPath + "/Savestates-1221"; public const int maxSaveStates = 10; @@ -39,6 +42,7 @@ internal SaveStateManager() { try { + selectSlot = false; DebugMod.settings.SaveStatePanelVisible = false; autoSlot = false; memoryState = new SaveState(); @@ -46,6 +50,10 @@ internal SaveStateManager() { Directory.CreateDirectory(path); } + else + { + RefreshStateMenu(); + } } catch (Exception) { @@ -71,12 +79,17 @@ public void SaveState(SaveStateType stateType) int initSlot = currentStateSlot; // Refactor using dict.keys()? - while (++currentStateSlot != initSlot && ++i < maxSaveStates) + while (currentStateSlot + 1 != initSlot && ++i < maxSaveStates) { - if (currentStateSlot == maxSaveStates) + if (currentStateSlot + 1 >= maxSaveStates) { currentStateSlot = 0; } + else + { + currentStateSlot++; + } + if (!saveStateFiles.ContainsKey(currentStateSlot)) { saveStateFiles.Add(currentStateSlot, new SaveState()); @@ -85,46 +98,27 @@ public void SaveState(SaveStateType stateType) if (currentStateSlot == initSlot) { // TODO: Inquire if want to overwrite - if (--currentStateSlot < 0) currentStateSlot = maxSaveStates - 1; + currentStateSlot--; + if (currentStateSlot < 0) currentStateSlot = maxSaveStates - 1; saveStateFiles.Remove(currentStateSlot); saveStateFiles.Add(currentStateSlot, new SaveState()); } + if (!memoryState.IsSet()) memoryState.SaveTempState(); + saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); } else { - - DebugMod.settings.SaveStatePanelVisible = true; - while (!saveStateFiles.ContainsKey(currentStateSlot)) - { - SelectSlot(); - } - - DebugMod.settings.SaveStatePanelVisible = false; - saveStateFiles[currentStateSlot].LoadStateFromFile(); - break; + StartCoroutine(SelectSlot(true, stateType)); } - - if (!memoryState.IsSet()) memoryState.SaveTempState(); - saveStateFiles[currentStateSlot].SaveStateToFile(memoryState, currentStateSlot); } break; case SaveStateType.SkipOne: - - DebugMod.settings.SaveStatePanelVisible = true; - while (!saveStateFiles.ContainsKey(currentStateSlot)) - { - SelectSlot(); - } - - DebugMod.settings.SaveStatePanelVisible = false; - saveStateFiles[currentStateSlot].LoadStateFromFile(); + StartCoroutine(SelectSlot(true, stateType)); break; default: break; } } - - #endregion #region loading @@ -143,24 +137,11 @@ public void LoadState(SaveStateType stateType) } break; case SaveStateType.File: - if (!saveStateFiles.ContainsKey(currentStateSlot)) - DebugMod.settings.SaveStatePanelVisible = true; - while (!saveStateFiles.ContainsKey(currentStateSlot)) - { - SelectSlot(); - } - - DebugMod.settings.SaveStatePanelVisible = false; + StartCoroutine(SelectSlot(false, stateType)); saveStateFiles[currentStateSlot].PrepareFileStateToMemory(currentStateSlot); break; case SaveStateType.SkipOne: - DebugMod.settings.SaveStatePanelVisible = true; - while (!saveStateFiles.ContainsKey(currentStateSlot)) - { - SelectSlot(); - } - - DebugMod.settings.SaveStatePanelVisible = false; + StartCoroutine(SelectSlot(false, stateType)); saveStateFiles[currentStateSlot].LoadStateFromFile(); break; default: @@ -171,19 +152,84 @@ public void LoadState(SaveStateType stateType) #endregion #region helper functionality - private void SelectSlot() + private IEnumerator SelectSlot(bool save, SaveStateType stateType) { - foreach (KeyValuePair entry in DebugMod.alphaKeyDict) + timeoutHelper = DateTime.Now.AddSeconds(timeoutAmount); + DebugMod.settings.SaveStatePanelVisible = selectSlot = true; + + //Console.AddLine("coro test (pre if): " + tmp++); + yield return new WaitUntil(DidInput); + + if (GUIController.didInput) { - if (Input.GetKeyDown(entry.Key)) + if (currentStateSlot >= 0 || currentStateSlot < maxSaveStates) { - if (DebugMod.alphaKeyDict.TryGetValue(entry.Key, out int keyInt)) + if (save) + { + SaveCoroHelper(stateType); + } + else { - // keyInt should be between 0-9 - currentStateSlot = keyInt; + LoadCoroHelper(stateType); } + GUIController.didInput = false; } } + else + { + Console.AddLine("Timeout (" + timeoutAmount + "s) reached"); + } + + yield return new WaitForSeconds(3); + DebugMod.settings.SaveStatePanelVisible = selectSlot = false; + } + + private void LoadCoroHelper(SaveStateType stateType) + { + switch (stateType) + { + case SaveStateType.File: + //if (!memoryState.IsSet()) memoryState.SaveTempState(); + saveStateFiles[currentStateSlot].PrepareFileStateToMemory(currentStateSlot); + break; + case SaveStateType.SkipOne: + saveStateFiles[currentStateSlot].LoadStateFromFile(); + break; + default: + break; + } + } + + private void SaveCoroHelper(SaveStateType stateType) + { + switch (stateType) + { + case SaveStateType.File: + if (!memoryState.IsSet()) memoryState.SaveTempState(); + saveStateFiles[currentStateSlot] = memoryState; + saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); + break; + case SaveStateType.SkipOne: + saveStateFiles[currentStateSlot] = new SaveState(); + saveStateFiles[currentStateSlot].SaveTempState(); + saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); + break; + default: + break; + } + } + + private bool DidInput() + { + if (GUIController.didInput) + { + return true; + } + else if (timeoutHelper < DateTime.Now) + { + return true; + } + return false; } public void ToggleAutoSlot() @@ -227,7 +273,32 @@ public static Dictionary GetSaveStatesInfo() } return returnData; } - + + public void RefreshStateMenu() + { + try + { + string[] files = Directory.GetFiles(path); + + foreach (string file in files) + { + var digits = file.SkipWhile(c => !Char.IsDigit(c)).TakeWhile(Char.IsDigit).ToArray(); + var str = new string(digits); + int slot = int.Parse(str); + // TODO: read savestate files enough to get summary + if (File.Exists(file) && (slot < maxSaveStates || slot >= 0)) + { + SaveState tmpData = JsonUtility.FromJson(File.ReadAllText(file)); + saveStateFiles.Remove(slot); + saveStateFiles.Add(slot, tmpData); + } + } + } + catch (Exception) + { + throw; + } + } #endregion } } diff --git a/Source/SaveStatesPanel.cs b/Source/SaveStatesPanel.cs index fdac231..4513b79 100644 --- a/Source/SaveStatesPanel.cs +++ b/Source/SaveStatesPanel.cs @@ -6,14 +6,14 @@ namespace DebugMod { public static class SaveStatesPanel { - private static CanvasPanel panel; + private static CanvasPanel statePanel; public static void BuildMenu(GameObject canvas) { - panel = new CanvasPanel( + statePanel = new CanvasPanel( canvas, GUIController.Instance.images["BlankVertical"], - new Vector2(570f, 230f), + new Vector2(900f, 40f), Vector2.zero, new Rect( 0f, @@ -24,72 +24,68 @@ public static void BuildMenu(GameObject canvas) ); //Labels - panel.AddText("Slot0", "0", new Vector2(10f, 20f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Slot1", "1", new Vector2(10f, 40f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Slot2", "2", new Vector2(10f, 60f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Slot3", "3", new Vector2(10f, 80f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Slot4", "4", new Vector2(10f, 100f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Slot5", "5", new Vector2(10f, 120f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Slot6", "6", new Vector2(10f, 140f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Slot7", "7", new Vector2(10f, 160f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Slot8", "8", new Vector2(10f, 180f), Vector2.zero, GUIController.Instance.arial, 15); - panel.AddText("Slot9", "9", new Vector2(10f, 200f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("Slot0", "0", new Vector2(10f, 20f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("Slot1", "1", new Vector2(10f, 40f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("Slot2", "2", new Vector2(10f, 60f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("Slot3", "3", new Vector2(10f, 80f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("Slot4", "4", new Vector2(10f, 100f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("Slot5", "5", new Vector2(10f, 120f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("Slot6", "6", new Vector2(10f, 140f), Vector2.xzero, GUIController.Instance.arial, 15); + statePanel.AddText("Slot7", "7", new Vector2(10f, 160f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("Slot8", "8", new Vector2(10f, 180f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("Slot9", "9", new Vector2(10f, 200f), Vector2.zero, GUIController.Instance.arial, 15); //Values - panel.AddText("0", "", new Vector2(50f, 20f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("1", "", new Vector2(50f, 40f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("2", "", new Vector2(50f, 60f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("3", "", new Vector2(50f, 80f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("4", "", new Vector2(50f, 100f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("5", "", new Vector2(50f, 120f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("6", "", new Vector2(50f, 140f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("7", "", new Vector2(50f, 160f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("8", "", new Vector2(50f, 180f), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("9", "", new Vector2(50f, 200f), Vector2.zero, GUIController.Instance.trajanNormal); + statePanel.AddText("0", "", new Vector2(50f, 20f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("1", "", new Vector2(50f, 40f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("2", "", new Vector2(50f, 60f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("3", "", new Vector2(50f, 80f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("4", "", new Vector2(50f, 100f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("5", "", new Vector2(50f, 120f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("6", "", new Vector2(50f, 140f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("7", "", new Vector2(50f, 160f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("8", "", new Vector2(50f, 180f), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("9", "", new Vector2(50f, 200f), Vector2.zero, GUIController.Instance.arial, 15); } public static void Update() { - if (panel == null) + if (statePanel == null) { return; } if (DebugMod.GM.IsNonGameplayScene()) { - if (panel.active) + if (statePanel.active) { - panel.SetActive(false, true); + statePanel.SetActive(false, true); } return; } - if (DebugMod.settings.SaveStatePanelVisible && !panel.active) + if (DebugMod.settings.SaveStatePanelVisible && !statePanel.active) { - panel.SetActive(true, false); + statePanel.SetActive(true, false); } - else if (!DebugMod.settings.SaveStatePanelVisible && panel.active) + else if (!DebugMod.settings.SaveStatePanelVisible && statePanel.active) { - panel.SetActive(false, true); + statePanel.SetActive(false, true); } - if (panel.active) + if (statePanel.active) { - panel.GetText("0").UpdateText("Open"); - panel.GetText("1").UpdateText("Open"); - panel.GetText("2").UpdateText("Open"); - panel.GetText("4").UpdateText("Open"); - panel.GetText("5").UpdateText("Open"); - panel.GetText("6").UpdateText("Open"); - panel.GetText("7").UpdateText("Open"); - panel.GetText("8").UpdateText("Open"); - panel.GetText("9").UpdateText("Open"); + + for (int i = 0; i < 10; i++) + { + statePanel.GetText(i.ToString()).UpdateText("open"); + } foreach (KeyValuePair entry in SaveStateManager.GetSaveStatesInfo()) { - panel.GetText(entry.Key.ToString()).UpdateText(string.Format("{0}\n{1}", entry.Value[2], entry.Value[1])); + statePanel.GetText(entry.Key.ToString()).UpdateText(string.Format("{0} // {1}", entry.Value[2], entry.Value[1])); } } } From bb6fb4fa16d944cb2e7a34bee5613aab7d404ac5 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Thu, 21 Jan 2021 02:45:58 +0100 Subject: [PATCH 11/91] SaveState coros fixed, added mono instance GameManager.instance.Coroutine() is obligatory syntax I learnt --- Source/BindableFunctions.cs | 15 +++++----- Source/DebugMod.cs | 3 +- Source/GUIController.cs | 7 +++++ Source/SaveState.cs | 2 +- Source/SaveStateManager.cs | 57 ++++++++++++++++++++++++------------- Source/SaveStatesPanel.cs | 3 +- 6 files changed, 55 insertions(+), 32 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 25b46dc..e7c43f5 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -390,6 +390,12 @@ public static void ToggleEnemyPanel() } } + [BindableMethod(name = "Toggle SaveState Panel", category = "Mod UI")] + public static void ToggleSaveStatesPanel() + { + DebugMod.settings.SaveStatePanelVisible = !DebugMod.settings.SaveStatePanelVisible; + } + // A variant of info panel. View handled in the two InfoPanel classes // Probably some race-condition potential here :) [BindableMethod(name = "Alt. Info Switch", category = "Mod UI")] @@ -398,12 +404,6 @@ public static void ToggleFullInfo() MinimalInfoPanel.minInfo = !MinimalInfoPanel.minInfo; } - [BindableMethod(name = "Toggle SaveState Panel", category = "Mod UI")] - public static void ToggleSaveStatesPanel() - { - DebugMod.settings.SaveStatePanelVisible = !DebugMod.settings.SaveStatePanelVisible; - } - #endregion #region Enemies @@ -583,8 +583,7 @@ public static void ToggleNoclip() public static void KillSelf() { if (DebugMod.GM.isPaused) UIManager.instance.TogglePauseGame(); - HeroController.instance.TakeHealth(PlayerData.instance.maxHealth); - + HeroController.instance.TakeHealth(9999); HeroController.instance.heroDeathPrefab.SetActive(true); DebugMod.GM.ReadyForRespawn(); diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 6e2e7bc..754a53b 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -85,6 +85,7 @@ public override void Initialize() instance.Log("First run detected, setting default binds"); settings.FirstRun = false; + settings.NumPadForSaveStates = false; settings.binds.Clear(); settings.binds.Add("Toggle All UI", (int)KeyCode.F1); @@ -161,7 +162,7 @@ public override void Initialize() public override string GetVersion() { - return "1.3.9d"; + return "1.3.9e"; } public override bool IsCurrent() diff --git a/Source/GUIController.cs b/Source/GUIController.cs index b7b0a4b..c146f5f 100644 --- a/Source/GUIController.cs +++ b/Source/GUIController.cs @@ -195,6 +195,13 @@ public void Update() { PlayerData.instance.MPCharge = PlayerData.instance.maxMP; PlayerData.instance.MPReserve = PlayerData.instance.MPReserveMax; + if (PlayerData.instance.MPReserve > 0) + { + HeroController.instance.TakeReserveMP(1); + HeroController.instance.AddMPChargeSpa(1); + } + HeroController.instance.TakeReserveMP(1); + HeroController.instance.AddMPChargeSpa(1); } if (DebugMod.playerInvincible && PlayerData.instance != null) diff --git a/Source/SaveState.cs b/Source/SaveState.cs index becee15..0f0e247 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -12,7 +12,7 @@ namespace DebugMod /// /// Saves and loads states from runtime data in Hollow Knight /// - internal class SaveState : MonoBehaviour + internal class SaveState { private string saveStateIdentifier = ""; private string saveScene; diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index 207b011..6b9fe16 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -23,7 +23,7 @@ public enum SaveStateType { /// HUD for viewing necessary info for UX. /// AutoSlotSelect to iterate over slots, eventually overwrite when circled and no free slots. /// - internal class SaveStateManager : MonoBehaviour + internal class SaveStateManager { public static SaveState memoryState; private static Dictionary saveStateFiles = new Dictionary(); @@ -42,6 +42,7 @@ internal SaveStateManager() { try { + selectSlot = false; DebugMod.settings.SaveStatePanelVisible = false; autoSlot = false; @@ -89,31 +90,31 @@ public void SaveState(SaveStateType stateType) { currentStateSlot++; } - - if (!saveStateFiles.ContainsKey(currentStateSlot)) - { - saveStateFiles.Add(currentStateSlot, new SaveState()); - } } if (currentStateSlot == initSlot) { // TODO: Inquire if want to overwrite currentStateSlot--; - if (currentStateSlot < 0) currentStateSlot = maxSaveStates - 1; + if (currentStateSlot < 0) + { + currentStateSlot = maxSaveStates - 1; + } + } + if (saveStateFiles.ContainsKey(currentStateSlot)) + { saveStateFiles.Remove(currentStateSlot); - saveStateFiles.Add(currentStateSlot, new SaveState()); } - if (!memoryState.IsSet()) memoryState.SaveTempState(); + saveStateFiles.Add(currentStateSlot, new SaveState()); saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); } else { - StartCoroutine(SelectSlot(true, stateType)); + GameManager.instance.StartCoroutine(SelectSlot(true, stateType)); } } break; case SaveStateType.SkipOne: - StartCoroutine(SelectSlot(true, stateType)); + GameManager.instance.StartCoroutine(SelectSlot(true, stateType)); break; default: break; } @@ -137,12 +138,10 @@ public void LoadState(SaveStateType stateType) } break; case SaveStateType.File: - StartCoroutine(SelectSlot(false, stateType)); - saveStateFiles[currentStateSlot].PrepareFileStateToMemory(currentStateSlot); + GameManager.instance.StartCoroutine(SelectSlot(false, stateType)); break; case SaveStateType.SkipOne: - StartCoroutine(SelectSlot(false, stateType)); - saveStateFiles[currentStateSlot].LoadStateFromFile(); + GameManager.instance.StartCoroutine(SelectSlot(false, stateType)); break; default: break; @@ -172,15 +171,15 @@ private IEnumerator SelectSlot(bool save, SaveStateType stateType) { LoadCoroHelper(stateType); } - GUIController.didInput = false; } + GUIController.didInput = false; } else { Console.AddLine("Timeout (" + timeoutAmount + "s) reached"); } - yield return new WaitForSeconds(3); + //yield return new WaitForSeconds(2); DebugMod.settings.SaveStatePanelVisible = selectSlot = false; } @@ -189,10 +188,18 @@ private void LoadCoroHelper(SaveStateType stateType) switch (stateType) { case SaveStateType.File: - //if (!memoryState.IsSet()) memoryState.SaveTempState(); + if (saveStateFiles[currentStateSlot] == null) + { + saveStateFiles.Add(currentStateSlot, new SaveState()); + } saveStateFiles[currentStateSlot].PrepareFileStateToMemory(currentStateSlot); + memoryState = saveStateFiles[currentStateSlot]; break; case SaveStateType.SkipOne: + if (saveStateFiles[currentStateSlot] == null) + { + saveStateFiles.Add(currentStateSlot, new SaveState()); + } saveStateFiles[currentStateSlot].LoadStateFromFile(); break; default: @@ -205,12 +212,22 @@ private void SaveCoroHelper(SaveStateType stateType) switch (stateType) { case SaveStateType.File: - if (!memoryState.IsSet()) memoryState.SaveTempState(); + if (memoryState == null || !memoryState.IsSet()) + { + memoryState.SaveTempState(); + } + if (saveStateFiles[currentStateSlot] == null) + { + saveStateFiles.Add(currentStateSlot, new SaveState()); + } saveStateFiles[currentStateSlot] = memoryState; saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); break; case SaveStateType.SkipOne: - saveStateFiles[currentStateSlot] = new SaveState(); + if (saveStateFiles[currentStateSlot] == null) + { + saveStateFiles.Add(currentStateSlot, new SaveState()); + } saveStateFiles[currentStateSlot].SaveTempState(); saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); break; diff --git a/Source/SaveStatesPanel.cs b/Source/SaveStatesPanel.cs index 4513b79..232e143 100644 --- a/Source/SaveStatesPanel.cs +++ b/Source/SaveStatesPanel.cs @@ -30,7 +30,7 @@ public static void BuildMenu(GameObject canvas) statePanel.AddText("Slot3", "3", new Vector2(10f, 80f), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("Slot4", "4", new Vector2(10f, 100f), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("Slot5", "5", new Vector2(10f, 120f), Vector2.zero, GUIController.Instance.arial, 15); - statePanel.AddText("Slot6", "6", new Vector2(10f, 140f), Vector2.xzero, GUIController.Instance.arial, 15); + statePanel.AddText("Slot6", "6", new Vector2(10f, 140f), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("Slot7", "7", new Vector2(10f, 160f), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("Slot8", "8", new Vector2(10f, 180f), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("Slot9", "9", new Vector2(10f, 200f), Vector2.zero, GUIController.Instance.arial, 15); @@ -77,7 +77,6 @@ public static void Update() if (statePanel.active) { - for (int i = 0; i < 10; i++) { statePanel.GetText(i.ToString()).UpdateText("open"); From 7b130831edc264ae7b64bc67b8eafb31998ce1bc Mon Sep 17 00:00:00 2001 From: cerpintext Date: Thu, 21 Jan 2021 23:49:00 +0100 Subject: [PATCH 12/91] SaveStates to and from files work --- Source/GUIController.cs | 1 + Source/SaveState.cs | 144 +++++++++++++++++++++---------------- Source/SaveStateManager.cs | 138 +++++++++++++++++++---------------- 3 files changed, 158 insertions(+), 125 deletions(-) diff --git a/Source/GUIController.cs b/Source/GUIController.cs index c146f5f..a13fcde 100644 --- a/Source/GUIController.cs +++ b/Source/GUIController.cs @@ -186,6 +186,7 @@ public void Update() // keyInt should be between 0-9 SaveStateManager.currentStateSlot = keyInt; didInput = true; + Console.AddLine("Number selected, didInput bool: " + didInput.ToString()); } } } diff --git a/Source/SaveState.cs b/Source/SaveState.cs index 0f0e247..ebd8682 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -10,78 +10,96 @@ namespace DebugMod { /// - /// Saves and loads states from runtime data in Hollow Knight + /// Handles struct SaveStateData and individual SaveState operations /// internal class SaveState { - private string saveStateIdentifier = ""; - private string saveScene; - private PlayerData savedPd; - private object lockArea; - private SceneData savedSd; - private Vector3 savePos; - private FieldInfo cameraLockArea; - private string filePath = ""; - + [Serializable] + public class SaveStateData + { + public string saveStateIdentifier; + public string saveScene; + public PlayerData savedPd; + public object lockArea; + public SceneData savedSd; + public Vector3 savePos; + public FieldInfo cameraLockArea; + public string filePath; + } + + [SerializeField] + public SaveStateData data; internal SaveState() { - + this.data = new SaveStateData(); } private SaveState(string _scene, string _identifier, PlayerData _pd, SceneData _sd, Vector3 _pos, FieldInfo _cameraLockArea, object _paramLockArea) { - saveScene = _scene; - saveStateIdentifier = _identifier; - savedPd = _pd; - savedSd = _sd; - savePos = _pos; - cameraLockArea = _cameraLockArea; - lockArea = _paramLockArea; + data.saveScene = _scene; + data.saveStateIdentifier = _identifier; + data.savedPd = _pd; + data.savedSd = _sd; + data.savePos = _pos; + data.cameraLockArea = _cameraLockArea; + data.lockArea = _paramLockArea; } #region saving public void SaveTempState() { - saveScene = GameManager.instance.GetSceneNameString(); - saveStateIdentifier = "(tmp)_" + saveScene + "-" + DateTime.Now.ToString("H:mm_d-MMM"); - savedPd = JsonUtility.FromJson(JsonUtility.ToJson(PlayerData.instance)); - savedSd = JsonUtility.FromJson(JsonUtility.ToJson(SceneData.instance)); - savePos = HeroController.instance.gameObject.transform.position; - cameraLockArea = (cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); - lockArea = cameraLockArea.GetValue(GameManager.instance.cameraCtrl); + data.saveScene = GameManager.instance.GetSceneNameString(); + data.saveStateIdentifier = "(tmp)_" + data.saveScene + "-" + DateTime.Now.ToString("H:mm_d-MMM"); + data.savedPd = JsonUtility.FromJson(JsonUtility.ToJson(PlayerData.instance)); + data.savedSd = JsonUtility.FromJson(JsonUtility.ToJson(SceneData.instance)); + data.savePos = HeroController.instance.gameObject.transform.position; + data.cameraLockArea = (data.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); + data.lockArea = data.cameraLockArea.GetValue(GameManager.instance.cameraCtrl); } public void SaveStateToFile(int paramSlot) { try { - if (saveStateIdentifier.StartsWith("(tmp)_")) + if (data.saveStateIdentifier.StartsWith("(tmp)_")) { - saveStateIdentifier = saveStateIdentifier.Substring(6); + data.saveStateIdentifier = data.saveStateIdentifier.Substring(6); } - else if (String.IsNullOrEmpty(saveStateIdentifier)) + else if (String.IsNullOrEmpty(data.saveStateIdentifier)) { throw new Exception("No temp save state set"); } //filePath = SaveStateManager.path + paramSlot + ".json"; - filePath = string.Concat(new object[] -{ + data.filePath = string.Concat(new object[] { Application.persistentDataPath, "/Savestates-1221/savestate", paramSlot, ".json" }); - - File.WriteAllText(string.Concat( - new object[]{ filePath }), - JsonUtility.ToJson( - new SaveState ( saveStateIdentifier, saveScene, savedPd, savedSd, savePos, cameraLockArea, lockArea ), + + File.WriteAllText( + data.filePath, + JsonUtility.ToJson( data, prettyPrint: true ) ); + + + /* + DebugMod.instance.Log(string.Concat(new object[] { + "SaveStateToFile (this): \n - ", data.saveStateIdentifier, + "\n - ", data.saveScene, + "\n - ", (JsonUtility.ToJson(data.savedPd)), + "\n - ", (JsonUtility.ToJson(data.savedSd)), + "\n - ", data.savePos.ToString(), + "\n - ", data.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic), + "\n - ", data.lockArea.ToString(), " ========= ", data.cameraLockArea.GetValue(GameManager.instance.cameraCtrl) + })); + DebugMod.instance.Log("SaveStateToFile (data): " + data); + */ } catch (Exception) { @@ -107,9 +125,9 @@ public void PrepareFileStateToMemory(int paramSlot) { try { - SaveState tmpData = new SaveState(); + SaveStateData tmpData = new SaveStateData(); - filePath = string.Concat(new object[] + data.filePath = string.Concat(new object[] { Application.persistentDataPath, "/Savestates-1221/savestate", @@ -117,19 +135,19 @@ public void PrepareFileStateToMemory(int paramSlot) ".json" }); - if (File.Exists(filePath)) + if (File.Exists(data.filePath)) { - tmpData = JsonUtility.FromJson(File.ReadAllText(filePath)); + tmpData = JsonUtility.FromJson(File.ReadAllText(data.filePath)); try { - saveStateIdentifier = tmpData.saveStateIdentifier; - cameraLockArea = tmpData.cameraLockArea; - savedPd = tmpData.savedPd; - savedSd = tmpData.savedSd; - savePos = tmpData.savePos; - saveScene = tmpData.saveScene; - lockArea = tmpData.lockArea; - Console.AddLine("Load SaveState ready:" + saveStateIdentifier); + data.saveStateIdentifier = tmpData.saveStateIdentifier; + data.cameraLockArea = tmpData.cameraLockArea; + data.savedPd = tmpData.savedPd; + data.savedSd = tmpData.savedSd; + data.savePos = tmpData.savePos; + data.saveScene = tmpData.saveScene; + data.lockArea = tmpData.lockArea; + Console.AddLine("Load SaveState ready:" + data.saveStateIdentifier); } catch (Exception) { @@ -145,34 +163,34 @@ public void PrepareFileStateToMemory(int paramSlot) private IEnumerator LoadStateCoro() { - Console.AddLine("LoadStateCoro line1: " + savedPd.hazardRespawnLocation.ToString()); - cameraLockArea = (cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); + Console.AddLine("LoadStateCoro line1: " + data.savedPd.hazardRespawnLocation.ToString()); + data.cameraLockArea = (data.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); GameManager.instance.ChangeToScene("Room_Sly_Storeroom", "", 0f); while (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != "Room_Sly_Storeroom") { yield return null; } - GameManager.instance.sceneData = (SceneData.instance = JsonUtility.FromJson(JsonUtility.ToJson(savedSd))); + GameManager.instance.sceneData = (SceneData.instance = JsonUtility.FromJson(JsonUtility.ToJson(data.savedSd))); //if (!BindableFunctions.preserveThroughStates) //{ - Console.AddLine("Before ResetSemiPersistentItems(): " + savedPd.hazardRespawnLocation.ToString()); + Console.AddLine("Before ResetSemiPersistentItems(): " + data.savedPd.hazardRespawnLocation.ToString()); GameManager.instance.ResetSemiPersistentItems(); //} yield return null; - HeroController.instance.gameObject.transform.position = savePos; - PlayerData.instance = (GameManager.instance.playerData = (HeroController.instance.playerData = JsonUtility.FromJson(JsonUtility.ToJson(savedPd)))); - GameManager.instance.ChangeToScene(saveScene, "", 0.4f); + HeroController.instance.gameObject.transform.position = data.savePos; + PlayerData.instance = (GameManager.instance.playerData = (HeroController.instance.playerData = JsonUtility.FromJson(JsonUtility.ToJson(data.savedPd)))); + GameManager.instance.ChangeToScene(data.saveScene, "", 0.4f); try { - cameraLockArea.SetValue(GameManager.instance.cameraCtrl, lockArea); - GameManager.instance.cameraCtrl.LockToArea(lockArea as CameraLockArea); + data.cameraLockArea.SetValue(GameManager.instance.cameraCtrl, data.lockArea); + GameManager.instance.cameraCtrl.LockToArea(data.lockArea as CameraLockArea); BindableFunctions.cameraGameplayScene.SetValue(GameManager.instance.cameraCtrl, true); } catch (Exception message) { Debug.LogError(message); } - yield return new WaitUntil(() => UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == saveScene); + yield return new WaitUntil(() => UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == data.saveScene); HeroController.instance.playerData = PlayerData.instance; if (PlayerData.instance.MPCharge >= 99) { @@ -189,7 +207,7 @@ private IEnumerator LoadStateCoro() HeroController.instance.TakeMP(1); HeroController.instance.AddMPChargeSpa(1); } - Console.AddLine("LoadStateCoro end of func: " + savedPd.hazardRespawnLocation.ToString()); + Console.AddLine("LoadStateCoro end of func: " + data.savedPd.hazardRespawnLocation.ToString()); //HeroController.instance.SetHazardRespawn(savedPd.hazardRespawnLocation, savedPd.hazardRespawnFacingRight); HeroController.instance.proxyFSM.SendEvent("HeroCtrl-HeroDamaged"); HeroController.instance.geoCounter.playerData = PlayerData.instance; @@ -210,7 +228,7 @@ private IEnumerator LoadStateCoro() public bool IsSet() { bool isSet = false; - if (!String.IsNullOrEmpty(saveStateIdentifier)) + if (!String.IsNullOrEmpty(data.saveStateIdentifier)) { isSet = true; } @@ -219,16 +237,16 @@ public bool IsSet() public string GetSaveStateID() { - return saveStateIdentifier; + return data.saveStateIdentifier; } public string[] GetSaveStateInfo() { return new string[] { - filePath, - saveScene, - saveStateIdentifier + data.filePath, + data.saveScene, + data.saveStateIdentifier }; } diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index 6b9fe16..3a6e22e 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -74,47 +74,11 @@ public void SaveState(SaveStateType stateType) case SaveStateType.File: if (memoryState.IsSet()) { - if (autoSlot) - { - int i = 0; - int initSlot = currentStateSlot; - - // Refactor using dict.keys()? - while (currentStateSlot + 1 != initSlot && ++i < maxSaveStates) - { - if (currentStateSlot + 1 >= maxSaveStates) - { - currentStateSlot = 0; - } - else - { - currentStateSlot++; - } - } - if (currentStateSlot == initSlot) - { - // TODO: Inquire if want to overwrite - currentStateSlot--; - if (currentStateSlot < 0) - { - currentStateSlot = maxSaveStates - 1; - } - } - if (saveStateFiles.ContainsKey(currentStateSlot)) - { - saveStateFiles.Remove(currentStateSlot); - } - saveStateFiles.Add(currentStateSlot, new SaveState()); - saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); - } - else - { - GameManager.instance.StartCoroutine(SelectSlot(true, stateType)); - } + AutoSlotSelect(stateType); } break; case SaveStateType.SkipOne: - GameManager.instance.StartCoroutine(SelectSlot(true, stateType)); + AutoSlotSelect(stateType); break; default: break; } @@ -155,13 +119,18 @@ private IEnumerator SelectSlot(bool save, SaveStateType stateType) { timeoutHelper = DateTime.Now.AddSeconds(timeoutAmount); DebugMod.settings.SaveStatePanelVisible = selectSlot = true; - + + //Console.AddLine("didInput bool, pre-WaitUntil(DidInput): " + GUIController.didInput.ToString()); + //Console.AddLine("coro test (pre if): " + tmp++); yield return new WaitUntil(DidInput); - + + //Console.AddLine("didInput bool, post-WaitUntil(DidInput): " + GUIController.didInput.ToString()); + + if (GUIController.didInput) { - if (currentStateSlot >= 0 || currentStateSlot < maxSaveStates) + if (currentStateSlot >= 0 && currentStateSlot < maxSaveStates) { if (save) { @@ -183,53 +152,57 @@ private IEnumerator SelectSlot(bool save, SaveStateType stateType) DebugMod.settings.SaveStatePanelVisible = selectSlot = false; } - private void LoadCoroHelper(SaveStateType stateType) + private void SaveCoroHelper(SaveStateType stateType) { switch (stateType) { case SaveStateType.File: - if (saveStateFiles[currentStateSlot] == null) + if (memoryState == null || !memoryState.IsSet()) { - saveStateFiles.Add(currentStateSlot, new SaveState()); + memoryState.SaveTempState(); } - saveStateFiles[currentStateSlot].PrepareFileStateToMemory(currentStateSlot); - memoryState = saveStateFiles[currentStateSlot]; + if (saveStateFiles.ContainsKey(currentStateSlot)) + { + saveStateFiles.Remove(currentStateSlot); + } + saveStateFiles.Add(currentStateSlot, new SaveState()); + saveStateFiles[currentStateSlot].data = memoryState.data; + saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); break; case SaveStateType.SkipOne: - if (saveStateFiles[currentStateSlot] == null) + if (saveStateFiles.ContainsKey(currentStateSlot)) { - saveStateFiles.Add(currentStateSlot, new SaveState()); + saveStateFiles.Remove(currentStateSlot); } - saveStateFiles[currentStateSlot].LoadStateFromFile(); + saveStateFiles.Add(currentStateSlot, new SaveState()); + saveStateFiles[currentStateSlot].SaveTempState(); + saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); break; default: break; } } - private void SaveCoroHelper(SaveStateType stateType) + private void LoadCoroHelper(SaveStateType stateType) { switch (stateType) { case SaveStateType.File: - if (memoryState == null || !memoryState.IsSet()) - { - memoryState.SaveTempState(); - } - if (saveStateFiles[currentStateSlot] == null) + if (saveStateFiles.ContainsKey(currentStateSlot)) { - saveStateFiles.Add(currentStateSlot, new SaveState()); + saveStateFiles.Remove(currentStateSlot); } - saveStateFiles[currentStateSlot] = memoryState; - saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); + saveStateFiles.Add(currentStateSlot, new SaveState()); + saveStateFiles[currentStateSlot].PrepareFileStateToMemory(currentStateSlot); + memoryState = saveStateFiles[currentStateSlot]; break; case SaveStateType.SkipOne: - if (saveStateFiles[currentStateSlot] == null) + if (saveStateFiles.ContainsKey(currentStateSlot)) { - saveStateFiles.Add(currentStateSlot, new SaveState()); + saveStateFiles.Remove(currentStateSlot); } - saveStateFiles[currentStateSlot].SaveTempState(); - saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); + saveStateFiles.Add(currentStateSlot, new SaveState()); + saveStateFiles[currentStateSlot].LoadStateFromFile(); break; default: break; @@ -316,6 +289,47 @@ public void RefreshStateMenu() throw; } } + + private void AutoSlotSelect(SaveStateType stateType) + { + if (autoSlot) + { + int i = 0; + int initSlot = currentStateSlot; + + // Refactor using dict.keys()? + while (currentStateSlot + 1 != initSlot && ++i < maxSaveStates) + { + if (currentStateSlot + 1 >= maxSaveStates) + { + currentStateSlot = 0; + } + else + { + currentStateSlot++; + } + } + if (currentStateSlot == initSlot) + { + // TODO: Inquire if want to overwrite + currentStateSlot--; + if (currentStateSlot < 0) + { + currentStateSlot = maxSaveStates - 1; + } + } + if (saveStateFiles.ContainsKey(currentStateSlot)) + { + saveStateFiles.Remove(currentStateSlot); + } + saveStateFiles.Add(currentStateSlot, new SaveState()); + saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); + } + else + { + GameManager.instance.StartCoroutine(SelectSlot(true, stateType)); + } + } #endregion } } From d687678faf143dee58ac1fb3f962a03c75a381f2 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Wed, 27 Jan 2021 16:14:35 +0100 Subject: [PATCH 13/91] SaveStates get properly read at startup --- Source/BindableFunctions.cs | 6 +++ Source/DebugMod.cs | 2 +- Source/GUIController.cs | 14 +++---- Source/MinimalInfoPanel.cs | 15 ------- Source/SaveState.cs | 70 ++++++++++++++------------------ Source/SaveStateManager.cs | 80 +++++++++++++++++++++---------------- Source/SaveStatesPanel.cs | 19 ++++++--- 7 files changed, 102 insertions(+), 104 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index e7c43f5..0efd406 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -222,6 +222,12 @@ public static void ToggleAutoSlot() { DebugMod.saveStateManager.ToggleAutoSlot(); } + + [BindableMethod(name = "Refresh state menu", category = "Savestates")] + public static void RefreshSaveStates() + { + DebugMod.saveStateManager.RefreshStateMenu(); + } #endregion #region Visual diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 754a53b..3565ac1 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -162,7 +162,7 @@ public override void Initialize() public override string GetVersion() { - return "1.3.9e"; + return "1.3.9test"; } public override bool IsCurrent() diff --git a/Source/GUIController.cs b/Source/GUIController.cs index a13fcde..1e3c167 100644 --- a/Source/GUIController.cs +++ b/Source/GUIController.cs @@ -175,7 +175,7 @@ public void Update() } } - if (SaveStateManager.selectSlot && DebugMod.settings.SaveStatePanelVisible) + if (SaveStateManager.inSelectSlotState && DebugMod.settings.SaveStatePanelVisible) { foreach (KeyValuePair entry in DebugMod.alphaKeyDict) { @@ -186,7 +186,7 @@ public void Update() // keyInt should be between 0-9 SaveStateManager.currentStateSlot = keyInt; didInput = true; - Console.AddLine("Number selected, didInput bool: " + didInput.ToString()); + //Console.AddLine("Number selected, didInput bool: " + didInput.ToString()); } } } @@ -194,14 +194,14 @@ public void Update() if (DebugMod.infiniteSoul && PlayerData.instance.MPCharge < PlayerData.instance.maxMP && PlayerData.instance.health > 0 && !HeroController.instance.cState.dead && GameManager.instance.IsGameplayScene()) { - PlayerData.instance.MPCharge = PlayerData.instance.maxMP; - PlayerData.instance.MPReserve = PlayerData.instance.MPReserveMax; - if (PlayerData.instance.MPReserve > 0) + PlayerData.instance.MPCharge = PlayerData.instance.maxMP - 1; + if (PlayerData.instance.MPReserveMax > 0) { + PlayerData.instance.MPReserve = PlayerData.instance.MPReserveMax - 1; HeroController.instance.TakeReserveMP(1); - HeroController.instance.AddMPChargeSpa(1); + HeroController.instance.AddMPChargeSpa(2); } - HeroController.instance.TakeReserveMP(1); + //HeroController.instance.TakeReserveMP(1); HeroController.instance.AddMPChargeSpa(1); } diff --git a/Source/MinimalInfoPanel.cs b/Source/MinimalInfoPanel.cs index 4e20476..e651a31 100644 --- a/Source/MinimalInfoPanel.cs +++ b/Source/MinimalInfoPanel.cs @@ -125,21 +125,6 @@ public static void Update() altPanel.GetText("Autoslot").UpdateText(string.Format("{0}", GetStringForBool(SaveStateManager.GetAutoSlot()))); altPanel.GetText("Current slot").UpdateText(string.Format("{0}", slotSet)); - /* - if (SaveStateManager.HasFiles()) - { - string slotSet = SaveStateManager.GetCurrentSlot().ToString(); - if (slotSet == "-1") slotSet = "unset"; - - panel.GetText("Current").UpdateText( - string.Format( - "Auto-select: {0}/n Current slot: {1}", - GetStringForBool(SaveStateManager.GetAutoSlot()), - slotSet - ) - ); - } - */ } } diff --git a/Source/SaveState.cs b/Source/SaveState.cs index ebd8682..33911ce 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -32,17 +32,7 @@ public class SaveStateData internal SaveState() { - this.data = new SaveStateData(); - } - - private SaveState(string _scene, string _identifier, PlayerData _pd, SceneData _sd, Vector3 _pos, FieldInfo _cameraLockArea, object _paramLockArea) { - data.saveScene = _scene; - data.saveStateIdentifier = _identifier; - data.savedPd = _pd; - data.savedSd = _sd; - data.savePos = _pos; - data.cameraLockArea = _cameraLockArea; - data.lockArea = _paramLockArea; + data = new SaveStateData(); } #region saving @@ -70,18 +60,14 @@ public void SaveStateToFile(int paramSlot) { throw new Exception("No temp save state set"); } - - //filePath = SaveStateManager.path + paramSlot + ".json"; - - data.filePath = string.Concat(new object[] { - Application.persistentDataPath, - "/Savestates-1221/savestate", - paramSlot, - ".json" - }); - File.WriteAllText( - data.filePath, + File.WriteAllText ( + string.Concat(new object[] { + SaveStateManager.path, + "/savestate", + paramSlot, + ".json" + }), JsonUtility.ToJson( data, prettyPrint: true ) @@ -101,9 +87,10 @@ public void SaveStateToFile(int paramSlot) DebugMod.instance.Log("SaveStateToFile (data): " + data); */ } - catch (Exception) + catch (Exception ex) { - throw; + DebugMod.instance.LogDebug(ex.Message); + throw ex; } } #endregion @@ -125,19 +112,20 @@ public void PrepareFileStateToMemory(int paramSlot) { try { - SaveStateData tmpData = new SaveStateData(); - - data.filePath = string.Concat(new object[] + data.filePath = string.Concat( + new object[] { - Application.persistentDataPath, - "/Savestates-1221/savestate", + SaveStateManager.path, + "savestate", paramSlot, ".json" }); + DebugMod.instance.Log("prep filepath: " + data.filePath); if (File.Exists(data.filePath)) { - tmpData = JsonUtility.FromJson(File.ReadAllText(data.filePath)); + DebugMod.instance.Log("checked filepath: " + data.filePath); + SaveStateData tmpData = JsonUtility.FromJson(File.ReadAllText(data.filePath)); try { data.saveStateIdentifier = tmpData.saveStateIdentifier; @@ -147,17 +135,18 @@ public void PrepareFileStateToMemory(int paramSlot) data.savePos = tmpData.savePos; data.saveScene = tmpData.saveScene; data.lockArea = tmpData.lockArea; - Console.AddLine("Load SaveState ready:" + data.saveStateIdentifier); + DebugMod.instance.Log("Load SaveState ready: " + data.saveStateIdentifier); } - catch (Exception) + catch (Exception ex) { - Console.AddLine("Save prep failed"); + DebugMod.instance.Log(string.Format(ex.Source, ex.Message)); } } } - catch (Exception) + catch (Exception ex) { - throw; + DebugMod.instance.LogDebug(ex.Message); + throw ex; } } @@ -192,6 +181,8 @@ private IEnumerator LoadStateCoro() } yield return new WaitUntil(() => UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == data.saveScene); HeroController.instance.playerData = PlayerData.instance; + HeroController.instance.geoCounter.playerData = PlayerData.instance; + HeroController.instance.geoCounter.TakeGeo(0); if (PlayerData.instance.MPCharge >= 99) { if (PlayerData.instance.MPReserve > 0) @@ -207,11 +198,9 @@ private IEnumerator LoadStateCoro() HeroController.instance.TakeMP(1); HeroController.instance.AddMPChargeSpa(1); } - Console.AddLine("LoadStateCoro end of func: " + data.savedPd.hazardRespawnLocation.ToString()); + //Console.AddLine("LoadStateCoro end of func: " + data.savedPd.hazardRespawnLocation.ToString()); //HeroController.instance.SetHazardRespawn(savedPd.hazardRespawnLocation, savedPd.hazardRespawnFacingRight); HeroController.instance.proxyFSM.SendEvent("HeroCtrl-HeroDamaged"); - HeroController.instance.geoCounter.playerData = PlayerData.instance; - HeroController.instance.geoCounter.TakeGeo(0); HeroAnimationController component = HeroController.instance.GetComponent(); typeof(HeroAnimationController).GetField("pd", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(component, PlayerData.instance); HeroController.instance.TakeHealth(1); @@ -244,9 +233,8 @@ public string[] GetSaveStateInfo() { return new string[] { - data.filePath, - data.saveScene, - data.saveStateIdentifier + data.saveStateIdentifier, + data.saveScene }; } diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index 3a6e22e..c1e22cd 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -25,29 +25,30 @@ public enum SaveStateType { /// internal class SaveStateManager { + public const int maxSaveStates = 5; + public static SaveState memoryState; + public static bool inSelectSlotState = false; + public static int currentStateSlot = -1; + public static string path = Application.persistentDataPath + "/Savestates-1221/"; + private static Dictionary saveStateFiles = new Dictionary(); + private static bool autoSlot; private DateTime timeoutHelper; private double timeoutAmount = 8; - public static bool selectSlot = false; - public static int currentStateSlot = -1; - public static string path = Application.persistentDataPath + "/Savestates-1221"; - public const int maxSaveStates = 10; - private static bool autoSlot; - //public static bool preserveThroughStates = false; internal SaveStateManager() { try { - - selectSlot = false; - DebugMod.settings.SaveStatePanelVisible = false; + inSelectSlotState = false; autoSlot = false; + DebugMod.settings.SaveStatePanelVisible = false; memoryState = new SaveState(); - if (!Directory.Exists(SaveStateManager.path)) + + if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } @@ -118,7 +119,7 @@ public void LoadState(SaveStateType stateType) private IEnumerator SelectSlot(bool save, SaveStateType stateType) { timeoutHelper = DateTime.Now.AddSeconds(timeoutAmount); - DebugMod.settings.SaveStatePanelVisible = selectSlot = true; + DebugMod.settings.SaveStatePanelVisible = inSelectSlotState = true; //Console.AddLine("didInput bool, pre-WaitUntil(DidInput): " + GUIController.didInput.ToString()); @@ -149,7 +150,7 @@ private IEnumerator SelectSlot(bool save, SaveStateType stateType) } //yield return new WaitForSeconds(2); - DebugMod.settings.SaveStatePanelVisible = selectSlot = false; + DebugMod.settings.SaveStatePanelVisible = inSelectSlotState = false; } private void SaveCoroHelper(SaveStateType stateType) @@ -254,11 +255,14 @@ public static bool HasFiles() public static Dictionary GetSaveStatesInfo() { Dictionary returnData = new Dictionary(); - foreach (KeyValuePair stateData in saveStateFiles) + if (HasFiles()) { - if (stateData.Value.IsSet()) + foreach (KeyValuePair stateData in saveStateFiles) { - returnData.Add(stateData.Key, stateData.Value.GetSaveStateInfo()); + if (stateData.Value.IsSet()) + { + returnData.Add(stateData.Key, stateData.Value.GetSaveStateInfo()); + } } } return returnData; @@ -268,25 +272,37 @@ public void RefreshStateMenu() { try { + //SaveState tempSave = new SaveState(); + string shortFileName; string[] files = Directory.GetFiles(path); + DebugMod.instance.Log( + "path var: " + path + + "\nSavestates: " + files.ToString()); foreach (string file in files) { - var digits = file.SkipWhile(c => !Char.IsDigit(c)).TakeWhile(Char.IsDigit).ToArray(); - var str = new string(digits); - int slot = int.Parse(str); - // TODO: read savestate files enough to get summary - if (File.Exists(file) && (slot < maxSaveStates || slot >= 0)) + shortFileName = Path.GetFileName(file); + DebugMod.instance.Log("file: " + shortFileName); + var digits = shortFileName.SkipWhile(c => !Char.IsDigit(c)).TakeWhile(Char.IsDigit).ToArray(); + int slot = int.Parse(new string(digits)); + + if (File.Exists(file) && (slot >= 0 || slot < maxSaveStates)) { - SaveState tmpData = JsonUtility.FromJson(File.ReadAllText(file)); - saveStateFiles.Remove(slot); - saveStateFiles.Add(slot, tmpData); + if (saveStateFiles.ContainsKey(slot)) + { + saveStateFiles.Remove(slot); + } + saveStateFiles.Add(slot, new SaveState()); + saveStateFiles[slot].PrepareFileStateToMemory(slot); + + DebugMod.instance.Log(saveStateFiles[slot].GetSaveStateID()); } } } - catch (Exception) + catch (Exception ex) { - throw; + DebugMod.instance.Log(string.Format(ex.Source, ex.Message)); + throw ex; } } @@ -297,18 +313,16 @@ private void AutoSlotSelect(SaveStateType stateType) int i = 0; int initSlot = currentStateSlot; + // saveStateFiles.Keys; // Refactor using dict.keys()? - while (currentStateSlot + 1 != initSlot && ++i < maxSaveStates) + while (++currentStateSlot != initSlot && ++i < maxSaveStates && saveStateFiles.ContainsKey(currentStateSlot)) { - if (currentStateSlot + 1 >= maxSaveStates) + if (currentStateSlot + 1 > maxSaveStates) { currentStateSlot = 0; } - else - { - currentStateSlot++; - } } + if (currentStateSlot == initSlot) { // TODO: Inquire if want to overwrite @@ -317,11 +331,9 @@ private void AutoSlotSelect(SaveStateType stateType) { currentStateSlot = maxSaveStates - 1; } - } - if (saveStateFiles.ContainsKey(currentStateSlot)) - { saveStateFiles.Remove(currentStateSlot); } + saveStateFiles.Add(currentStateSlot, new SaveState()); saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); } diff --git a/Source/SaveStatesPanel.cs b/Source/SaveStatesPanel.cs index 232e143..283dd7c 100644 --- a/Source/SaveStatesPanel.cs +++ b/Source/SaveStatesPanel.cs @@ -23,8 +23,15 @@ public static void BuildMenu(GameObject canvas) ) ); - //Labels - statePanel.AddText("Slot0", "0", new Vector2(10f, 20f), Vector2.zero, GUIController.Instance.arial, 15); + for (int i = 0; i < SaveStateManager.maxSaveStates; i++) { + + //Labels + statePanel.AddText("Slot " + i, i.ToString(), new Vector2(10, i * 20 + 20), Vector2.zero, GUIController.Instance.arial, 15); + + //Values + statePanel.AddText(i.ToString(), "", new Vector2(50, i * 20 + 20), Vector2.zero, GUIController.Instance.arial, 15); + } + /* statePanel.AddText("Slot1", "1", new Vector2(10f, 40f), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("Slot2", "2", new Vector2(10f, 60f), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("Slot3", "3", new Vector2(10f, 80f), Vector2.zero, GUIController.Instance.arial, 15); @@ -34,7 +41,7 @@ public static void BuildMenu(GameObject canvas) statePanel.AddText("Slot7", "7", new Vector2(10f, 160f), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("Slot8", "8", new Vector2(10f, 180f), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("Slot9", "9", new Vector2(10f, 200f), Vector2.zero, GUIController.Instance.arial, 15); - + //Values statePanel.AddText("0", "", new Vector2(50f, 20f), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("1", "", new Vector2(50f, 40f), Vector2.zero, GUIController.Instance.arial, 15); @@ -46,7 +53,7 @@ public static void BuildMenu(GameObject canvas) statePanel.AddText("7", "", new Vector2(50f, 160f), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("8", "", new Vector2(50f, 180f), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("9", "", new Vector2(50f, 200f), Vector2.zero, GUIController.Instance.arial, 15); - + */ } public static void Update() @@ -77,14 +84,14 @@ public static void Update() if (statePanel.active) { - for (int i = 0; i < 10; i++) + for (int i = 0; i < SaveStateManager.maxSaveStates; i++) { statePanel.GetText(i.ToString()).UpdateText("open"); } foreach (KeyValuePair entry in SaveStateManager.GetSaveStatesInfo()) { - statePanel.GetText(entry.Key.ToString()).UpdateText(string.Format("{0} // {1}", entry.Value[2], entry.Value[1])); + statePanel.GetText(entry.Key.ToString()).UpdateText(string.Format("{0} - {1}", entry.Value[0], entry.Value[1])); } } } From 5ecdf5d007e5e3c92351b21cccb5646105a75028 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Sun, 31 Jan 2021 19:16:15 +0100 Subject: [PATCH 14/91] Tested further, seems to work well Noclip uses invincibility by default Fixed savestate in-game display Lowered slot cap for performance --- Source/BindableFunctions.cs | 4 ++++ Source/DebugMod.cs | 2 +- Source/MinimalInfoPanel.cs | 4 ++-- Source/SaveState.cs | 14 +++++++++---- Source/SaveStateManager.cs | 41 +++++++++++++++++++------------------ Source/SaveStatesPanel.cs | 2 +- 6 files changed, 39 insertions(+), 28 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 0efd406..b034907 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -576,11 +576,15 @@ public static void ToggleNoclip() if (DebugMod.noclip) { + if (!DebugMod.playerInvincible) + ToggleInvincibility(); Console.AddLine("Enabled noclip"); DebugMod.noclipPos = DebugMod.RefKnight.transform.position; } else { + if (DebugMod.playerInvincible) + ToggleInvincibility(); Console.AddLine("Disabled noclip"); } } diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 3565ac1..c04fd09 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -162,7 +162,7 @@ public override void Initialize() public override string GetVersion() { - return "1.3.9test"; + return "1.4.0"; } public override bool IsCurrent() diff --git a/Source/MinimalInfoPanel.cs b/Source/MinimalInfoPanel.cs index e651a31..d5a8349 100644 --- a/Source/MinimalInfoPanel.cs +++ b/Source/MinimalInfoPanel.cs @@ -107,9 +107,9 @@ public static void Update() if (SaveStateManager.memoryState.IsSet()) { - string[] temp = SaveStateManager.memoryState.GetSaveStateInfo(); + //string[] temp = ; //altPanel.GetText("Current SaveState").UpdateText(string.Format("{0}\n{1}", temp[2], temp[1])); - altPanel.GetText("Current SaveState").UpdateText(temp[2]); + altPanel.GetText("Current SaveState").UpdateText(SaveStateManager.memoryState.GetSaveStateID()); } else { diff --git a/Source/SaveState.cs b/Source/SaveState.cs index 33911ce..e7ac84c 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -48,6 +48,12 @@ public void SaveTempState() data.lockArea = data.cameraLockArea.GetValue(GameManager.instance.cameraCtrl); } + public void NewSaveStateToFile(int paramSlot) + { + SaveTempState(); + SaveStateToFile(paramSlot); + } + public void SaveStateToFile(int paramSlot) { try @@ -102,13 +108,13 @@ public void LoadTempState() HeroController.instance.StartCoroutine(LoadStateCoro()); } - public void LoadStateFromFile() + public void NewLoadStateFromFile() { - PrepareFileStateToMemory(SaveStateManager.currentStateSlot); + LoadStateFromFile(SaveStateManager.currentStateSlot); LoadTempState(); } - public void PrepareFileStateToMemory(int paramSlot) + public void LoadStateFromFile(int paramSlot) { try { @@ -124,7 +130,7 @@ public void PrepareFileStateToMemory(int paramSlot) if (File.Exists(data.filePath)) { - DebugMod.instance.Log("checked filepath: " + data.filePath); + //DebugMod.instance.Log("checked filepath: " + data.filePath); SaveStateData tmpData = JsonUtility.FromJson(File.ReadAllText(data.filePath)); try { diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index c1e22cd..5662c9f 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -69,18 +69,11 @@ public void SaveState(SaveStateType stateType) switch (stateType) { case SaveStateType.Memory: - if (!memoryState.IsSet()) memoryState.SaveTempState(); memoryState.SaveTempState(); break; - case SaveStateType.File: - if (memoryState.IsSet()) - { - AutoSlotSelect(stateType); - } - break; - case SaveStateType.SkipOne: + case SaveStateType.File or SaveStateType.SkipOne: AutoSlotSelect(stateType); - break; + break; default: break; } } @@ -102,10 +95,7 @@ public void LoadState(SaveStateType stateType) Console.AddLine("No save state active"); } break; - case SaveStateType.File: - GameManager.instance.StartCoroutine(SelectSlot(false, stateType)); - break; - case SaveStateType.SkipOne: + case SaveStateType.File or SaveStateType.SkipOne: GameManager.instance.StartCoroutine(SelectSlot(false, stateType)); break; default: @@ -176,8 +166,7 @@ private void SaveCoroHelper(SaveStateType stateType) saveStateFiles.Remove(currentStateSlot); } saveStateFiles.Add(currentStateSlot, new SaveState()); - saveStateFiles[currentStateSlot].SaveTempState(); - saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); + saveStateFiles[currentStateSlot].NewSaveStateToFile(currentStateSlot); break; default: break; @@ -194,7 +183,7 @@ private void LoadCoroHelper(SaveStateType stateType) saveStateFiles.Remove(currentStateSlot); } saveStateFiles.Add(currentStateSlot, new SaveState()); - saveStateFiles[currentStateSlot].PrepareFileStateToMemory(currentStateSlot); + saveStateFiles[currentStateSlot].LoadStateFromFile(currentStateSlot); memoryState = saveStateFiles[currentStateSlot]; break; case SaveStateType.SkipOne: @@ -203,7 +192,7 @@ private void LoadCoroHelper(SaveStateType stateType) saveStateFiles.Remove(currentStateSlot); } saveStateFiles.Add(currentStateSlot, new SaveState()); - saveStateFiles[currentStateSlot].LoadStateFromFile(); + saveStateFiles[currentStateSlot].NewLoadStateFromFile(); break; default: break; @@ -293,7 +282,7 @@ public void RefreshStateMenu() saveStateFiles.Remove(slot); } saveStateFiles.Add(slot, new SaveState()); - saveStateFiles[slot].PrepareFileStateToMemory(slot); + saveStateFiles[slot].LoadStateFromFile(slot); DebugMod.instance.Log(saveStateFiles[slot].GetSaveStateID()); } @@ -333,9 +322,21 @@ private void AutoSlotSelect(SaveStateType stateType) } saveStateFiles.Remove(currentStateSlot); } - + saveStateFiles.Add(currentStateSlot, new SaveState()); - saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); + if (stateType == SaveStateType.Memory) + { + if (memoryState == null || !memoryState.IsSet()) + { + memoryState.SaveTempState(); + } + saveStateFiles[currentStateSlot].data = memoryState.data; + saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); + } + else if (stateType == SaveStateType.SkipOne) + { + saveStateFiles[currentStateSlot].NewSaveStateToFile(currentStateSlot); + } } else { diff --git a/Source/SaveStatesPanel.cs b/Source/SaveStatesPanel.cs index 283dd7c..ffb5508 100644 --- a/Source/SaveStatesPanel.cs +++ b/Source/SaveStatesPanel.cs @@ -13,7 +13,7 @@ public static void BuildMenu(GameObject canvas) statePanel = new CanvasPanel( canvas, GUIController.Instance.images["BlankVertical"], - new Vector2(900f, 40f), + new Vector2(800f, 40f), Vector2.zero, new Rect( 0f, From 156af52439d77e128c5ac40602727f66e2f87c19 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Thu, 4 Feb 2021 05:36:17 +0100 Subject: [PATCH 15/91] Ported the hitbox viewer [credits: seresharp, 56] --- Source/HitboxViewer.cs | 270 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 Source/HitboxViewer.cs diff --git a/Source/HitboxViewer.cs b/Source/HitboxViewer.cs new file mode 100644 index 0000000..56d3a8d --- /dev/null +++ b/Source/HitboxViewer.cs @@ -0,0 +1,270 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using GlobalEnums; +using Modding; +using UnityEngine; +using UnityEngine.SceneManagement; + +using Object = UnityEngine.Object; + +namespace DebugMod +{ + //public class ShowHitboxes : Mod, ITogglableMod + public class ShowHitboxes + { + public static int HitboxState; + + private static Material greenMat; + private static Material redMat; + private static Material yellowMat; + private static Material blueMat; + + private Dictionary lines = new Dictionary(); + private List colliders = new List(); + + public ShowHitboxes() + { + HitboxState = 0; + + greenMat = new Material(Shader.Find("Diffuse")); + greenMat.renderQueue = 4000; + greenMat.color = Color.green; + + redMat = new Material(Shader.Find("Diffuse")); + redMat.renderQueue = 4000; + redMat.color = Color.red; + + yellowMat = new Material(Shader.Find("Diffuse")); + yellowMat.renderQueue = 4000; + yellowMat.color = Color.yellow; + + blueMat = new Material(Shader.Find("Diffuse")); + blueMat.renderQueue = 4000; + blueMat.color = Color.blue; + } + + public void Load() + { + Unload(); + UnityEngine.SceneManagement.SceneManager.activeSceneChanged += SpawnHitboxes; + ModHooks.Instance.HeroUpdateHook += UpdateHitboxes; + HitboxState = 1; + + SpawnHitboxes(); + } + + + public void Unload() + { + UnityEngine.SceneManagement.SceneManager.activeSceneChanged -= SpawnHitboxes; + ModHooks.Instance.HeroUpdateHook -= UpdateHitboxes; + HitboxState = 0; + + foreach (GameObject obj in Object.FindObjectsOfType()) + { + if (obj.name == "Mod Hitbox") + { + Object.Destroy(obj); + } + } + } + + private void DestroyBorder(IEnumerable borders) + { + foreach (GameObject border in borders) + { + Object.Destroy(border); + } + } + + private void SpawnHitboxes() + { + if (!GameManager.instance.IsGameplayScene()) + { + return; + } + + DestroyBorder(Object.FindObjectsOfType().Where(x => x.name.Contains("sceneborder"))); + + foreach (Collider2D col in lines.Keys.ToArray()) + { + if (col != null && lines[col] != null) + { + Object.Destroy(lines[col].gameObject); + } + } + + colliders = new List(); + lines = new Dictionary(); + + foreach (Collider2D col in Object.FindObjectsOfType()) + { + if (colliders.Contains(col)) + { + continue; + } + + if (col.gameObject.layer == (int)PhysLayers.TERRAIN) + { + lines.Add(col, SetupLineRenderer(col, null, greenMat)); + } + else if (col.GetComponent()) + { + lines.Add(col, SetupLineRenderer(col, null, blueMat)); + } + else if (col.GetComponent() || col.gameObject.LocateMyFSM("damages_hero") != null) + { + colliders.Add(col); + lines.Add(col, SetupLineRenderer(col, null, redMat)); + } + else if (col.gameObject == HeroController.instance.gameObject && !col.isTrigger) + { + colliders.Add(col); + lines.Add(col, SetupLineRenderer(col, null, yellowMat)); + } + else if (col.GetComponent()) + { + NonBouncer bounce = col.GetComponent(); + if (bounce == null || !bounce.active) + { + colliders.Add(col); + lines.Add(col, SetupLineRenderer(col, null, blueMat)); + } + } + } + } + + private void SpawnHitboxes(Scene from, Scene to) => SpawnHitboxes(); + + private void UpdateHitboxes() + { + if (colliders == null || lines == null) + { + return; + } + + foreach (Collider2D col in colliders) + { + if (col == null || !col.enabled) + { + if (lines[col] != null) + { + Object.Destroy(lines[col].gameObject); + } + + continue; + } + + lines[col] = SetupLineRenderer(col, lines[col]); + } + } + + private LineRenderer SetupLineRenderer(Collider2D col, LineRenderer line = null, Material mat = null) + { + if (line == null) + { + if (mat == null) + { + mat = greenMat; + } + + GameObject obj = new GameObject("Mod Hitbox"); + obj.transform.SetParent(col.transform); + obj.transform.position = Vector3.zero; + + line = obj.AddComponent(); + line.SetWidth(.05f, .05f); + line.sharedMaterial = mat; + } + + if (col is BoxCollider2D box) + { + Vector2 topRight = box.size / 2f; + Vector2 bottomLeft = -topRight; + Vector2 bottomRight = new Vector2(topRight.x, bottomLeft.y); + Vector2 topLeft = -bottomRight; + + line.SetVertexCount(5); + line.SetPositions(new Vector3[] + { + col.transform.TransformPoint(bottomLeft + box.offset), + col.transform.TransformPoint(topLeft + box.offset), + col.transform.TransformPoint(topRight + box.offset), + col.transform.TransformPoint(bottomRight + box.offset), + col.transform.TransformPoint(bottomLeft + box.offset) + }); + } + else if (col is CircleCollider2D circle) + { + Vector3 center = circle.transform.position + (Vector3)circle.offset; + + Vector3[] points = new Vector3[30]; + float sliceSize = Mathf.PI * 2f / points.Length; + + for (int i = 0; i < points.Length - 1; i++) + { + float theta = sliceSize * i; + float sin = (float)Math.Sin(theta); + float cos = (float)Math.Cos(theta); + + points[i] = new Vector2( + (cos - sin) * circle.transform.localScale.x * circle.radius, + (cos + sin) * circle.transform.localScale.y * circle.radius); + } + + points[points.Length - 1] = points[0]; + + line.SetVertexCount(points.Length); + line.SetPositions(points); + } + else if (col is PolygonCollider2D poly) + { + Vector3[] points = new Vector3[poly.points.Length + 1]; + for (int i = 0; i < poly.points.Length; i++) + { + points[i] = poly.transform.TransformPoint(poly.points[i]); + } + + points[points.Length - 1] = points[0]; + line.SetVertexCount(points.Length); + line.SetPositions(points); + } + else if (col is EdgeCollider2D edge) + { + Vector3[] points = new Vector3[edge.points.Length]; + for (int i = 0; i < edge.points.Length; i++) + { + points[i] = edge.transform.TransformPoint(edge.points[i]); + } + + line.SetVertexCount(points.Length); + line.SetPositions(points); + } + + return line; + } + + private bool IsChildOf(GameObject child, GameObject parent) + { + if (child == null || parent == null) + { + return false; + } + + Transform t = child.transform; + + while (t != null) + { + if (t.gameObject == parent) + { + return true; + } + + t = t.parent; + } + + return false; + } + } +} From 6e9ebf82ce678ddc30111b52c1ebc50ed5100f62 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Thu, 4 Feb 2021 05:36:34 +0100 Subject: [PATCH 16/91] Hitbox viewer to bindable functions Todo: make savestates refer to copy rather than reference --- Source/BindableFunctions.cs | 7 +++++++ Source/DebugMod.cs | 4 ++-- Source/DebugMod.csproj | 1 + Source/GUIController.cs | 9 +++++++++ Source/Settings.cs | 6 ++++++ 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index b034907..4665dcc 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -232,6 +232,13 @@ public static void RefreshSaveStates() #region Visual + [BindableMethod(name = "Show Hitboxes", category = "Visual")] + public static void ShowHitboxes() + { + DebugMod.settings.ShowHitBoxes = !DebugMod.settings.ShowHitBoxes; + Console.AddLine("Toggled show hitboxes: " + (DebugMod.settings.ShowHitBoxes ? "true" : "false")); + } + [BindableMethod(name = "Toggle Vignette", category = "Visual")] public static void ToggleVignette() { diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index c04fd09..a9ff252 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -10,7 +10,7 @@ namespace DebugMod { - public class DebugMod : Mod + public class DebugMod : Mod, IMod { private static GameManager _gm; private static InputHandler _ih; @@ -19,7 +19,7 @@ public class DebugMod : Mod private static PlayMakerFSM _refKnightSlash; private static CameraController _refCamera; private static PlayMakerFSM _refDreamNail; - + internal static GameManager GM => _gm != null ? _gm : (_gm = GameManager.instance); internal static InputHandler IH => _ih != null ? _ih : (_ih = GM.inputHandler); internal static HeroController HC => _hc != null ? _hc : (_hc = GM.hero_ctrl); diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 89e33cd..8fe464d 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -73,6 +73,7 @@ + diff --git a/Source/GUIController.cs b/Source/GUIController.cs index 1e3c167..230bc62 100644 --- a/Source/GUIController.cs +++ b/Source/GUIController.cs @@ -17,6 +17,7 @@ public class GUIController : MonoBehaviour public Vector3 hazardLocation; public string respawnSceneWatch; public static bool didInput; + public static ShowHitboxes hitboxes = new ShowHitboxes(); private GameObject canvas; private static GUIController _instance; @@ -281,6 +282,14 @@ public void Update() PlayerData.instance.respawnMarkerName.ToString() })); } + if (ShowHitboxes.HitboxState != 1 && DebugMod.settings.ShowHitBoxes) + { + hitboxes.Load(); + } + else if (ShowHitboxes.HitboxState != 0 && !DebugMod.settings.ShowHitBoxes) + { + hitboxes.Unload(); + } } } diff --git a/Source/Settings.cs b/Source/Settings.cs index b7443c0..588f4c0 100644 --- a/Source/Settings.cs +++ b/Source/Settings.cs @@ -63,5 +63,11 @@ public bool NumPadForSaveStates get => GetBool(true); set => SetBool(value); } + + public bool ShowHitBoxes + { + get => GetBool(true); + set => SetBool(value); + } } } From 877774b16ffe59a1071e034afb7d9142bf1c84ca Mon Sep 17 00:00:00 2001 From: cerpintext Date: Sun, 7 Feb 2021 02:45:39 +0100 Subject: [PATCH 17/91] SaveState deep-copy implemented Slight renames of BindableFunctions for organising. SaveStateData.DeepCopy() for proper handling of state slots vs quickslot --- Source/BindableFunctions.cs | 67 ++++++++++++++++++++++++------------- Source/DebugMod.csproj | 1 + Source/MinimalInfoPanel.cs | 4 +-- Source/SaveState.cs | 17 ++++++++++ Source/SaveStateManager.cs | 43 +++++++++++------------- 5 files changed, 82 insertions(+), 50 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 4665dcc..33926b1 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -4,6 +4,7 @@ using System.IO; using UnityEngine; using GlobalEnums; +using HutongGames.PlayMaker; namespace DebugMod { @@ -153,30 +154,6 @@ public static void TimescaleUp() } } - [BindableMethod(name = "SceneData to file", category = "Misc")] - public static void SceneDataToFile() - { - File.WriteAllText(string.Concat( - new object[] { Application.persistentDataPath, "SceneData.json" }), - JsonUtility.ToJson( - SceneData.instance, - prettyPrint: true - ) - ); - } - - [BindableMethod(name = "PlayerData to file", category = "Misc")] - public static void PlayerDataToFile() - { - - File.WriteAllText(string.Concat( - new object[] { Application.persistentDataPath, "PlayerData.json" }), - JsonUtility.ToJson( - PlayerData.instance, - prettyPrint: true - ) - ); - } #endregion #region SaveStates @@ -1294,5 +1271,47 @@ public static void AddDGPosition() } #endregion + + + #region ExportData + + [BindableMethod(name = "SceneData to file", category = "ExportData")] + public static void SceneDataToFile() + { + File.WriteAllText(string.Concat( + new object[] { Application.persistentDataPath, "/SceneData.json" }), + JsonUtility.ToJson( + SceneData.instance, + prettyPrint: true + ) + ); + } + + + + [BindableMethod(name = "PlayerData to file", category = "ExportData")] + public static void PlayerDataToFile() + { + File.WriteAllText(string.Concat( + new object[] { Application.persistentDataPath, "/PlayerData.json" }), + JsonUtility.ToJson( + PlayerData.instance, + prettyPrint: true + ) + ); + } + + /* + [BindableMethod(name = "Scene FSMs to file", category = "ExportData")] + public static void FSMsToFile() + { + foreach (var fsm in GameManager.instance.GetComponents()) + { + DebugMod.instance.Log(fsm); + } + + } + */ + #endregion } } diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 8fe464d..bc217d8 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -73,6 +73,7 @@ + diff --git a/Source/MinimalInfoPanel.cs b/Source/MinimalInfoPanel.cs index d5a8349..ed6ecec 100644 --- a/Source/MinimalInfoPanel.cs +++ b/Source/MinimalInfoPanel.cs @@ -105,11 +105,11 @@ public static void Update() altPanel.GetText("Scene Name").UpdateText(DebugMod.GetSceneName()); - if (SaveStateManager.memoryState.IsSet()) + if (SaveStateManager.quickState.IsSet()) { //string[] temp = ; //altPanel.GetText("Current SaveState").UpdateText(string.Format("{0}\n{1}", temp[2], temp[1])); - altPanel.GetText("Current SaveState").UpdateText(SaveStateManager.memoryState.GetSaveStateID()); + altPanel.GetText("Current SaveState").UpdateText(SaveStateManager.quickState.GetSaveStateID()); } else { diff --git a/Source/SaveState.cs b/Source/SaveState.cs index e7ac84c..c4a43c3 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -25,6 +25,19 @@ public class SaveStateData public Vector3 savePos; public FieldInfo cameraLockArea; public string filePath; + + internal SaveStateData() { } + + internal SaveStateData(SaveStateData _data) + { + saveStateIdentifier = _data.saveStateIdentifier; + saveScene = _data.saveScene; + cameraLockArea = _data.cameraLockArea; + savedPd = _data.savedPd; + savedSd = _data.savedSd; + savePos = _data.savePos; + lockArea = _data.lockArea; + } } [SerializeField] @@ -243,6 +256,10 @@ public string[] GetSaveStateInfo() data.saveScene }; } + public SaveStateData DeepCopy() + { + return new SaveStateData(this.data); + } #endregion } diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index 5662c9f..3965911 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -17,7 +17,7 @@ public enum SaveStateType { /// /// Handles organisation of SaveState-s - /// memoryState replicating legacy behaviour of only stored in RAM. + /// quickState replicating legacy behaviour of only stored in RAM. /// Dictionary(int slot : file). Might change to HashMap(?) /// if: memory requirement too high: array for limiting savestates? hashmap as all states should logically be unique? /// HUD for viewing necessary info for UX. @@ -27,7 +27,7 @@ internal class SaveStateManager { public const int maxSaveStates = 5; - public static SaveState memoryState; + public static SaveState quickState; public static bool inSelectSlotState = false; public static int currentStateSlot = -1; public static string path = Application.persistentDataPath + "/Savestates-1221/"; @@ -46,7 +46,7 @@ internal SaveStateManager() inSelectSlotState = false; autoSlot = false; DebugMod.settings.SaveStatePanelVisible = false; - memoryState = new SaveState(); + quickState = new SaveState(); if (!Directory.Exists(path)) { @@ -69,7 +69,7 @@ public void SaveState(SaveStateType stateType) switch (stateType) { case SaveStateType.Memory: - memoryState.SaveTempState(); + quickState.SaveTempState(); break; case SaveStateType.File or SaveStateType.SkipOne: AutoSlotSelect(stateType); @@ -81,14 +81,15 @@ public void SaveState(SaveStateType stateType) #endregion #region loading + public void LoadState(SaveStateType stateType) { switch (stateType) { case SaveStateType.Memory: - if (memoryState.IsSet()) + if (quickState.IsSet()) { - memoryState.LoadTempState(); + quickState.LoadTempState(); } else { @@ -109,16 +110,9 @@ public void LoadState(SaveStateType stateType) private IEnumerator SelectSlot(bool save, SaveStateType stateType) { timeoutHelper = DateTime.Now.AddSeconds(timeoutAmount); - DebugMod.settings.SaveStatePanelVisible = inSelectSlotState = true; - - //Console.AddLine("didInput bool, pre-WaitUntil(DidInput): " + GUIController.didInput.ToString()); - //Console.AddLine("coro test (pre if): " + tmp++); + DebugMod.settings.SaveStatePanelVisible = inSelectSlotState = true; yield return new WaitUntil(DidInput); - - //Console.AddLine("didInput bool, post-WaitUntil(DidInput): " + GUIController.didInput.ToString()); - - if (GUIController.didInput) { if (currentStateSlot >= 0 && currentStateSlot < maxSaveStates) @@ -139,25 +133,25 @@ private IEnumerator SelectSlot(bool save, SaveStateType stateType) Console.AddLine("Timeout (" + timeoutAmount + "s) reached"); } - //yield return new WaitForSeconds(2); DebugMod.settings.SaveStatePanelVisible = inSelectSlotState = false; } + // Todo: cleanup Adds and Removes, because used to C++ :) private void SaveCoroHelper(SaveStateType stateType) { switch (stateType) { case SaveStateType.File: - if (memoryState == null || !memoryState.IsSet()) + if (quickState == null || !quickState.IsSet()) { - memoryState.SaveTempState(); + quickState.SaveTempState(); } if (saveStateFiles.ContainsKey(currentStateSlot)) { saveStateFiles.Remove(currentStateSlot); } saveStateFiles.Add(currentStateSlot, new SaveState()); - saveStateFiles[currentStateSlot].data = memoryState.data; + saveStateFiles[currentStateSlot].data = quickState.DeepCopy(); saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); break; case SaveStateType.SkipOne: @@ -184,7 +178,7 @@ private void LoadCoroHelper(SaveStateType stateType) } saveStateFiles.Add(currentStateSlot, new SaveState()); saveStateFiles[currentStateSlot].LoadStateFromFile(currentStateSlot); - memoryState = saveStateFiles[currentStateSlot]; + quickState.data = saveStateFiles[currentStateSlot].DeepCopy(); break; case SaveStateType.SkipOne: if (saveStateFiles.ContainsKey(currentStateSlot)) @@ -229,9 +223,9 @@ public static int GetCurrentSlot() public string[] GetCurrentMemoryState() { - if (memoryState.IsSet()) + if (quickState.IsSet()) { - return memoryState.GetSaveStateInfo(); + return quickState.GetSaveStateInfo(); } return null; } @@ -326,11 +320,12 @@ private void AutoSlotSelect(SaveStateType stateType) saveStateFiles.Add(currentStateSlot, new SaveState()); if (stateType == SaveStateType.Memory) { - if (memoryState == null || !memoryState.IsSet()) + if (quickState == null || !quickState.IsSet()) { - memoryState.SaveTempState(); + quickState.SaveTempState(); } - saveStateFiles[currentStateSlot].data = memoryState.data; + // May not need DeepCopy() + saveStateFiles[currentStateSlot].data = quickState.DeepCopy(); saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); } else if (stateType == SaveStateType.SkipOne) From 5e46725181e674aa2973519c3e5ac65d0c2daad0 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Wed, 10 Feb 2021 23:20:01 +0100 Subject: [PATCH 18/91] Hitboxview mode matching 1028 minidebug --- Source/BindableFunctions.cs | 4 +- Source/GUIController.cs | 15 +++-- Source/HitboxViewer.cs | 130 +++++++++++++++++++++++++++++------- Source/Settings.cs | 6 +- 4 files changed, 120 insertions(+), 35 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 33926b1..de028cd 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -212,8 +212,8 @@ public static void RefreshSaveStates() [BindableMethod(name = "Show Hitboxes", category = "Visual")] public static void ShowHitboxes() { - DebugMod.settings.ShowHitBoxes = !DebugMod.settings.ShowHitBoxes; - Console.AddLine("Toggled show hitboxes: " + (DebugMod.settings.ShowHitBoxes ? "true" : "false")); + if (++DebugMod.settings.ShowHitBoxes > 2) DebugMod.settings.ShowHitBoxes = 0; + Console.AddLine("Toggled show hitboxes: " + DebugMod.settings.ShowHitBoxes); } [BindableMethod(name = "Toggle Vignette", category = "Visual")] diff --git a/Source/GUIController.cs b/Source/GUIController.cs index 230bc62..5cf26fb 100644 --- a/Source/GUIController.cs +++ b/Source/GUIController.cs @@ -282,13 +282,16 @@ public void Update() PlayerData.instance.respawnMarkerName.ToString() })); } - if (ShowHitboxes.HitboxState != 1 && DebugMod.settings.ShowHitBoxes) + if (ShowHitboxes.State != DebugMod.settings.ShowHitBoxes) { - hitboxes.Load(); - } - else if (ShowHitboxes.HitboxState != 0 && !DebugMod.settings.ShowHitBoxes) - { - hitboxes.Unload(); + if (DebugMod.settings.ShowHitBoxes != 0) + { + hitboxes.Load(); + } + else if (ShowHitboxes.State != 0 && DebugMod.settings.ShowHitBoxes == 0) + { + hitboxes.Unload(); + } } } } diff --git a/Source/HitboxViewer.cs b/Source/HitboxViewer.cs index 56d3a8d..dba6570 100644 --- a/Source/HitboxViewer.cs +++ b/Source/HitboxViewer.cs @@ -13,7 +13,7 @@ namespace DebugMod //public class ShowHitboxes : Mod, ITogglableMod public class ShowHitboxes { - public static int HitboxState; + public static int State; private static Material greenMat; private static Material redMat; @@ -25,7 +25,7 @@ public class ShowHitboxes public ShowHitboxes() { - HitboxState = 0; + State = 0; greenMat = new Material(Shader.Find("Diffuse")); greenMat.renderQueue = 4000; @@ -49,7 +49,7 @@ public void Load() Unload(); UnityEngine.SceneManagement.SceneManager.activeSceneChanged += SpawnHitboxes; ModHooks.Instance.HeroUpdateHook += UpdateHitboxes; - HitboxState = 1; + State = DebugMod.settings.ShowHitBoxes; SpawnHitboxes(); } @@ -59,7 +59,7 @@ public void Unload() { UnityEngine.SceneManagement.SceneManager.activeSceneChanged -= SpawnHitboxes; ModHooks.Instance.HeroUpdateHook -= UpdateHitboxes; - HitboxState = 0; + State = DebugMod.settings.ShowHitBoxes; foreach (GameObject obj in Object.FindObjectsOfType()) { @@ -105,33 +105,115 @@ private void SpawnHitboxes() continue; } - if (col.gameObject.layer == (int)PhysLayers.TERRAIN) - { - lines.Add(col, SetupLineRenderer(col, null, greenMat)); - } - else if (col.GetComponent()) - { - lines.Add(col, SetupLineRenderer(col, null, blueMat)); - } - else if (col.GetComponent() || col.gameObject.LocateMyFSM("damages_hero") != null) + if (col.gameObject.layer == (int)PhysLayers.TERRAIN) + { + lines.Add(col, SetupLineRenderer(col, null, greenMat)); + } + else if (col.GetComponent()) + { + lines.Add(col, SetupLineRenderer(col, null, blueMat)); + } + else if (col.GetComponent() || col.gameObject.LocateMyFSM("damages_hero") != null) + { + colliders.Add(col); + lines.Add(col, SetupLineRenderer(col, null, redMat)); + } + else if (col.gameObject == HeroController.instance.gameObject && !col.isTrigger) + { + colliders.Add(col); + lines.Add(col, SetupLineRenderer(col, null, yellowMat)); + } + else if (col.GetComponent()) + { + NonBouncer bounce = col.GetComponent(); + if (bounce == null || !bounce.active) + { + colliders.Add(col); + lines.Add(col, SetupLineRenderer(col, null, blueMat)); + } + } + + /* State 2 */ + else if (State == 2 && col.isTrigger && col.gameObject.GetComponent() != null) + { + colliders.Add(col); + lines.Add(col, this.SetupLineRenderer(col, null, blueMat)); + } + else if (State == 2 && col.isTrigger && col.gameObject.GetComponent() == null) + { + this.colliders.Add(col); + this.lines.Add(col, this.SetupLineRenderer(col, null, yellowMat)); + } + + } + } + + private void Spawn1028Hitboxes() + { + if (!GameManager.instance.IsGameplayScene()) + { + return; + } + + DestroyBorder(Object.FindObjectsOfType().Where(x => x.name.Contains("sceneborder"))); + + foreach (Collider2D col in lines.Keys.ToArray()) + { + if (col != null && lines[col] != null) { - colliders.Add(col); - lines.Add(col, SetupLineRenderer(col, null, redMat)); + Object.Destroy(lines[col].gameObject); } - else if (col.gameObject == HeroController.instance.gameObject && !col.isTrigger) + } + + colliders = new List(); + lines = new Dictionary(); + + foreach (Collider2D col in Object.FindObjectsOfType()) + { + if (colliders.Contains(col)) { - colliders.Add(col); - lines.Add(col, SetupLineRenderer(col, null, yellowMat)); + continue; } - else if (col.GetComponent()) - { - NonBouncer bounce = col.GetComponent(); - if (bounce == null || !bounce.active) + + if (col.gameObject.layer == (int)PhysLayers.TERRAIN) + { + lines.Add(col, SetupLineRenderer(col, null, greenMat)); + } + else if (col.GetComponent()) { - colliders.Add(col); lines.Add(col, SetupLineRenderer(col, null, blueMat)); } - } + else if (col.GetComponent() || col.gameObject.LocateMyFSM("damages_hero") != null) + { + colliders.Add(col); + lines.Add(col, SetupLineRenderer(col, null, redMat)); + } + else if (col.gameObject == HeroController.instance.gameObject && !col.isTrigger) + { + colliders.Add(col); + lines.Add(col, SetupLineRenderer(col, null, yellowMat)); + } + else if (col.GetComponent()) + { + NonBouncer bounce = col.GetComponent(); + if (bounce == null || !bounce.active) + { + colliders.Add(col); + lines.Add(col, SetupLineRenderer(col, null, blueMat)); + } + } + + /* State 2 */ + else if (State == 2 && col.isTrigger && col.gameObject.GetComponent() != null) + { + colliders.Add(col); + lines.Add(col, this.SetupLineRenderer(col, null, blueMat)); + } + else if (State == 2 && col.isTrigger && col.gameObject.GetComponent() == null) + { + this.colliders.Add(col); + this.lines.Add(col, this.SetupLineRenderer(col, null, yellowMat)); + } } } diff --git a/Source/Settings.cs b/Source/Settings.cs index 588f4c0..7bfe3c8 100644 --- a/Source/Settings.cs +++ b/Source/Settings.cs @@ -64,10 +64,10 @@ public bool NumPadForSaveStates set => SetBool(value); } - public bool ShowHitBoxes + public int ShowHitBoxes { - get => GetBool(true); - set => SetBool(value); + get => GetInt(); + set => SetInt(value); } } } From c4c4ddfdd1dacd63fa19711da3aa1586d62b694a Mon Sep 17 00:00:00 2001 From: cerpintext Date: Fri, 26 Feb 2021 06:02:35 +0100 Subject: [PATCH 19/91] backporting CP readme, fixed small bugs, renamed stuff --- README.md | 86 ++++++++++++++++++++++++++++++++++++- Source/BindableFunctions.cs | 30 +++++++------ Source/BossHandler.cs | 24 +++++++++++ Source/DebugMod.cs | 12 +++--- Source/SaveStateManager.cs | 4 +- Source/Settings.cs | 6 +++ 6 files changed, 141 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 02397fa..d4aa62f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,86 @@ Original mod by KeinZantezuken. Remaking using canvas instead of imgui and the modding framework created by myself and MyEyes/Firzen. -# How to build: -Make a folder `Source/References/`, and add `Assembly-CSharp.dll` (with modding-api), `PlayMaker.dll`, `UnityEngine.dll`, and `UnityEngine.UI.dll` from your `Hollow Knight/hollow_knight_Data/Managed/`-folder \ No newline at end of file +---------------------------------------------------------------------------------------- + FEATURES +---------------------------------------------------------------------------------------- +* A completely new toggleable UI in game that provides the following functions: +* Cheats such as invincibility and noclip +* The ability to unlock all charms or repair broken ones +* Change which skills the player has +* Change which items the player has +* Give the player more of consumable resources such as geo and essence +* Respawn bosses +* Hold multiple dream gate positions +* Change the player's respawn point to anywhere in the current scene +* Recall to the set respawn point +* Kill all enemies +* Add HP bars to enemies +* Draw collision boxes for enemies +* Clone or delete any enemy +* Set an enemy's health to 9999 +* Change the player's nail damage +* Damage the player +* Change the camera zoom level +* Disable the in game HUD +* Make the player invisible +* Disable the lighting around the player +* Disable the vignette drawn around the player +* Change the time scale of the game +---------------------------------------------------------------------------------------- + INSTALLATION +---------------------------------------------------------------------------------------- +##(STEAM, WINDOWS) +1) Download the modding API from here: https://cdn.discordapp.com/attachments/298798821402607618/797126249457385482/Assembly-CSharp.dll +2) Right click Hollow Knight in Steam -> Properties -> Local Files -> Browse Local Files +3) Create a backup of the game files located here +4) Copy the contents of the modding API zip into this folder (Overwrite files when asked) +5) Copy the contents of this zip into the folder (Overwrite files when asked) +6) This mod should not affect saves negatively, but it is a good idea to back them up anyway. + Saves are located at %AppData%\..\LocalLow\Team Cherry\Hollow Knight\ + +## How to build (for devs): +1) Make a folder `Source/References/`, then +2) add `Assembly-CSharp.dll` (with modding-api), and `PlayMaker.dll`, `UnityEngine.dll` and `UnityEngine.UI.dll` from your `Hollow Knight/hollow_knight_Data/Managed/`-folder +---------------------------------------------------------------------------------------- + CREDITS +---------------------------------------------------------------------------------------- +Coding - Seresharp +SaveStates/Current Patch - 56, Yurihaia, Krythom +UI design and graphics - The Embraced One +Assistance with canvas - Katie + +---------------------------------------------------------------------------------------- + SAVESTATE BASICS +---------------------------------------------------------------------------------------- +*All savestates are loaded in RAM. If this causes performance issues for you, please report it.* + +To use numpad for slot select; after installing debugmod, start and stop the game, +then go to the Hollow Knight saves-directory and open the `DebugMod.GlobalSettings` json-file. +In that file find `"NumPadForSaveStates"`, and change the corresponding value from 0 to 1. + +Savestates files are located in `%APPDATA%\..\LocalLow\Team Cherry\Hollow Knight\Savestates-1221\`. They use the name format `savestate.json`. +After saving a savestate to file, you can edit the name of that savestate. To do this, open the file in any text-editor, and the first variable/line should be something like `"saveStateIdentifier": "",`. Change `` in the second pair of `"`-s to whatever you want that savestate named in the select savestate in-game menu. + +## Quickslot: +The main savestate used. Not saved permanently. + +## Quickslot save to file +Specifies slot number, then saves the current Quickslot from temporary memory to a numbered json-file in the game save directory, overwriting any files with identical number as the selected one. + +## Load file to quickslot +Asks to specify slot number, then reads the json-file with that number from the game save directory and loads it into the Quickslot, overwriting any current savestate there. + +## Save new state to file +Specifies slot number, then makes a new savestate and saves to a json-file with the given slot number. + +## Load new state from file +Specifies slot number, then loads savestate from that file directly. + +---------------------------------------------------------------------------------------- + Known Issues +---------------------------------------------------------------------------------------- +## Savestates: +* Charm effect lingering after loading a different savestate +* UI not refreshing properly to remove obsolete vessel fragments +* Soul meter stuck at full if in that state before loading +* Softlocks if loading savestate during dream transitions \ No newline at end of file diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index de028cd..d466226 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -158,37 +158,37 @@ public static void TimescaleUp() #region SaveStates - [BindableMethod(name = "Make Savestate", category = "Savestates")] + [BindableMethod(name = "Quickslot (save)", category = "Savestates")] public static void SaveState() { DebugMod.saveStateManager.SaveState(SaveStateType.Memory); } - [BindableMethod(name = "Load SaveState", category = "Savestates")] + [BindableMethod(name = "Quickslot (load)", category = "Savestates")] public static void LoadState() { DebugMod.saveStateManager.LoadState(SaveStateType.Memory); } - [BindableMethod(name = "Save current to file", category = "Savestates")] + [BindableMethod(name = "Quickslot save to file", category = "Savestates")] public static void CurrentSaveStateToFile() { DebugMod.saveStateManager.SaveState(SaveStateType.File); } - [BindableMethod(name = "Load file to current", category = "Savestates")] + [BindableMethod(name = "Load file to quickslot", category = "Savestates")] public static void CurrentSlotToSaveMemory() { DebugMod.saveStateManager.LoadState(SaveStateType.File); } - [BindableMethod(name = "Make Savestate (file)", category = "Savestates")] + [BindableMethod(name = "Save new state to file", category = "Savestates")] public static void NewSaveStateToFile() { DebugMod.saveStateManager.SaveState(SaveStateType.SkipOne); } - [BindableMethod(name = "Load Savestate (file)", category = "Savestates")] + [BindableMethod(name = "Load new state from file", category = "Savestates")] public static void LoadFromFile() { DebugMod.saveStateManager.LoadState(SaveStateType.SkipOne); @@ -306,10 +306,10 @@ public static void HideHero() public static void ToggleAllPanels() { bool active = !( - DebugMod.settings.HelpPanelVisible || - DebugMod.settings.InfoPanelVisible || - DebugMod.settings.EnemiesPanelVisible || - DebugMod.settings.TopMenuVisible || + DebugMod.settings.HelpPanelVisible || + DebugMod.settings.InfoPanelVisible || + DebugMod.settings.EnemiesPanelVisible || + DebugMod.settings.TopMenuVisible || DebugMod.settings.ConsoleVisible || DebugMod.settings.MinInfoPanelVisible || DebugMod.settings.SaveStatePanelVisible @@ -387,7 +387,6 @@ public static void ToggleSaveStatesPanel() } // A variant of info panel. View handled in the two InfoPanel classes - // Probably some race-condition potential here :) [BindableMethod(name = "Alt. Info Switch", category = "Mod UI")] public static void ToggleFullInfo() { @@ -398,7 +397,7 @@ public static void ToggleFullInfo() #region Enemies - [BindableMethod(name = "Toggle Hitboxes", category = "Enemy Panel")] + [BindableMethod(name = "Toggle Hitboxes (enemy panel)", category = "Enemy Panel")] public static void ToggleEnemyCollision() { EnemiesPanel.hitboxes = !EnemiesPanel.hitboxes; @@ -974,6 +973,12 @@ public static void IncreaseQuakeLevel() #endregion #region Bosses + /* + [BindableMethod(name = "Force Uumuu extra attack", category = "Bosses")] + public static void ForceUumuuExtra() { + BossHandler.UumuuExtra(); + } + */ [BindableMethod(name = "Respawn Ghost", category = "Bosses")] public static void RespawnGhost() @@ -1272,7 +1277,6 @@ public static void AddDGPosition() #endregion - #region ExportData [BindableMethod(name = "SceneData to file", category = "ExportData")] diff --git a/Source/BossHandler.cs b/Source/BossHandler.cs index 9e3a09a..721d50f 100644 --- a/Source/BossHandler.cs +++ b/Source/BossHandler.cs @@ -124,5 +124,29 @@ public static void RespawnGhost() Console.AddLine("No ghost in this scene to respawn"); } } + + public static void UumuuExtra() + { + if (DebugMod.GetSceneName() == "Fungus3_archive_02") + { + PlayMakerFSM[] components = GameObject.Find("Mega Jellyfish").GetComponents(); + + if (components != null) + { + foreach (PlayMakerFSM playMakerFSM in components) + { + //if (playMakerFSM.) + { + playMakerFSM.FsmVariables.GetFsmBool("Activated").Value = false; + Console.AddLine("Boss control for this scene was reset, re-enter scene or warp"); + } + } + } + else + { + Console.AddLine("GO does not exist or no FSM on it"); + } + } + } } } diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index a9ff252..a107007 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -85,6 +85,8 @@ public override void Initialize() instance.Log("First run detected, setting default binds"); settings.FirstRun = false; + settings.MinInfoPanelVisible = false; + settings.SaveStatePanelVisible = false; settings.NumPadForSaveStates = false; settings.binds.Clear(); @@ -93,14 +95,14 @@ public override void Initialize() settings.binds.Add("Toggle Top Menu", (int)KeyCode.F3); settings.binds.Add("Toggle Console", (int)KeyCode.F4); settings.binds.Add("Toggle Binds", (int)KeyCode.F5); - settings.binds.Add("Full/Min Info Switch", (int)KeyCode.F6); + settings.binds.Add("Alt. Info Switch", (int)KeyCode.F6); //settings.binds.Add("Hazard Respawn", (int)KeyCode.F6); //settings.binds.Add("Set Respawn", (int)KeyCode.F7); settings.binds.Add("Force Camera Follow", (int)KeyCode.F8); settings.binds.Add("Toggle Enemy Panel", (int)KeyCode.F9); - settings.binds.Add("Self Damage", (int)KeyCode.F10); - settings.binds.Add("Nail Damage +4", (int)KeyCode.Equals); - settings.binds.Add("Nail Damage -4", (int)KeyCode.Minus); + //settings.binds.Add("Self Damage", (int)KeyCode.F10); + //settings.binds.Add("Nail Damage +4", (int)KeyCode.Equals); + //settings.binds.Add("Nail Damage -4", (int)KeyCode.Minus); settings.binds.Add("Increase Timescale", (int)KeyCode.KeypadPlus); settings.binds.Add("Decrease Timescale", (int)KeyCode.KeypadMinus); settings.binds.Add("Toggle Hero Light", (int)KeyCode.Home); @@ -162,7 +164,7 @@ public override void Initialize() public override string GetVersion() { - return "1.4.0"; + return "1.4.0-wip"; } public override bool IsCurrent() diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index 3965911..b9bb89b 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -15,6 +15,8 @@ public enum SaveStateType { SkipOne } + // TODO: Fix vessel count between savestates + /// /// Handles organisation of SaveState-s /// quickState replicating legacy behaviour of only stored in RAM. @@ -25,7 +27,7 @@ public enum SaveStateType { /// internal class SaveStateManager { - public const int maxSaveStates = 5; + public static int maxSaveStates = DebugMod.settings.MaxSaveStates; public static SaveState quickState; public static bool inSelectSlotState = false; diff --git a/Source/Settings.cs b/Source/Settings.cs index 7bfe3c8..94e796d 100644 --- a/Source/Settings.cs +++ b/Source/Settings.cs @@ -69,5 +69,11 @@ public int ShowHitBoxes get => GetInt(); set => SetInt(value); } + + public int MaxSaveStates + { + get => GetInt(6); + set => SetInt(value); + } } } From a909d255beaabb9957c0f25a932c96566e749fd3 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Fri, 26 Feb 2021 06:10:20 +0100 Subject: [PATCH 20/91] Fixed max slot number and added def value 6 to first run settings --- README.md | 2 ++ Source/DebugMod.cs | 1 + Source/Settings.cs | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d4aa62f..12f8247 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,8 @@ To use numpad for slot select; after installing debugmod, start and stop the gam then go to the Hollow Knight saves-directory and open the `DebugMod.GlobalSettings` json-file. In that file find `"NumPadForSaveStates"`, and change the corresponding value from 0 to 1. +To change the amount of available Savestate-slots (default: 6), find `MaxSaveStates` and set the corresponding value between 0 and 10 respective of how many slots you want. + Savestates files are located in `%APPDATA%\..\LocalLow\Team Cherry\Hollow Knight\Savestates-1221\`. They use the name format `savestate.json`. After saving a savestate to file, you can edit the name of that savestate. To do this, open the file in any text-editor, and the first variable/line should be something like `"saveStateIdentifier": "",`. Change `` in the second pair of `"`-s to whatever you want that savestate named in the select savestate in-game menu. diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index a107007..c4885c5 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -88,6 +88,7 @@ public override void Initialize() settings.MinInfoPanelVisible = false; settings.SaveStatePanelVisible = false; settings.NumPadForSaveStates = false; + settings.MaxSaveStates = 6; settings.binds.Clear(); settings.binds.Add("Toggle All UI", (int)KeyCode.F1); diff --git a/Source/Settings.cs b/Source/Settings.cs index 94e796d..72b37c7 100644 --- a/Source/Settings.cs +++ b/Source/Settings.cs @@ -72,7 +72,7 @@ public int ShowHitBoxes public int MaxSaveStates { - get => GetInt(6); + get => GetInt(); set => SetInt(value); } } From b38e6fb289fbacaa6e84cafd8da89e81cdbdf7ec Mon Sep 17 00:00:00 2001 From: cerpintext Date: Tue, 2 Mar 2021 18:19:31 +0100 Subject: [PATCH 21/91] README and reverted 56's fast savestate Commented out some in-game log lines Instructions on using savestate system Wrote down a few known issues --- README.md | 42 ++++++++++++++++++++++++++---------------- Source/SaveState.cs | 13 +++++++++++-- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 12f8247..3665542 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ -Original mod by KeinZantezuken. Remaking using canvas instead of imgui and the modding framework created by myself and MyEyes/Firzen. - ---------------------------------------------------------------------------------------- FEATURES ---------------------------------------------------------------------------------------- -* A completely new toggleable UI in game that provides the following functions: +* A toggleable UI in-game that provides the following functions: * Cheats such as invincibility and noclip * The ability to unlock all charms or repair broken ones * Change which skills the player has @@ -29,9 +27,13 @@ Original mod by KeinZantezuken. Remaking using canvas instead of imgui and the m ---------------------------------------------------------------------------------------- INSTALLATION ---------------------------------------------------------------------------------------- -##(STEAM, WINDOWS) -1) Download the modding API from here: https://cdn.discordapp.com/attachments/298798821402607618/797126249457385482/Assembly-CSharp.dll + +## (STEAM/GOG, WINDOWS) +1) Download the modding API for Hollow Knight 1.2.2.1 + At the time of writing, 1.2.2.1-40 is the most up-to-date release: https://cdn.discordapp.com/attachments/298798821402607618/815053620307034182/ModdingAPI.zip 2) Right click Hollow Knight in Steam -> Properties -> Local Files -> Browse Local Files + OR + In GOG galaxy 2 -> Click button to the right of Update -> Manage Installation -> Show Folder 3) Create a backup of the game files located here 4) Copy the contents of the modding API zip into this folder (Overwrite files when asked) 5) Copy the contents of this zip into the folder (Overwrite files when asked) @@ -41,18 +43,11 @@ Original mod by KeinZantezuken. Remaking using canvas instead of imgui and the m ## How to build (for devs): 1) Make a folder `Source/References/`, then 2) add `Assembly-CSharp.dll` (with modding-api), and `PlayMaker.dll`, `UnityEngine.dll` and `UnityEngine.UI.dll` from your `Hollow Knight/hollow_knight_Data/Managed/`-folder ----------------------------------------------------------------------------------------- - CREDITS ----------------------------------------------------------------------------------------- -Coding - Seresharp -SaveStates/Current Patch - 56, Yurihaia, Krythom -UI design and graphics - The Embraced One -Assistance with canvas - Katie ---------------------------------------------------------------------------------------- SAVESTATE BASICS ---------------------------------------------------------------------------------------- -*All savestates are loaded in RAM. If this causes performance issues for you, please report it.* +*If you have performance issues, please report it.* To use numpad for slot select; after installing debugmod, start and stop the game, then go to the Hollow Knight saves-directory and open the `DebugMod.GlobalSettings` json-file. @@ -64,7 +59,7 @@ Savestates files are located in `%APPDATA%\..\LocalLow\Team Cherry\Hollow Knight After saving a savestate to file, you can edit the name of that savestate. To do this, open the file in any text-editor, and the first variable/line should be something like `"saveStateIdentifier": "",`. Change `` in the second pair of `"`-s to whatever you want that savestate named in the select savestate in-game menu. ## Quickslot: -The main savestate used. Not saved permanently. +The main savestate used. Not saved permanently, cleared when the game restarts. ## Quickslot save to file Specifies slot number, then saves the current Quickslot from temporary memory to a numbered json-file in the game save directory, overwriting any files with identical number as the selected one. @@ -82,7 +77,22 @@ Specifies slot number, then loads savestate from that file directly. Known Issues ---------------------------------------------------------------------------------------- ## Savestates: -* Charm effect lingering after loading a different savestate +* Charm effects not updating properly after loading savestates * UI not refreshing properly to remove obsolete vessel fragments * Soul meter stuck at full if in that state before loading -* Softlocks if loading savestate during dream transitions \ No newline at end of file +* Softlocks if loading savestate during dream transitions +* If loading savestate during transition visual glitch. Either press 'esc' twice to get control of the knight and walk through a transition if this happens, or quit to menu and load back in before loading the savestate +* (All savestates are loaded in RAM, which means fast loading from savestates fetched from files BUT potentially general performance issues) + +---------------------------------------------------------------------------------------- + CREDITS +---------------------------------------------------------------------------------------- +Seresharp +56 +Yurihaia +Krythom +The Embraced One +Katie +KeinZantezuken +MyEyes/Firzen +Cerpintext \ No newline at end of file diff --git a/Source/SaveState.cs b/Source/SaveState.cs index c4a43c3..5c17952 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -171,7 +171,15 @@ public void LoadStateFromFile(int paramSlot) private IEnumerator LoadStateCoro() { - Console.AddLine("LoadStateCoro line1: " + data.savedPd.hazardRespawnLocation.ToString()); + /* + string scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; + + if (data.saveScene == scene) + { + yield return UnityEngine.SceneManagement.SceneManager.UnloadScene(scene); + } + */ + //Console.AddLine("LoadStateCoro line1: " + data.savedPd.hazardRespawnLocation.ToString()); data.cameraLockArea = (data.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); GameManager.instance.ChangeToScene("Room_Sly_Storeroom", "", 0f); while (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != "Room_Sly_Storeroom") @@ -181,7 +189,7 @@ private IEnumerator LoadStateCoro() GameManager.instance.sceneData = (SceneData.instance = JsonUtility.FromJson(JsonUtility.ToJson(data.savedSd))); //if (!BindableFunctions.preserveThroughStates) //{ - Console.AddLine("Before ResetSemiPersistentItems(): " + data.savedPd.hazardRespawnLocation.ToString()); + //Console.AddLine("Before ResetSemiPersistentItems(): " + data.savedPd.hazardRespawnLocation.ToString()); GameManager.instance.ResetSemiPersistentItems(); //} yield return null; @@ -210,6 +218,7 @@ private IEnumerator LoadStateCoro() HeroController.instance.AddMPChargeSpa(1); } HeroController.instance.TakeMP(1); + yield return null; HeroController.instance.AddMPChargeSpa(1); } else From 7d43826a91e9f2cf8ff2534ba16db96061141af9 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Tue, 2 Mar 2021 19:01:21 +0100 Subject: [PATCH 22/91] Relative path in proj for game files --- Source/DebugMod.csproj | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index bc217d8..40b2155 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -41,6 +41,7 @@ bin\Windows\AnyCPU\Release\DebugMod.xml PLATFORM_WINDOWS prompt + default 4 false @@ -53,27 +54,26 @@ False - ..\..\Steam\steamapps\common\Hollow Knight\hollow_knight_Data\Managed\Assembly-CSharp.dll + .\References\Assembly-CSharp.dll False - ..\..\Steam\steamapps\common\Hollow Knight\hollow_knight_Data\Managed\PlayMaker.dll + .\References\PlayMaker.dll - ..\..\Steam\steamapps\common\Hollow Knight\hollow_knight_Data\Managed\UnityEngine.dll + .\References\UnityEngine.dll - ..\..\Steam\steamapps\common\Hollow Knight\hollow_knight_Data\Managed\UnityEngine.UI.dll + .\References\UnityEngine.UI.dll - @@ -176,7 +176,8 @@ <_PostBuildHookHostPlatform>$(Platform) - XCOPY "$(TargetDir)DebugMod.dll" "D:\GOG Galaxy\Games\Hollow Knight\hollow_knight_Data\Managed\Mods\" /y + + From d2c6d414730a8fe44ab0a71be1e6ae1306247705 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Tue, 2 Mar 2021 19:25:59 +0100 Subject: [PATCH 23/91] Added boundary check on file reading --- Source/SaveStateManager.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index b9bb89b..fab85e6 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -242,11 +242,16 @@ public static Dictionary GetSaveStatesInfo() Dictionary returnData = new Dictionary(); if (HasFiles()) { + int total = 0; foreach (KeyValuePair stateData in saveStateFiles) { - if (stateData.Value.IsSet()) + if (stateData.Value.IsSet() + && stateData.Key < DebugMod.settings.MaxSaveStates + && stateData.Key >= 0 + && total < DebugMod.settings.MaxSaveStates) { returnData.Add(stateData.Key, stateData.Value.GetSaveStateInfo()); + ++total; } } } From 2bdc05392c855ea0a061685501ae6b013b654d63 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Wed, 3 Mar 2021 00:34:04 +0100 Subject: [PATCH 24/91] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3665542..587e3d5 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ 2) add `Assembly-CSharp.dll` (with modding-api), and `PlayMaker.dll`, `UnityEngine.dll` and `UnityEngine.UI.dll` from your `Hollow Knight/hollow_knight_Data/Managed/`-folder ---------------------------------------------------------------------------------------- - SAVESTATE BASICS + # SAVESTATE BASICS ---------------------------------------------------------------------------------------- *If you have performance issues, please report it.* @@ -56,7 +56,7 @@ In that file find `"NumPadForSaveStates"`, and change the corresponding value fr To change the amount of available Savestate-slots (default: 6), find `MaxSaveStates` and set the corresponding value between 0 and 10 respective of how many slots you want. Savestates files are located in `%APPDATA%\..\LocalLow\Team Cherry\Hollow Knight\Savestates-1221\`. They use the name format `savestate.json`. -After saving a savestate to file, you can edit the name of that savestate. To do this, open the file in any text-editor, and the first variable/line should be something like `"saveStateIdentifier": "",`. Change `` in the second pair of `"`-s to whatever you want that savestate named in the select savestate in-game menu. +After saving a savestate to file, you can edit the name of that savestate. To do this, open the file in any text-editor, and the first variable/line should be something like `"saveStateIdentifier": "",`. Change `` inside the pair of `"`-s to whatever you want that savestate named in the select savestate in-game menu. ## Quickslot: The main savestate used. Not saved permanently, cleared when the game restarts. @@ -95,4 +95,4 @@ The Embraced One Katie KeinZantezuken MyEyes/Firzen -Cerpintext \ No newline at end of file +Cerpintext From 9ac89b958f8c02235c85b59f64fff5367ca728c1 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Wed, 3 Mar 2021 00:34:25 +0100 Subject: [PATCH 25/91] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 587e3d5..8729a58 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ 2) add `Assembly-CSharp.dll` (with modding-api), and `PlayMaker.dll`, `UnityEngine.dll` and `UnityEngine.UI.dll` from your `Hollow Knight/hollow_knight_Data/Managed/`-folder ---------------------------------------------------------------------------------------- - # SAVESTATE BASICS + SAVESTATE BASICS ---------------------------------------------------------------------------------------- *If you have performance issues, please report it.* From e7e400b7b9b7c8baaabb23f4789e7bf7562d2c08 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Wed, 3 Mar 2021 00:41:18 +0100 Subject: [PATCH 26/91] Added ugly #header in readme for linking --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 8729a58..b7feb27 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,9 @@ ---------------------------------------------------------------------------------------- SAVESTATE BASICS ---------------------------------------------------------------------------------------- + +## Savestates + *If you have performance issues, please report it.* To use numpad for slot select; after installing debugmod, start and stop the game, From b5b0dd07a1b2aacb99aced50cf83aa5451f5ddc5 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Wed, 3 Mar 2021 00:43:14 +0100 Subject: [PATCH 27/91] version number --- Source/DebugMod.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index c4885c5..1c7d685 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -165,7 +165,7 @@ public override void Initialize() public override string GetVersion() { - return "1.4.0-wip"; + return "1.4.0"; } public override bool IsCurrent() From 8b88232bafb6fe7387125a1dcf4ebcedb658e0aa Mon Sep 17 00:00:00 2001 From: cerpintext Date: Sat, 6 Mar 2021 08:05:18 +0100 Subject: [PATCH 28/91] Readme api link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b7feb27..85b906e 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ ## (STEAM/GOG, WINDOWS) 1) Download the modding API for Hollow Knight 1.2.2.1 - At the time of writing, 1.2.2.1-40 is the most up-to-date release: https://cdn.discordapp.com/attachments/298798821402607618/815053620307034182/ModdingAPI.zip + At the time of writing, 1.2.2.1-41 is the most up-to-date release: https://cdn.discordapp.com/attachments/298798821402607618/817653175586783242/Assembly-CSharp.dll 2) Right click Hollow Knight in Steam -> Properties -> Local Files -> Browse Local Files OR In GOG galaxy 2 -> Click button to the right of Update -> Manage Installation -> Show Folder From f39a4c1b49aa97e2bec1adef178d7b834d20a6ce Mon Sep 17 00:00:00 2001 From: cerpintext Date: Tue, 23 Mar 2021 23:12:44 +0100 Subject: [PATCH 29/91] various smol messy stuffs --- Source/BindableFunctions.cs | 10 ++-- Source/BossHandler.cs | 97 +++++++++++++++++++++++++++++++++++-- Source/DebugMod.cs | 2 +- Source/DebugMod.csproj | 3 ++ Source/EnemyData.cs | 2 +- Source/GUIController.cs | 3 +- Source/HitboxViewer.cs | 65 +++++++++++++------------ Source/SaveStateManager.cs | 5 +- 8 files changed, 145 insertions(+), 42 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index d466226..cd55a7f 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -194,12 +194,14 @@ public static void LoadFromFile() DebugMod.saveStateManager.LoadState(SaveStateType.SkipOne); } + /* [BindableMethod(name = "Toggle auto slot", category = "Savestates")] public static void ToggleAutoSlot() { DebugMod.saveStateManager.ToggleAutoSlot(); } - + */ + [BindableMethod(name = "Refresh state menu", category = "Savestates")] public static void RefreshSaveStates() { @@ -973,12 +975,12 @@ public static void IncreaseQuakeLevel() #endregion #region Bosses - /* + [BindableMethod(name = "Force Uumuu extra attack", category = "Bosses")] - public static void ForceUumuuExtra() { + public static void ForceUumuuExtra() + { BossHandler.UumuuExtra(); } - */ [BindableMethod(name = "Respawn Ghost", category = "Bosses")] public static void RespawnGhost() diff --git a/Source/BossHandler.cs b/Source/BossHandler.cs index 721d50f..2afb73c 100644 --- a/Source/BossHandler.cs +++ b/Source/BossHandler.cs @@ -1,16 +1,23 @@ -using System.Collections.Generic; +using System.Collections; +using System.Collections.Generic; +using System.Linq; using UnityEngine; +using UnityEngine.SceneManagement; +using HutongGames.PlayMaker; +using HutongGames.PlayMaker.Actions; +using Vasi; namespace DebugMod { public static class BossHandler { - public static bool bossSub; - public static Dictionary> bossData; public static Dictionary ghostData; public static bool bossFound; public static bool ghostFound; + + private static bool fsmToggle = false; + private static NonBouncer _coro; public static void LookForBoss(string sceneName) { @@ -127,6 +134,28 @@ public static void RespawnGhost() public static void UumuuExtra() { + if (!fsmToggle) + { + var go = new GameObject(); + _coro = go.AddComponent(); + //GameManager.instance. + Object.DontDestroyOnLoad(_coro); + + Console.AddLine(_coro.ToString()); + + UnityEngine.SceneManagement.SceneManager.sceneLoaded += StartUumuuCoro; + fsmToggle = true; + + } + else + { + Object.Destroy(_coro); + UnityEngine.SceneManagement.SceneManager.sceneLoaded -= StartUumuuCoro; + fsmToggle = false; + Console.AddLine("Uumuu forced extra attack OFF"); + } + + /* if (DebugMod.GetSceneName() == "Fungus3_archive_02") { PlayMakerFSM[] components = GameObject.Find("Mega Jellyfish").GetComponents(); @@ -147,6 +176,68 @@ public static void UumuuExtra() Console.AddLine("GO does not exist or no FSM on it"); } } + */ + } + + private static void StartUumuuCoro(Scene scene, LoadSceneMode lsm) + { + //Console.AddLine("Uumuu test: " + scene.name); + if (scene.name == "Fungus3_archive_02") + { + Console.AddLine(_coro.ToString()); + _coro.StartCoroutine(UumuuExtraCoro()); + } + } + + private static IEnumerator UumuuExtraCoro() + { + yield return null; + Console.AddLine("Uumuu coro check"); + // Find Uumuu and the FSM + GameObject uumuu = GameObject.Find("Mega Jellyfish"); + Console.AddLine("Uumuu coro mid pls work"); + if (uumuu == null) + yield break; + Console.AddLine("aaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + PlayMakerFSM fsm = uumuu.LocateMyFSM("Mega Jellyfish"); + + fsm.GetState("Idle").GetAction().timeMax = 1.2f;; + + + // Fix the waits and the number of attacks + + + //fsm.GetState("Idle").GetAction().timeMax = 1.5f; + //fsm.GetState("Set Timer").GetAction().max = 2f; + //fsm.FsmVariables.GetFsmFloat("Quirrel Time").Value = 4f; + + // Fix the pattern to 2 quick, then 1 long if it still needs to attack + //FsmState choice = fsm.GetState("Choice"); + //choice.RemoveAction(); + //choice.AddMethod(() => SetUumuuPattern(fsm)); + + // Reset the multizap counter to 0 so the pattern remains 2 quick 1 optional long + //fsm.GetState("Recover").AddMethod(() => fsm.FsmVariables.GetFsmInt("Ct Multizap").Value = 0); + + // Set the initial RecoilSpeed to 0 so that dream nailing her on the first cycle doesn't push her + //uumuu.GetComponent().SetRecoilSpeed(0); + + // Set her HP to 1028 value + //uumuu.GetComponent().hp = 250; + + } + + private static void SetUumuuPattern(PlayMakerFSM fsm) + { + if (fsm.FsmVariables.GetFsmInt("Ct Multizap").Value < 2) + { + fsm.Fsm.Event(fsm.FsmEvents.First(e => e.Name == "MULTIZAP")); + fsm.FsmVariables.GetFsmInt("Ct Multizap").Value++; + } + else + { + fsm.Fsm.Event(fsm.FsmEvents.First(e => e.Name == "CHASE")); + } } } } diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 1c7d685..48fee7e 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -165,7 +165,7 @@ public override void Initialize() public override string GetVersion() { - return "1.4.0"; + return "1.4.1-a"; } public override bool IsCurrent() diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 40b2155..8c70fb5 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -69,6 +69,9 @@ .\References\UnityEngine.UI.dll + + References\Vasi.dll + diff --git a/Source/EnemyData.cs b/Source/EnemyData.cs index 636f9e5..39a908b 100644 --- a/Source/EnemyData.cs +++ b/Source/EnemyData.cs @@ -15,7 +15,7 @@ public struct EnemyData public EnemyData(int hp, PlayMakerFSM fsm, Component spr, GameObject parent = null, GameObject go = null) { HP = hp; - maxHP = hp; + maxHP = hp; // max hp is just curr hp on panel init FSM = fsm; Spr = spr; gameObject = go; diff --git a/Source/GUIController.cs b/Source/GUIController.cs index 5cf26fb..85dc5f5 100644 --- a/Source/GUIController.cs +++ b/Source/GUIController.cs @@ -133,8 +133,9 @@ public void Update() { foreach (KeyCode kc in Enum.GetValues(typeof(KeyCode))) { - if (Input.GetKeyDown(kc)) + if (Input.GetKeyDown(kc) && kc != KeyCode.Mouse0) { + // Fix UX if (KeyBindPanel.keyWarning != kc) { foreach (KeyValuePair kvp in DebugMod.settings.binds) diff --git a/Source/HitboxViewer.cs b/Source/HitboxViewer.cs index dba6570..891c495 100644 --- a/Source/HitboxViewer.cs +++ b/Source/HitboxViewer.cs @@ -105,46 +105,49 @@ private void SpawnHitboxes() continue; } - if (col.gameObject.layer == (int)PhysLayers.TERRAIN) - { - lines.Add(col, SetupLineRenderer(col, null, greenMat)); - } - else if (col.GetComponent()) - { - lines.Add(col, SetupLineRenderer(col, null, blueMat)); - } - else if (col.GetComponent() || col.gameObject.LocateMyFSM("damages_hero") != null) - { - colliders.Add(col); - lines.Add(col, SetupLineRenderer(col, null, redMat)); - } - else if (col.gameObject == HeroController.instance.gameObject && !col.isTrigger) - { - colliders.Add(col); - lines.Add(col, SetupLineRenderer(col, null, yellowMat)); - } - else if (col.GetComponent()) - { - NonBouncer bounce = col.GetComponent(); - if (bounce == null || !bounce.active) - { - colliders.Add(col); - lines.Add(col, SetupLineRenderer(col, null, blueMat)); - } - } - + if (State == 2) + { /* State 2 */ - else if (State == 2 && col.isTrigger && col.gameObject.GetComponent() != null) + if (col.isTrigger && col.gameObject.GetComponent() != null) { colliders.Add(col); lines.Add(col, this.SetupLineRenderer(col, null, blueMat)); } - else if (State == 2 && col.isTrigger && col.gameObject.GetComponent() == null) + else if (col.isTrigger && col.gameObject.GetComponent() == null) { this.colliders.Add(col); this.lines.Add(col, this.SetupLineRenderer(col, null, yellowMat)); } - + } + + if (col.gameObject.layer == (int)PhysLayers.TERRAIN) + { + lines.Add(col, SetupLineRenderer(col, null, greenMat)); + } + else if (col.GetComponent()) + { + lines.Add(col, SetupLineRenderer(col, null, blueMat)); + } + else if (col.GetComponent() || col.gameObject.LocateMyFSM("damages_hero") != null) + { + colliders.Add(col); + lines.Add(col, SetupLineRenderer(col, null, redMat)); + } + else if (col.gameObject == HeroController.instance.gameObject && !col.isTrigger) + { + colliders.Add(col); + lines.Add(col, SetupLineRenderer(col, null, yellowMat)); + } + else if (col.GetComponent()) + { + NonBouncer bounce = col.GetComponent(); + if (bounce == null || !bounce.active) + { + colliders.Add(col); + lines.Add(col, SetupLineRenderer(col, null, blueMat)); + } + } + } } diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index fab85e6..e60488e 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -68,6 +68,7 @@ internal SaveStateManager() #region saving public void SaveState(SaveStateType stateType) { + RefreshStateMenu(); switch (stateType) { case SaveStateType.Memory: @@ -86,6 +87,7 @@ public void SaveState(SaveStateType stateType) public void LoadState(SaveStateType stateType) { + RefreshStateMenu(); switch (stateType) { case SaveStateType.Memory: @@ -267,7 +269,8 @@ public void RefreshStateMenu() string[] files = Directory.GetFiles(path); DebugMod.instance.Log( "path var: " + path + - "\nSavestates: " + files.ToString()); + "\nSavestates: " + files.ToString() + ); foreach (string file in files) { From ec6f0dea91816dbf68a33aefe684a21b7b3ed7d3 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Wed, 24 Mar 2021 08:22:36 +0100 Subject: [PATCH 30/91] SceneIndex to file helper func --- Source/BindableFunctions.cs | 26 ++++++++++++++++++++++++++ Source/SaveState.cs | 34 +++++++++++++++++++--------------- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index cd55a7f..245f311 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -1,10 +1,12 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using System.IO; using UnityEngine; using GlobalEnums; using HutongGames.PlayMaker; +using UnityEngine.SceneManagement; namespace DebugMod { @@ -1318,6 +1320,30 @@ public static void FSMsToFile() } */ + + [BindableMethod(name = "AllScenesByIndex to file (SLOW)", category = "ExportData")] + public static void SceneIndexesToFile() + { + Console.AddLine("sceneCountInBuildSettings: " + UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings); + Console.AddLine("sceneCount: " + UnityEngine.SceneManagement.SceneManager.sceneCount); + + Dictionary sceneIndexList = new Dictionary(); + Scene tmp; + int curr = UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex; + + for (int i = 0; i < UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings; i++) + { + if (curr != i) UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(i); + tmp = UnityEngine.SceneManagement.SceneManager.GetSceneAt(i); + sceneIndexList.Add(tmp.buildIndex, tmp.name); + //Console.AddLine(tmp.name + " == " + tmp.buildIndex); + if (curr != i) UnityEngine.SceneManagement.SceneManager.UnloadScene(i); + } + + File.WriteAllLines(string.Concat(new object[] {Application.persistentDataPath, "/SceneIndexList.txt"}), + sceneIndexList.Select(x => "[" + x.Key + " -- " + x.Value + "]").ToArray() + ); + } #endregion } } diff --git a/Source/SaveState.cs b/Source/SaveState.cs index 5c17952..bc2c7b6 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Reflection; using System.Text; +using HutongGames.PlayMaker.Actions; using UnityEngine; namespace DebugMod @@ -210,22 +211,27 @@ private IEnumerator LoadStateCoro() HeroController.instance.playerData = PlayerData.instance; HeroController.instance.geoCounter.playerData = PlayerData.instance; HeroController.instance.geoCounter.TakeGeo(0); - if (PlayerData.instance.MPCharge >= 99) + if (PlayerData.instance.MPCharge >= PlayerData.instance.maxMP) { - if (PlayerData.instance.MPReserve > 0) - { - HeroController.instance.TakeReserveMP(1); - HeroController.instance.AddMPChargeSpa(1); - } - HeroController.instance.TakeMP(1); + int tmpMp = PlayerData.instance.MPCharge; + HeroController.instance.TakeMP(PlayerData.instance.MPCharge); yield return null; - HeroController.instance.AddMPChargeSpa(1); + HeroController.instance.AddMPChargeSpa(tmpMp); } - else + else { - HeroController.instance.TakeMP(1); HeroController.instance.AddMPChargeSpa(1); + yield return null; + HeroController.instance.TakeMP(1); } + if (PlayerData.instance.MPReserveMax > 0) + { + int tmpReserve = PlayerData.instance.MPReserve; + HeroController.instance.TakeReserveMP(PlayerData.instance.MPReserve); + yield return null; + HeroController.instance.AddMPChargeSpa(tmpReserve); + } + //Console.AddLine("LoadStateCoro end of func: " + data.savedPd.hazardRespawnLocation.ToString()); //HeroController.instance.SetHazardRespawn(savedPd.hazardRespawnLocation, savedPd.hazardRespawnFacingRight); HeroController.instance.proxyFSM.SendEvent("HeroCtrl-HeroDamaged"); @@ -236,7 +242,9 @@ private IEnumerator LoadStateCoro() GameCameras.instance.hudCanvas.gameObject.SetActive(true); HeroController.instance.TakeHealth(1); HeroController.instance.AddHealth(1); + GameManager.instance.inputHandler.RefreshPlayerData(); yield break; + // need to redraw UI somehow } #endregion @@ -244,11 +252,7 @@ private IEnumerator LoadStateCoro() public bool IsSet() { - bool isSet = false; - if (!String.IsNullOrEmpty(data.saveStateIdentifier)) - { - isSet = true; - } + bool isSet = !String.IsNullOrEmpty(data.saveStateIdentifier); return isSet; } From 7fbb73006bcbb73a9c4f2878285d46c76d869fc5 Mon Sep 17 00:00:00 2001 From: Mulhima <81007262+TheMulhima@users.noreply.github.com> Date: Sat, 29 May 2021 11:26:14 +0400 Subject: [PATCH 31/91] Add option in top menu to lock key binds --- Source/TopMenu.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Source/TopMenu.cs b/Source/TopMenu.cs index 6c8dabd..51c23e0 100644 --- a/Source/TopMenu.cs +++ b/Source/TopMenu.cs @@ -1,4 +1,4 @@ -using System; +using System; using UnityEngine; namespace DebugMod @@ -27,7 +27,7 @@ public static void BuildMenu(GameObject canvas) panel.AddButton("DreamGate", GUIController.Instance.images["ButtonRect"], new Vector2(546f, 68f), Vector2.zero, DreamGatePanelClicked, buttonRect, GUIController.Instance.trajanBold, "DreamGate"); //Dropdown panels - panel.AddPanel("Cheats Panel", GUIController.Instance.images["DropdownBG"], new Vector2(45f, 75f), Vector2.zero, new Rect(0, 0, GUIController.Instance.images["DropdownBG"].width, 210f)); + panel.AddPanel("Cheats Panel", GUIController.Instance.images["DropdownBG"], new Vector2(45f, 75f), Vector2.zero, new Rect(0, 0, GUIController.Instance.images["DropdownBG"].width, 240f)); panel.AddPanel("Charms Panel", GUIController.Instance.images["DropdownBG"], new Vector2(145f, 75f), Vector2.zero, new Rect(0, 0, GUIController.Instance.images["DropdownBG"].width, 240f)); panel.AddPanel("Skills Panel", GUIController.Instance.images["DropdownBG"], new Vector2(245f, 75f), Vector2.zero, new Rect(0, 0, GUIController.Instance.images["DropdownBG"].width, GUIController.Instance.images["DropdownBG"].height)); panel.AddPanel("Items Panel", GUIController.Instance.images["DropdownBG"], new Vector2(345f, 75f), Vector2.zero, new Rect(0, 0, GUIController.Instance.images["DropdownBG"].width, GUIController.Instance.images["DropdownBG"].height)); @@ -41,6 +41,7 @@ public static void BuildMenu(GameObject canvas) panel.GetPanel("Cheats Panel").AddButton("Invincibility", GUIController.Instance.images["ButtonRectEmpty"], new Vector2(5f, 120f), Vector2.zero, InvincibilityClicked, new Rect(0f, 0f, 80f, 20f), GUIController.Instance.trajanNormal, "Invincibility", 10); panel.GetPanel("Cheats Panel").AddButton("Noclip", GUIController.Instance.images["ButtonRectEmpty"], new Vector2(5f, 150f), Vector2.zero, NoclipClicked, new Rect(0f, 0f, 80f, 20f), GUIController.Instance.trajanNormal, "Noclip", 10); panel.GetPanel("Cheats Panel").AddButton("Kill Self", GUIController.Instance.images["ButtonRectEmpty"], new Vector2(5f, 180f), Vector2.zero, KillSelfClicked, new Rect(0f, 0f, 80f, 20f), GUIController.Instance.trajanNormal, "Kill Self", 10); + panel.GetPanel("Cheats Panel").AddButton("Lock KeyBinds", GUIController.Instance.images["ButtonRectEmpty"], new Vector2(5f, 210f), Vector2.zero, KeyBindLockClicked, new Rect(0f, 0f, 80f, 20f), GUIController.Instance.trajanNormal, "Lock KeyBinds", 10); //Charms panel @@ -185,6 +186,7 @@ public static void Update() panel.GetButton("Infinite HP", "Cheats Panel").SetTextColor(DebugMod.infiniteHP ? new Color(244f / 255f, 127f / 255f, 32f / 255f) : Color.white); panel.GetButton("Invincibility", "Cheats Panel").SetTextColor(PlayerData.instance.isInvincible ? new Color(244f / 255f, 127f / 255f, 32f / 255f) : Color.white); panel.GetButton("Noclip", "Cheats Panel").SetTextColor(DebugMod.noclip ? new Color(244f / 255f, 127f / 255f, 32f / 255f) : Color.white); + panel.GetButton("Lock KeyBinds", "Cheats Panel").SetTextColor(DebugMod.KeyBindLock ? new Color(244f / 255f, 127f / 255f, 32f / 255f) : Color.white); } if (panel.GetPanel("Bosses Panel").active) @@ -623,5 +625,11 @@ private static void ScrollDownClicked(string buttonName) DreamGate.scrollPosition++; } } + + private static void KeyBindLockClicked(string buttonName) + { + DebugMod.KeyBindLock = !DebugMod.KeyBindLock; + Console.AddLine((DebugMod.KeyBindLock ? "Removing" : "Adding") + "the ability to use keybinds"); + } } } From 852086d26dd02715823fc5e9f7de2dd8695d91fd Mon Sep 17 00:00:00 2001 From: Mulhima <81007262+TheMulhima@users.noreply.github.com> Date: Sat, 29 May 2021 11:28:21 +0400 Subject: [PATCH 32/91] Added new variables to implement the new changes --- Source/DebugMod.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 48fee7e..7a0ae89 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Collections.Generic; using System.Reflection; @@ -34,6 +34,8 @@ public class DebugMod : Mod, IMod private static float _loadTime; private static float _unloadTime; private static bool _loadingChar; + public static bool KeyBindLock; + public static float AmountToMove; internal static bool infiniteHP; internal static bool infiniteSoul; @@ -151,6 +153,8 @@ public override void Initialize() GUIController.Instance.BuildMenus(); Console.AddLine("New session started " + DateTime.Now); + AmountToMove = settings.AmountToMove; + KeyBindLock = false; } catch (Exception e) { DebugMod.instance.Log(String.Concat( @@ -165,7 +169,7 @@ public override void Initialize() public override string GetVersion() { - return "1.4.1-a"; + return "1.4.2"; } public override bool IsCurrent() From fc6e34c6303d22a3de4cd93ea0d4e88e4cebd0f8 Mon Sep 17 00:00:00 2001 From: Mulhima <81007262+TheMulhima@users.noreply.github.com> Date: Sat, 29 May 2021 11:29:57 +0400 Subject: [PATCH 33/91] Pressing escape unbinds keys also, implements the lock keybinds change --- Source/GUIController.cs | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/Source/GUIController.cs b/Source/GUIController.cs index 85dc5f5..35bb294 100644 --- a/Source/GUIController.cs +++ b/Source/GUIController.cs @@ -152,7 +152,15 @@ public void Update() KeyBindPanel.keyWarning = KeyCode.None; - DebugMod.settings.binds[bind.Key] = (int)kc; + //remove bind + if (kc == KeyCode.Escape) + { + DebugMod.settings.binds.Remove(bind.Key); + } + else if (kc != KeyCode.Escape) + { + DebugMod.settings.binds[bind.Key] = (int) kc; + } KeyBindPanel.UpdateHelpText(); break; } @@ -160,13 +168,29 @@ public void Update() } else if (Input.GetKeyDown((KeyCode)bind.Value)) { - try + //This makes sure atleast you can close the UI when the KeyBindLock is active. + //Im sure theres a better way to do this but idk. + if (bind.Value == DebugMod.settings.binds["Toggle All UI"]) { - ((MethodInfo)DebugMod.bindMethods[bind.Key].Second).Invoke(null, null); + try + { + ((MethodInfo)DebugMod.bindMethods[bind.Key].Second).Invoke(null, null); + } + catch (Exception e) + { + DebugMod.instance.LogError("Error running keybind method " + bind.Key + ":\n" + e.ToString()); + } } - catch (Exception e) + else if (!DebugMod.KeyBindLock) { - DebugMod.instance.LogError("Error running keybind method " + bind.Key + ":\n" + e.ToString()); + try + { + ((MethodInfo)DebugMod.bindMethods[bind.Key].Second).Invoke(null, null); + } + catch (Exception e) + { + DebugMod.instance.LogError("Error running keybind method " + bind.Key + ":\n" + e.ToString()); + } } } } @@ -320,4 +344,4 @@ public static GUIController Instance } } } -} \ No newline at end of file +} From 819017dadf7fba3d2a4a0dc76e90c5aa070af7df Mon Sep 17 00:00:00 2001 From: Mulhima <81007262+TheMulhima@users.noreply.github.com> Date: Sat, 29 May 2021 11:33:27 +0400 Subject: [PATCH 34/91] Added new functions and fixed voidheart the new functions being: 1. Reset. (it resets some settings like nailDamage, camera stuff, timescale, and cheats) 2. Move Right/Left/Up/Down by a fixed amount of units (default 0.1) --- Source/BindableFunctions.cs | 92 ++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 245f311..a203949 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -155,7 +155,45 @@ public static void TimescaleUp() Console.AddLine("Cannot set TimeScale greater than 2.0"); } } + [BindableMethod(name = "Reset", category = "Misc")] + public static void Reset() + { + var pd = PlayerData.instance; + var HC = HeroController.instance; + var GC = GameCameras.instance; + + //nail damage + pd.nailDamage = 5+ pd.nailSmithUpgrades * 4; + PlayMakerFSM.BroadcastEvent("UPDATE NAIL DAMAGE"); + //Hero Light + GameObject gameObject = DebugMod.RefKnight.transform.Find("HeroLight").gameObject; + Color color = gameObject.GetComponent().color; + color.a = 0.7f; + gameObject.GetComponent().color = color; + + //HUD + if (!GC.hudCanvas.gameObject.activeInHierarchy) + GC.hudCanvas.gameObject.SetActive(true); + + //Hide Hero + tk2dSprite component = DebugMod.RefKnight.GetComponent(); + color = component.color; color.a = 1f; + component.color = color; + + //rest all is self explanatory + Time.timeScale = 1f; + GC.tk2dCam.ZoomFactor = 1f; + HC.vignette.enabled = false; + EnemiesPanel.hitboxes = false; + EnemiesPanel.hpBars = false; + EnemiesPanel.autoUpdate = false; + pd.infiniteAirJump=false; + DebugMod.infiniteSoul = false; + DebugMod.infiniteHP = false; + pd.isInvincible=false; + DebugMod.noclip=false; + } #endregion #region SaveStates @@ -609,6 +647,7 @@ public static void GiveAllCharms() PlayerData.instance.hasCharm = true; PlayerData.instance.charmsOwned = 40; PlayerData.instance.royalCharmState = 4; + PlayerData.instance.gotShadeCharm = true; PlayerData.instance.gotKingFragment = true; PlayerData.instance.gotQueenFragment = true; PlayerData.instance.notchShroomOgres = true; @@ -641,8 +680,10 @@ public static void IncreaseKingsoulLevel() } PlayerData.instance.royalCharmState++; + + PlayerData.instance.gotShadeCharm = PlayerData.instance.royalCharmState == 4; - if (PlayerData.instance.royalCharmState >= 5) + if (PlayerData.instance.royalCharmState >= 5) { PlayerData.instance.royalCharmState = 0; } @@ -1345,5 +1386,52 @@ public static void SceneIndexesToFile() ); } #endregion + + #region MovePlayer + + [BindableMethod(name = "Move 0.1 units to the right", category = "PlayerMovement")] + public static void MoveRight() + { + var HeroPos = HeroController.instance.transform.position; + HeroController.instance.transform.position= new Vector3(HeroPos.x + DebugMod.AmountToMove, HeroPos.y); + Console.AddLine("Moved player 0.1 units to the right"); + } + [BindableMethod(name = "Move 0.1 units to the left", category = "PlayerMovement")] + public static void MoveL() + { + var HeroPos = HeroController.instance.transform.position; + HeroController.instance.transform.position = new Vector3(HeroPos.x - DebugMod.AmountToMove, HeroPos.y); + Console.AddLine("Moved player 0.1 units to the left"); + } + [BindableMethod(name = "Move 0.1 units up", category = "PlayerMovement")] + public static void MoveUp() + { + var HeroPos = HeroController.instance.transform.position; + HeroController.instance.transform.position = new Vector3(HeroPos.x, HeroPos.y + DebugMod.AmountToMove); + Console.AddLine("Moved player 0.1 units to the up"); + } + [BindableMethod(name = "Move 0.1 units down", category = "PlayerMovement")] + public static void MoveDown() + { + var HeroPos = HeroController.instance.transform.position; + HeroController.instance.transform.position = new Vector3(HeroPos.x, HeroPos.y - DebugMod.AmountToMove); + Console.AddLine("Moved player 0.1 units to the down"); + } + + [BindableMethod(name = "FaceLeft", category = "PlayerMovement")] + public static void FaceLeft() + { + HeroController.instance.FaceLeft(); + Console.AddLine("Made player face left"); + } + + [BindableMethod(name = "FaceRight", category = "PlayerMovement")] + public static void FaceRight() + { + HeroController.instance.FaceRight(); + Console.AddLine("Made player face right"); + } + + #endregion } } From e6821289804411fe2824091086c54614fe23ff67 Mon Sep 17 00:00:00 2001 From: Mulhima <81007262+TheMulhima@users.noreply.github.com> Date: Sat, 29 May 2021 11:34:57 +0400 Subject: [PATCH 35/91] Increased precision of HeroPos Also, moved the right side of lower info panel a bit to the right to accommodate for the increased decimal places --- Source/InfoPanel.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Source/InfoPanel.cs b/Source/InfoPanel.cs index b899f09..4a48747 100644 --- a/Source/InfoPanel.cs +++ b/Source/InfoPanel.cs @@ -1,4 +1,5 @@ -using UnityEngine; +using System; +using UnityEngine; using InControl; namespace DebugMod @@ -123,8 +124,8 @@ public static void BuildMenu(GameObject canvas) panel.AddText("Right1 Label", "Session Time\nLoad\nHero Pos\nMove Raw", new Vector2(1285, 747), Vector2.zero, GUIController.Instance.arial); panel.AddText("Right1", "", new Vector2(1385, 747), Vector2.zero, GUIController.Instance.trajanNormal); - panel.AddText("Right2 Label", "Move Vector\nKey Pressed\nMove Pressed\nInput X", new Vector2(1500, 747), Vector2.zero, GUIController.Instance.arial); - panel.AddText("Right2", "", new Vector2(1600, 747), Vector2.zero, GUIController.Instance.trajanNormal); + panel.AddText("Right2 Label", "Move Vector\nKey Pressed\nMove Pressed\nInput X", new Vector2(1550, 747), Vector2.zero, GUIController.Instance.arial); + panel.AddText("Right2", "", new Vector2(1650, 747), Vector2.zero, GUIController.Instance.trajanNormal); panel.FixRenderOrder(); } @@ -220,11 +221,19 @@ public static void Update() int time1 = Mathf.FloorToInt(Time.realtimeSinceStartup / 60f); int time2 = Mathf.FloorToInt(Time.realtimeSinceStartup - (float)(time1 * 60)); - panel.GetText("Right1").UpdateText(string.Format("{0:00}:{1:00}", time1, time2) + "\n" + DebugMod.GetLoadTime() + "s\n" + (Vector2)DebugMod.RefKnight.transform.position + "\n" + string.Format("L: {0} R: {1}", DebugMod.IH.inputActions.left.RawValue, DebugMod.IH.inputActions.right.RawValue)); + panel.GetText("Right1").UpdateText(string.Format("{0:00}:{1:00}", time1, time2) + "\n" + DebugMod.GetLoadTime() + "s\n" + GetHeroPos() + "\n" + string.Format("L: {0} R: {1}", DebugMod.IH.inputActions.left.RawValue, DebugMod.IH.inputActions.right.RawValue)); panel.GetText("Right2").UpdateText(DebugMod.IH.inputActions.moveVector.Vector.x + ", " + DebugMod.IH.inputActions.moveVector.Vector.y + "\n" + GetStringForBool(InputManager.AnyKeyIsPressed) + "\n" + GetStringForBool(DebugMod.IH.inputActions.left.IsPressed || DebugMod.IH.inputActions.right.IsPressed) + "\n" + DebugMod.IH.inputX); } } + private static string GetHeroPos() + { + float HeroX = (float) DebugMod.RefKnight.transform.position.x; + float HeroY = (float) DebugMod.RefKnight.transform.position.y; + + return $"({HeroX}, {HeroY})"; + } + private static string GetStringForBool(bool b) { return b ? "✓" : "X"; From 09aa506a3e5a0f905a0da7619ae424d582bd1626 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Mon, 31 May 2021 20:07:02 +0200 Subject: [PATCH 36/91] Tons of older, small things Commented out non-functional blocks Divided hitbox-viewer modes to lightly improve performance load between the two Added a "will hardfall" indicator to minInfo panel Think I fixed the issue with savestate panel not updating to new files while in-game?? --- Source/BindableFunctions.cs | 33 +++++++++- Source/HitboxViewer.cs | 119 +++++++++++++++--------------------- Source/MinimalInfoPanel.cs | 5 ++ Source/SaveStateManager.cs | 40 ++++++------ 4 files changed, 104 insertions(+), 93 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 245f311..9132ddc 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -202,13 +202,15 @@ public static void ToggleAutoSlot() { DebugMod.saveStateManager.ToggleAutoSlot(); } - */ + [BindableMethod(name = "Refresh state menu", category = "Savestates")] public static void RefreshSaveStates() { DebugMod.saveStateManager.RefreshStateMenu(); } + */ + #endregion #region Visual @@ -391,10 +393,29 @@ public static void ToggleSaveStatesPanel() } // A variant of info panel. View handled in the two InfoPanel classes + // TODO: stop not knowing how to use xor in c# [BindableMethod(name = "Alt. Info Switch", category = "Mod UI")] public static void ToggleFullInfo() { MinimalInfoPanel.minInfo = !MinimalInfoPanel.minInfo; + + if (MinimalInfoPanel.minInfo) + { + if (DebugMod.settings.InfoPanelVisible) + { + DebugMod.settings.InfoPanelVisible = false; + DebugMod.settings.MinInfoPanelVisible = true; + } + } + else + { + if (DebugMod.settings.MinInfoPanelVisible) + { + DebugMod.settings.MinInfoPanelVisible = false; + DebugMod.settings.InfoPanelVisible = true; + } + } + } #endregion @@ -978,12 +999,13 @@ public static void IncreaseQuakeLevel() #region Bosses + /* [BindableMethod(name = "Force Uumuu extra attack", category = "Bosses")] public static void ForceUumuuExtra() { BossHandler.UumuuExtra(); } - + */ [BindableMethod(name = "Respawn Ghost", category = "Bosses")] public static void RespawnGhost() { @@ -1321,7 +1343,11 @@ public static void FSMsToFile() } */ - [BindableMethod(name = "AllScenesByIndex to file (SLOW)", category = "ExportData")] + // Use some threading or coroutine lol + // commented out for being painfully unoptimised. + // if you have use for this in its current state, you know how to uncomment and compile, or to ask me for the list :p + /* + [BindableMethod(name = "AllScenesByIndex (SLOW)", category = "ExportData")] public static void SceneIndexesToFile() { Console.AddLine("sceneCountInBuildSettings: " + UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings); @@ -1344,6 +1370,7 @@ public static void SceneIndexesToFile() sceneIndexList.Select(x => "[" + x.Key + " -- " + x.Value + "]").ToArray() ); } + */ #endregion } } diff --git a/Source/HitboxViewer.cs b/Source/HitboxViewer.cs index 891c495..9e4a226 100644 --- a/Source/HitboxViewer.cs +++ b/Source/HitboxViewer.cs @@ -95,6 +95,19 @@ private void SpawnHitboxes() } } + switch (State) + { + case 1: + State1Boxes(); + break; + case 2: + State2Boxes(); + break; + } + } + + private void State1Boxes() + { colliders = new List(); lines = new Dictionary(); @@ -104,22 +117,7 @@ private void SpawnHitboxes() { continue; } - - if (State == 2) - { - /* State 2 */ - if (col.isTrigger && col.gameObject.GetComponent() != null) - { - colliders.Add(col); - lines.Add(col, this.SetupLineRenderer(col, null, blueMat)); - } - else if (col.isTrigger && col.gameObject.GetComponent() == null) - { - this.colliders.Add(col); - this.lines.Add(col, this.SetupLineRenderer(col, null, yellowMat)); - } - } - + if (col.gameObject.layer == (int)PhysLayers.TERRAIN) { lines.Add(col, SetupLineRenderer(col, null, greenMat)); @@ -147,27 +145,12 @@ private void SpawnHitboxes() lines.Add(col, SetupLineRenderer(col, null, blueMat)); } } - } - } - - private void Spawn1028Hitboxes() + } + + + private void State2Boxes() { - if (!GameManager.instance.IsGameplayScene()) - { - return; - } - - DestroyBorder(Object.FindObjectsOfType().Where(x => x.name.Contains("sceneborder"))); - - foreach (Collider2D col in lines.Keys.ToArray()) - { - if (col != null && lines[col] != null) - { - Object.Destroy(lines[col].gameObject); - } - } - colliders = new List(); lines = new Dictionary(); @@ -178,45 +161,39 @@ private void Spawn1028Hitboxes() continue; } - if (col.gameObject.layer == (int)PhysLayers.TERRAIN) - { - lines.Add(col, SetupLineRenderer(col, null, greenMat)); - } - else if (col.GetComponent()) - { - lines.Add(col, SetupLineRenderer(col, null, blueMat)); - } - else if (col.GetComponent() || col.gameObject.LocateMyFSM("damages_hero") != null) - { - colliders.Add(col); - lines.Add(col, SetupLineRenderer(col, null, redMat)); - } - else if (col.gameObject == HeroController.instance.gameObject && !col.isTrigger) - { - colliders.Add(col); - lines.Add(col, SetupLineRenderer(col, null, yellowMat)); - } - else if (col.GetComponent()) - { - NonBouncer bounce = col.GetComponent(); - if (bounce == null || !bounce.active) - { - colliders.Add(col); - lines.Add(col, SetupLineRenderer(col, null, blueMat)); - } - } - - /* State 2 */ - else if (State == 2 && col.isTrigger && col.gameObject.GetComponent() != null) + if (col.gameObject.layer == (int)PhysLayers.TERRAIN) + { + lines.Add(col, SetupLineRenderer(col, null, greenMat)); + } + else if (col.GetComponent()) + { + lines.Add(col, SetupLineRenderer(col, null, blueMat)); + } + else if (col.GetComponent() || col.gameObject.LocateMyFSM("damages_hero") != null) + { + colliders.Add(col); + lines.Add(col, SetupLineRenderer(col, null, redMat)); + } + else if (col.GetComponent()) + { + NonBouncer bounce = col.GetComponent(); + if (bounce == null || !bounce.active) { colliders.Add(col); - lines.Add(col, this.SetupLineRenderer(col, null, blueMat)); - } - else if (State == 2 && col.isTrigger && col.gameObject.GetComponent() == null) - { - this.colliders.Add(col); - this.lines.Add(col, this.SetupLineRenderer(col, null, yellowMat)); + lines.Add(col, SetupLineRenderer(col, null, blueMat)); } + } + else if (col.isTrigger && col.gameObject.GetComponent() != null) + { + colliders.Add(col); + lines.Add(col, this.SetupLineRenderer(col, null, blueMat)); + } + else if ((col.isTrigger && col.gameObject.GetComponent() == null) + || (col.gameObject == HeroController.instance.gameObject && !col.isTrigger)) + { + colliders.Add(col); + lines.Add(col, this.SetupLineRenderer(col, null, yellowMat)); + } } } diff --git a/Source/MinimalInfoPanel.cs b/Source/MinimalInfoPanel.cs index ed6ecec..1802898 100644 --- a/Source/MinimalInfoPanel.cs +++ b/Source/MinimalInfoPanel.cs @@ -41,6 +41,7 @@ public static void BuildMenu(GameObject canvas) altPanel.AddText("Alt Current Save State Lable", "Current SaveState", new Vector2(10f, 110f), Vector2.zero, GUIController.Instance.arial, 15); altPanel.AddText("Alt SaveState AutoSlot", "Autoslot", new Vector2(10f, 130f), Vector2.zero, GUIController.Instance.arial, 15); altPanel.AddText("Alt SaveState CurrentSlot", "Current slot", new Vector2(110f, 130f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt WillHardfall", "Hardfall", new Vector2(10f, 150f), Vector2.zero, GUIController.Instance.arial, 15); //Values altPanel.AddText("Vel", "", new Vector2(40f, 14f), Vector2.zero, GUIController.Instance.trajanNormal); @@ -59,6 +60,8 @@ public static void BuildMenu(GameObject canvas) altPanel.AddText("Autoslot", "", new Vector2(80f, 134f), Vector2.zero, GUIController.Instance.trajanNormal); altPanel.AddText("Current slot", "", new Vector2(200f, 134f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Hardfall", "", new Vector2(80f, 154f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.FixRenderOrder(); } @@ -125,6 +128,8 @@ public static void Update() altPanel.GetText("Autoslot").UpdateText(string.Format("{0}", GetStringForBool(SaveStateManager.GetAutoSlot()))); altPanel.GetText("Current slot").UpdateText(string.Format("{0}", slotSet)); + + altPanel.GetText("Hardfall").UpdateText(GetStringForBool(HeroController.instance.cState.willHardLand)); } } diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index e60488e..cf02503 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -3,13 +3,12 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reflection; -using System.Text; using UnityEngine; namespace DebugMod { - public enum SaveStateType { + public enum SaveStateType + { Memory, File, SkipOne @@ -75,7 +74,7 @@ public void SaveState(SaveStateType stateType) quickState.SaveTempState(); break; case SaveStateType.File or SaveStateType.SkipOne: - AutoSlotSelect(stateType); + GameManager.instance.StartCoroutine(SelectSlot(true, stateType)); break; default: break; } @@ -84,7 +83,7 @@ public void SaveState(SaveStateType stateType) #endregion #region loading - + public void LoadState(SaveStateType stateType) { RefreshStateMenu(); @@ -247,9 +246,9 @@ public static Dictionary GetSaveStatesInfo() int total = 0; foreach (KeyValuePair stateData in saveStateFiles) { - if (stateData.Value.IsSet() - && stateData.Key < DebugMod.settings.MaxSaveStates - && stateData.Key >= 0 + if (stateData.Value.IsSet() + && stateData.Key < DebugMod.settings.MaxSaveStates + && stateData.Key >= 0 && total < DebugMod.settings.MaxSaveStates) { returnData.Add(stateData.Key, stateData.Value.GetSaveStateInfo()); @@ -267,18 +266,18 @@ public void RefreshStateMenu() //SaveState tempSave = new SaveState(); string shortFileName; string[] files = Directory.GetFiles(path); - DebugMod.instance.Log( - "path var: " + path + - "\nSavestates: " + files.ToString() - ); + //DebugMod.instance.Log( + // "path var: " + path + + // "\nSavestates: " + files.ToString() + // ); foreach (string file in files) { shortFileName = Path.GetFileName(file); - DebugMod.instance.Log("file: " + shortFileName); + //DebugMod.instance.Log("file: " + shortFileName); var digits = shortFileName.SkipWhile(c => !Char.IsDigit(c)).TakeWhile(Char.IsDigit).ToArray(); int slot = int.Parse(new string(digits)); - + if (File.Exists(file) && (slot >= 0 || slot < maxSaveStates)) { if (saveStateFiles.ContainsKey(slot)) @@ -287,18 +286,19 @@ public void RefreshStateMenu() } saveStateFiles.Add(slot, new SaveState()); saveStateFiles[slot].LoadStateFromFile(slot); - - DebugMod.instance.Log(saveStateFiles[slot].GetSaveStateID()); + + //DebugMod.instance.LogError(saveStateFiles[slot].GetSaveStateID()); } } } catch (Exception ex) { - DebugMod.instance.Log(string.Format(ex.Source, ex.Message)); - throw ex; + DebugMod.instance.LogError(string.Format(ex.Source, ex.Message)); + //throw ex; } } + /* private void AutoSlotSelect(SaveStateType stateType) { if (autoSlot) @@ -337,7 +337,7 @@ private void AutoSlotSelect(SaveStateType stateType) // May not need DeepCopy() saveStateFiles[currentStateSlot].data = quickState.DeepCopy(); saveStateFiles[currentStateSlot].SaveStateToFile(currentStateSlot); - } + } else if (stateType == SaveStateType.SkipOne) { saveStateFiles[currentStateSlot].NewSaveStateToFile(currentStateSlot); @@ -348,6 +348,8 @@ private void AutoSlotSelect(SaveStateType stateType) GameManager.instance.StartCoroutine(SelectSlot(true, stateType)); } } + */ + #endregion } } From 41fc86b64815b27772d7ea2c802b62be17cb3fe8 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Mon, 31 May 2021 20:10:44 +0200 Subject: [PATCH 37/91] Does not work, but uumuu extra skeleton code --- Source/BossHandler.cs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Source/BossHandler.cs b/Source/BossHandler.cs index 2afb73c..7096183 100644 --- a/Source/BossHandler.cs +++ b/Source/BossHandler.cs @@ -141,11 +141,10 @@ public static void UumuuExtra() //GameManager.instance. Object.DontDestroyOnLoad(_coro); - Console.AddLine(_coro.ToString()); + Console.AddLine("Uumuu forced extra attack ON"); UnityEngine.SceneManagement.SceneManager.sceneLoaded += StartUumuuCoro; fsmToggle = true; - } else { @@ -181,27 +180,35 @@ public static void UumuuExtra() private static void StartUumuuCoro(Scene scene, LoadSceneMode lsm) { - //Console.AddLine("Uumuu test: " + scene.name); + Console.AddLine("Start Uumuu Coro Uumuu test: " + scene.name); if (scene.name == "Fungus3_archive_02") { - Console.AddLine(_coro.ToString()); - _coro.StartCoroutine(UumuuExtraCoro()); + Console.AddLine("_coro ToString: " + _coro.active.ToString()); + //_coro.StartCoroutine(UumuuExtraCoro()); + + GameObject uumuu = GameObject.Find("Mega Jellyfish"); + Console.AddLine("Uumuu GameObject"); + + if (uumuu != null) { + Console.AddLine("Locating Uumuu FSM"); + PlayMakerFSM fsm = uumuu.LocateMyFSM("Mega Jellyfish"); + + fsm.GetState("Idle").GetAction().timeMax = 1.6f; + } } } private static IEnumerator UumuuExtraCoro() { - yield return null; - Console.AddLine("Uumuu coro check"); // Find Uumuu and the FSM GameObject uumuu = GameObject.Find("Mega Jellyfish"); - Console.AddLine("Uumuu coro mid pls work"); + Console.AddLine("Uumuu GameObject"); if (uumuu == null) yield break; - Console.AddLine("aaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + Console.AddLine("Locating Uumuu FSM"); PlayMakerFSM fsm = uumuu.LocateMyFSM("Mega Jellyfish"); - fsm.GetState("Idle").GetAction().timeMax = 1.2f;; + fsm.GetState("Idle").GetAction().timeMax = 1.6f; // Fix the waits and the number of attacks From 3a26d842980828cdc3a5d38c26bf7e29f4fa40a9 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Tue, 1 Jun 2021 03:12:45 +0200 Subject: [PATCH 38/91] Small UX fixes, manual cancel savestate w/ file Savestates with file can now be cancelled either by: repressing the selected savestates interaction or wait for an extended 30s timeout --- Source/BindableFunctions.cs | 13 +++---- Source/DebugMod.cs | 1 + Source/GUIController.cs | 11 ++++-- Source/MinimalInfoPanel.cs | 18 ++++++--- Source/SaveState.cs | 2 + Source/SaveStateManager.cs | 74 ++++++++++++++++++++++++++++++------- Source/SaveStatesPanel.cs | 11 ++++-- Source/Settings.cs | 6 +++ Source/TopMenu.cs | 4 +- 9 files changed, 106 insertions(+), 34 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 699774b..65a54ce 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -155,7 +155,7 @@ public static void TimescaleUp() Console.AddLine("Cannot set TimeScale greater than 2.0"); } } - [BindableMethod(name = "Reset", category = "Misc")] + [BindableMethod(name = "Reset Debug States", category = "Misc")] public static void Reset() { var pd = PlayerData.instance; @@ -355,8 +355,7 @@ public static void ToggleAllPanels() DebugMod.settings.EnemiesPanelVisible || DebugMod.settings.TopMenuVisible || DebugMod.settings.ConsoleVisible || - DebugMod.settings.MinInfoPanelVisible || - DebugMod.settings.SaveStatePanelVisible + DebugMod.settings.MinInfoPanelVisible ); if (MinimalInfoPanel.minInfo) @@ -373,7 +372,6 @@ public static void ToggleAllPanels() DebugMod.settings.EnemiesPanelVisible = active; DebugMod.settings.ConsoleVisible = active; DebugMod.settings.HelpPanelVisible = active; - DebugMod.settings.SaveStatePanelVisible = active; if (DebugMod.settings.EnemiesPanelVisible) { @@ -686,6 +684,7 @@ public static void GiveAllCharms() PlayerData.instance.SetBoolInternal("fragileHealth_unbreakable", true); PlayerData.instance.SetBoolInternal("fragileStrength_unbreakable", true); PlayerData.instance.SetIntInternal("grimmChildLevel", 5); + PlayerData.instance.gotGrimmNotch = true; PlayerData.instance.charmSlots = 11; } @@ -740,7 +739,7 @@ public static void FixFragileStrength() } } - [BindableMethod(name = "Overcharm", category = "Charms")] + [BindableMethod(name = "Can Overcharm", category = "Charms")] public static void ToggleOvercharm() { PlayerData.instance.canOvercharm = true; @@ -1252,7 +1251,7 @@ public static void ToggleXunFlower() } else { - PlayerData.instance.hasLantern = false; + PlayerData.instance.hasXunFlower = false; Console.AddLine("Taking away delicate flower"); } } @@ -1358,8 +1357,6 @@ public static void SceneDataToFile() ); } - - [BindableMethod(name = "PlayerData to file", category = "ExportData")] public static void PlayerDataToFile() { diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 7a0ae89..0490d63 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -130,6 +130,7 @@ public override void Initialize() int alphaInt = 0; alphaKeyDict.Clear(); + for (int i = alphaStart; i <= alphaEnd; i++) { KeyCode tmpKeyCode = (KeyCode)i; diff --git a/Source/GUIController.cs b/Source/GUIController.cs index 35bb294..f02104f 100644 --- a/Source/GUIController.cs +++ b/Source/GUIController.cs @@ -16,7 +16,7 @@ public class GUIController : MonoBehaviour public Dictionary images = new Dictionary(); public Vector3 hazardLocation; public string respawnSceneWatch; - public static bool didInput; + public static bool didInput, inputEsc; public static ShowHitboxes hitboxes = new ShowHitboxes(); private GameObject canvas; @@ -200,7 +200,7 @@ public void Update() DebugMod.settings.binds.Remove(bind.Key); } } - + if (SaveStateManager.inSelectSlotState && DebugMod.settings.SaveStatePanelVisible) { foreach (KeyValuePair entry in DebugMod.alphaKeyDict) @@ -212,7 +212,12 @@ public void Update() // keyInt should be between 0-9 SaveStateManager.currentStateSlot = keyInt; didInput = true; - //Console.AddLine("Number selected, didInput bool: " + didInput.ToString()); + break; + } + else + { + didInput = inputEsc = true; + break; } } } diff --git a/Source/MinimalInfoPanel.cs b/Source/MinimalInfoPanel.cs index 1802898..006fcf8 100644 --- a/Source/MinimalInfoPanel.cs +++ b/Source/MinimalInfoPanel.cs @@ -57,10 +57,10 @@ public static void BuildMenu(GameObject canvas) altPanel.AddText("Scene Name", "", new Vector2(140f, 94f), Vector2.zero, GUIController.Instance.trajanNormal); altPanel.AddText("Current SaveState", "", new Vector2(140f, 114f), Vector2.zero, GUIController.Instance.trajanNormal); - altPanel.AddText("Autoslot", "", new Vector2(80f, 134f), Vector2.zero, GUIController.Instance.trajanNormal); + //altPanel.AddText("Autoslot", "", new Vector2(80f, 134f), Vector2.zero, GUIController.Instance.trajanNormal); altPanel.AddText("Current slot", "", new Vector2(200f, 134f), Vector2.zero, GUIController.Instance.trajanNormal); - altPanel.AddText("Hardfall", "", new Vector2(80f, 154f), Vector2.zero, GUIController.Instance.trajanNormal); + altPanel.AddText("Hardfall", "", new Vector2(80f, 134f), Vector2.zero, GUIController.Instance.trajanNormal); altPanel.FixRenderOrder(); } @@ -97,7 +97,7 @@ public static void Update() PlayerData.instance.CountGameCompletion(); altPanel.GetText("Vel").UpdateText(HeroController.instance.current_velocity.ToString()); - altPanel.GetText("Pos").UpdateText(DebugMod.RefKnight.transform.position.ToString()); + altPanel.GetText("Pos").UpdateText(GetHeroPos()); altPanel.GetText("MP").UpdateText((PlayerData.instance.MPCharge + PlayerData.instance.MPReserve).ToString()); altPanel.GetText("NailDmg").UpdateText(DebugMod.RefKnightSlash.FsmVariables.GetFsmInt("damageDealt").Value + " (Flat " + PlayerData.instance.nailDamage + ", x" + DebugMod.RefKnightSlash.FsmVariables.GetFsmFloat("Multiplier").Value + ")"); @@ -125,14 +125,22 @@ public static void Update() slotSet = "unset"; } - altPanel.GetText("Autoslot").UpdateText(string.Format("{0}", - GetStringForBool(SaveStateManager.GetAutoSlot()))); + //altPanel.GetText("Autoslot").UpdateText(string.Format("{0}", + // GetStringForBool(SaveStateManager.GetAutoSlot()))); altPanel.GetText("Current slot").UpdateText(string.Format("{0}", slotSet)); altPanel.GetText("Hardfall").UpdateText(GetStringForBool(HeroController.instance.cState.willHardLand)); } } + private static string GetHeroPos() + { + float HeroX = (float)DebugMod.RefKnight.transform.position.x; + float HeroY = (float)DebugMod.RefKnight.transform.position.y; + + return $"({HeroX}, {HeroY})"; + } + private static string GetStringForBool(bool b) { return b ? "✓" : "X"; diff --git a/Source/SaveState.cs b/Source/SaveState.cs index bc2c7b6..a6d32c4 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -237,11 +237,13 @@ private IEnumerator LoadStateCoro() HeroController.instance.proxyFSM.SendEvent("HeroCtrl-HeroDamaged"); HeroAnimationController component = HeroController.instance.GetComponent(); typeof(HeroAnimationController).GetField("pd", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(component, PlayerData.instance); + HeroController.instance.TakeHealth(1); HeroController.instance.AddHealth(1); GameCameras.instance.hudCanvas.gameObject.SetActive(true); HeroController.instance.TakeHealth(1); HeroController.instance.AddHealth(1); + GameManager.instance.inputHandler.RefreshPlayerData(); yield break; // need to redraw UI somehow diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index cf02503..d333f8d 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -29,14 +29,25 @@ internal class SaveStateManager public static int maxSaveStates = DebugMod.settings.MaxSaveStates; public static SaveState quickState; - public static bool inSelectSlotState = false; + public static bool inSelectSlotState = false; // a mutex, in practice? public static int currentStateSlot = -1; public static string path = Application.persistentDataPath + "/Savestates-1221/"; + public static string currentStateOperation = null; + private static string[] stateStrings = + { + "Quickslot (save)", + "Quickslot (load)", + "Save quickslot to file", + "Load quickslot from file", + "Save new state to file", + "Load new state from file" + }; private static Dictionary saveStateFiles = new Dictionary(); - private static bool autoSlot; + + //private static bool autoSlot; private DateTime timeoutHelper; - private double timeoutAmount = 8; + private double timeoutAmount = 30; //public static bool preserveThroughStates = false; @@ -45,7 +56,7 @@ internal SaveStateManager() try { inSelectSlotState = false; - autoSlot = false; + //autoSlot = false; DebugMod.settings.SaveStatePanelVisible = false; quickState = new SaveState(); @@ -67,14 +78,17 @@ internal SaveStateManager() #region saving public void SaveState(SaveStateType stateType) { - RefreshStateMenu(); switch (stateType) { case SaveStateType.Memory: quickState.SaveTempState(); break; case SaveStateType.File or SaveStateType.SkipOne: - GameManager.instance.StartCoroutine(SelectSlot(true, stateType)); + if (!inSelectSlotState) + { + RefreshStateMenu(); + GameManager.instance.StartCoroutine(SelectSlot(true, stateType)); + } break; default: break; } @@ -86,7 +100,6 @@ public void SaveState(SaveStateType stateType) public void LoadState(SaveStateType stateType) { - RefreshStateMenu(); switch (stateType) { case SaveStateType.Memory: @@ -100,7 +113,11 @@ public void LoadState(SaveStateType stateType) } break; case SaveStateType.File or SaveStateType.SkipOne: - GameManager.instance.StartCoroutine(SelectSlot(false, stateType)); + if (!inSelectSlotState) + { + RefreshStateMenu(); + GameManager.instance.StartCoroutine(SelectSlot(false, stateType)); + } break; default: break; @@ -112,11 +129,37 @@ public void LoadState(SaveStateType stateType) #region helper functionality private IEnumerator SelectSlot(bool save, SaveStateType stateType) { - timeoutHelper = DateTime.Now.AddSeconds(timeoutAmount); + switch (stateType) + { + case SaveStateType.Memory: + currentStateOperation = save ? "Quickslot (save)" : "Quickslot (load)"; + break; + case SaveStateType.File: + currentStateOperation = save ? "Quickslot save to file" : "Load file to quickslot"; + break; + case SaveStateType.SkipOne: + currentStateOperation = save ? "Save new state to file" : "Load new state from file"; + break; + default: + //DebugMod.instance.LogError("SelectSlot ended started"); + throw new ArgumentException("Helper func SelectSlot requires `bool` and `SaveStateType` to proceed the savestate process"); + } + if (DebugMod.settings.binds.TryGetValue(currentStateOperation, out int keycode)) + { + DebugMod.alphaKeyDict.Add((KeyCode)keycode, keycode); + } + else + { + throw new Exception("Helper func SelectSlot could not find a binding for the `" + currentStateOperation + "` savestate process"); + } + + yield return null; + timeoutHelper = DateTime.Now.AddSeconds(timeoutAmount); DebugMod.settings.SaveStatePanelVisible = inSelectSlotState = true; yield return new WaitUntil(DidInput); - if (GUIController.didInput) + + if (GUIController.didInput && !GUIController.inputEsc) { if (currentStateSlot >= 0 && currentStateSlot < maxSaveStates) { @@ -129,13 +172,16 @@ private IEnumerator SelectSlot(bool save, SaveStateType stateType) LoadCoroHelper(stateType); } } - GUIController.didInput = false; } else { - Console.AddLine("Timeout (" + timeoutAmount + "s) reached"); + if (GUIController.didInput) Console.AddLine("Savestate action cancelled"); + else Console.AddLine("Timeout (" + timeoutAmount.ToString() + ")s was reached"); } - + + DebugMod.alphaKeyDict.Remove((KeyCode)keycode); + currentStateOperation = null; + GUIController.inputEsc = GUIController.didInput = false; DebugMod.settings.SaveStatePanelVisible = inSelectSlotState = false; } @@ -209,6 +255,7 @@ private bool DidInput() return false; } + /* public void ToggleAutoSlot() { autoSlot = !autoSlot; @@ -218,6 +265,7 @@ public static bool GetAutoSlot() { return autoSlot; } + */ public static int GetCurrentSlot() { diff --git a/Source/SaveStatesPanel.cs b/Source/SaveStatesPanel.cs index ffb5508..dadd678 100644 --- a/Source/SaveStatesPanel.cs +++ b/Source/SaveStatesPanel.cs @@ -13,7 +13,7 @@ public static void BuildMenu(GameObject canvas) statePanel = new CanvasPanel( canvas, GUIController.Instance.images["BlankVertical"], - new Vector2(800f, 40f), + new Vector2(720f, 40f), Vector2.zero, new Rect( 0f, @@ -23,13 +23,16 @@ public static void BuildMenu(GameObject canvas) ) ); + statePanel.AddText("Mode", "mode: ", new Vector2(8, 20), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("currentmode", "-", new Vector2(60, 20), Vector2.zero, GUIController.Instance.arial, 15); + for (int i = 0; i < SaveStateManager.maxSaveStates; i++) { //Labels - statePanel.AddText("Slot " + i, i.ToString(), new Vector2(10, i * 20 + 20), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("Slot " + i, i.ToString(), new Vector2(10, i * 20 + 40), Vector2.zero, GUIController.Instance.arial, 15); //Values - statePanel.AddText(i.ToString(), "", new Vector2(50, i * 20 + 20), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText(i.ToString(), "", new Vector2(50, i * 20 + 40), Vector2.zero, GUIController.Instance.arial, 15); } /* statePanel.AddText("Slot1", "1", new Vector2(10f, 40f), Vector2.zero, GUIController.Instance.arial, 15); @@ -84,6 +87,8 @@ public static void Update() if (statePanel.active) { + statePanel.GetText("currentmode").UpdateText(SaveStateManager.currentStateOperation); + for (int i = 0; i < SaveStateManager.maxSaveStates; i++) { statePanel.GetText(i.ToString()).UpdateText("open"); diff --git a/Source/Settings.cs b/Source/Settings.cs index 72b37c7..c2a36a5 100644 --- a/Source/Settings.cs +++ b/Source/Settings.cs @@ -75,5 +75,11 @@ public int MaxSaveStates get => GetInt(); set => SetInt(value); } + + public float AmountToMove + { + get => GetFloat(0.1f); + set => SetFloat(value); + } } } diff --git a/Source/TopMenu.cs b/Source/TopMenu.cs index 51c23e0..fc213d5 100644 --- a/Source/TopMenu.cs +++ b/Source/TopMenu.cs @@ -41,7 +41,7 @@ public static void BuildMenu(GameObject canvas) panel.GetPanel("Cheats Panel").AddButton("Invincibility", GUIController.Instance.images["ButtonRectEmpty"], new Vector2(5f, 120f), Vector2.zero, InvincibilityClicked, new Rect(0f, 0f, 80f, 20f), GUIController.Instance.trajanNormal, "Invincibility", 10); panel.GetPanel("Cheats Panel").AddButton("Noclip", GUIController.Instance.images["ButtonRectEmpty"], new Vector2(5f, 150f), Vector2.zero, NoclipClicked, new Rect(0f, 0f, 80f, 20f), GUIController.Instance.trajanNormal, "Noclip", 10); panel.GetPanel("Cheats Panel").AddButton("Kill Self", GUIController.Instance.images["ButtonRectEmpty"], new Vector2(5f, 180f), Vector2.zero, KillSelfClicked, new Rect(0f, 0f, 80f, 20f), GUIController.Instance.trajanNormal, "Kill Self", 10); - panel.GetPanel("Cheats Panel").AddButton("Lock KeyBinds", GUIController.Instance.images["ButtonRectEmpty"], new Vector2(5f, 210f), Vector2.zero, KeyBindLockClicked, new Rect(0f, 0f, 80f, 20f), GUIController.Instance.trajanNormal, "Lock KeyBinds", 10); + panel.GetPanel("Cheats Panel").AddButton("Lock KeyBinds", GUIController.Instance.images["ButtonRectEmpty"], new Vector2(5f, 210f), Vector2.zero, KeyBindLockClicked, new Rect(0f, 0f, 80f, 20f), GUIController.Instance.trajanNormal, "Lock Binds", 10); //Charms panel @@ -629,7 +629,7 @@ private static void ScrollDownClicked(string buttonName) private static void KeyBindLockClicked(string buttonName) { DebugMod.KeyBindLock = !DebugMod.KeyBindLock; - Console.AddLine((DebugMod.KeyBindLock ? "Removing" : "Adding") + "the ability to use keybinds"); + Console.AddLine((DebugMod.KeyBindLock ? "Removing" : "Adding") + " the ability to use keybinds"); } } } From 92381d8faedec5da2b0f55d01b495c5c07b71384 Mon Sep 17 00:00:00 2001 From: DemoJameson Date: Thu, 3 Jun 2021 10:41:28 +0800 Subject: [PATCH 39/91] Resolve compile warnings and stop copying redundant dlls to the output folder --- Source/DebugMod.csproj | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 8c70fb5..07b8717 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -55,22 +55,27 @@ False .\References\Assembly-CSharp.dll + False False .\References\PlayMaker.dll + False .\References\UnityEngine.dll + False .\References\UnityEngine.UI.dll + False References\Vasi.dll + False @@ -92,9 +97,6 @@ - - UnityEngine.dll - From d722e749171dfc17ced4fd471d9c17c0fea171a6 Mon Sep 17 00:00:00 2001 From: DemoJameson Date: Sat, 5 Jun 2021 01:42:08 +0800 Subject: [PATCH 40/91] Rewrite the hitboxes feature 1. Using IMGUI to draw hitboxes, no more twisted lines 2. Draw the knight and enemies attack hitboxes 3. Draw the newly created objects hitboxes --- Source/DebugMod.csproj | 4 +- Source/GUIController.cs | 7 +- Source/Hitbox/Drawing.cs | 187 +++++++++++++++++++ Source/Hitbox/HitboxRender.cs | 190 +++++++++++++++++++ Source/Hitbox/HitboxViewer.cs | 58 ++++++ Source/HitboxViewer.cs | 332 ---------------------------------- 6 files changed, 442 insertions(+), 336 deletions(-) create mode 100644 Source/Hitbox/Drawing.cs create mode 100644 Source/Hitbox/HitboxRender.cs create mode 100644 Source/Hitbox/HitboxViewer.cs delete mode 100644 Source/HitboxViewer.cs diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 07b8717..0b56f2c 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -82,7 +82,9 @@ - + + + diff --git a/Source/GUIController.cs b/Source/GUIController.cs index f02104f..5a46885 100644 --- a/Source/GUIController.cs +++ b/Source/GUIController.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Reflection; +using DebugMod.Hitbox; using UnityEngine; using UnityEngine.UI; @@ -17,7 +18,7 @@ public class GUIController : MonoBehaviour public Vector3 hazardLocation; public string respawnSceneWatch; public static bool didInput, inputEsc; - public static ShowHitboxes hitboxes = new ShowHitboxes(); + private static readonly HitboxViewer hitboxes = new(); private GameObject canvas; private static GUIController _instance; @@ -312,13 +313,13 @@ public void Update() PlayerData.instance.respawnMarkerName.ToString() })); } - if (ShowHitboxes.State != DebugMod.settings.ShowHitBoxes) + if (HitboxViewer.State != DebugMod.settings.ShowHitBoxes) { if (DebugMod.settings.ShowHitBoxes != 0) { hitboxes.Load(); } - else if (ShowHitboxes.State != 0 && DebugMod.settings.ShowHitBoxes == 0) + else if (HitboxViewer.State != 0 && DebugMod.settings.ShowHitBoxes == 0) { hitboxes.Unload(); } diff --git a/Source/Hitbox/Drawing.cs b/Source/Hitbox/Drawing.cs new file mode 100644 index 0000000..8bbb841 --- /dev/null +++ b/Source/Hitbox/Drawing.cs @@ -0,0 +1,187 @@ +using System.Reflection; +using UnityEngine; + +namespace DebugMod.Hitbox { + // Line drawing routine originally courtesy of Linusmartensson: + // http://forum.unity3d.com/threads/71979-Drawing-lines-in-the-editor + // + // Rewritten to improve performance by Yossarian King / August 2013. + // + // Circle drawing functionality added by Cherno + // http://answers.unity.com/answers/713428/view.html + // + // This version produces virtually identical results to the original (tested by drawing + // one over the other and observing errors of one pixel or less), but for large numbers + // of lines this version is more than four times faster than the original, and comes + // within about 70% of the raw performance of Graphics.DrawTexture. + // + // Peak performance on my laptop is around 200,000 lines per second. The laptop is + // Windows 7 64-bit, Intel Core2 Duo CPU 2.53GHz, 4G RAM, NVIDIA GeForce GT 220M. + // Line width and anti-aliasing had negligible impact on performance. + // + // For a graph of benchmark results in a standalone Windows build, see this image: + // https://app.box.com/s/hyuhi565dtolqdm97e00 + // + // For a Google spreadsheet with full benchmark results, see: + // https://docs.google.com/spreadsheet/ccc?key=0AvJlJlbRO26VdHhzeHNRMVF2UHZHMXFCTVFZN011V1E&usp=sharing + + public static class Drawing { + private static Texture2D aaLineTex = null; + private static Texture2D lineTex = null; + private static Material blitMaterial = null; + private static Material blendMaterial = null; + private static Rect lineRect = new Rect(0, 0, 1, 1); + + // Draw a line in screen space, suitable for use from OnGUI calls from either + // MonoBehaviour or EditorWindow. Note that this should only be called during repaint + // events, when (Event.current.type == EventType.Repaint). + // + // Works by computing a matrix that transforms a unit square -- Rect(0,0,1,1) -- into + // a scaled, rotated, and offset rectangle that corresponds to the line and its width. + // A DrawTexture call used to draw a line texture into the transformed rectangle. + // + // More specifically: + // scale x by line length, y by line width + // rotate around z by the angle of the line + // offset by the position of the upper left corner of the target rectangle + // + // By working out the matrices and applying some trigonometry, the matrix calculation comes + // out pretty simple. See https://app.box.com/s/xi08ow8o8ujymazg100j for a picture of my + // notebook with the calculations. + public static void DrawLine(Vector2 pointA, Vector2 pointB, Color color, float width, bool antiAlias) { + // Normally the static initializer does this, but to handle texture reinitialization + // after editor play mode stops we need this check in the Editor. +#if UNITY_EDITOR + if (!lineTex) + { + Initialize(); + } +#endif + + // Note that theta = atan2(dy, dx) is the angle we want to rotate by, but instead + // of calculating the angle we just use the sine (dy/len) and cosine (dx/len). + float dx = pointB.x - pointA.x; + float dy = pointB.y - pointA.y; + float len = Mathf.Sqrt(dx * dx + dy * dy); + + // Early out on tiny lines to avoid divide by zero. + // Plus what's the point of drawing a line 1/1000th of a pixel long?? + if (len < 0.001f) { + return; + } + + // Pick texture and material (and tweak width) based on anti-alias setting. + Texture2D tex; + Material mat; + if (antiAlias) { + // Multiplying by three is fine for anti-aliasing width-1 lines, but make a wide "fringe" + // for thicker lines, which may or may not be desirable. + width = width * 3.0f; + tex = aaLineTex; + mat = blendMaterial; + } else { + tex = lineTex; + mat = blitMaterial; + } + + float wdx = width * dy / len; + float wdy = width * dx / len; + + Matrix4x4 matrix = Matrix4x4.identity; + matrix.m00 = dx; + matrix.m01 = -wdx; + matrix.m03 = pointA.x + 0.5f * wdx; + matrix.m10 = dy; + matrix.m11 = wdy; + matrix.m13 = pointA.y - 0.5f * wdy; + + // Use GL matrix and Graphics.DrawTexture rather than GUI.matrix and GUI.DrawTexture, + // for better performance. (Setting GUI.matrix is slow, and GUI.DrawTexture is just a + // wrapper on Graphics.DrawTexture.) + GL.PushMatrix(); + GL.MultMatrix(matrix); + + Graphics.DrawTexture(lineRect, tex, lineRect, 0, 0, 0, 0, color, mat); + // 启用抗锯齿时颜色似乎是半透明的,所以重复绘制一次使其更清晰 + if (antiAlias) { + Graphics.DrawTexture(lineRect, tex, lineRect, 0, 0, 0, 0, color, mat); + } + + GL.PopMatrix(); + } + + public static void DrawCircle(Vector2 center, int radius, Color color, float width, int segmentsPerQuarter) { + DrawCircle(center, radius, color, width, false, segmentsPerQuarter); + } + + public static void DrawCircle(Vector2 center, int radius, Color color, float width, bool antiAlias, int segmentsPerQuarter) { + float rh = (float) radius * 0.551915024494f; + + Vector2 p1 = new Vector2(center.x, center.y - radius); + Vector2 p1_tan_a = new Vector2(center.x - rh, center.y - radius); + Vector2 p1_tan_b = new Vector2(center.x + rh, center.y - radius); + + Vector2 p2 = new Vector2(center.x + radius, center.y); + Vector2 p2_tan_a = new Vector2(center.x + radius, center.y - rh); + Vector2 p2_tan_b = new Vector2(center.x + radius, center.y + rh); + + Vector2 p3 = new Vector2(center.x, center.y + radius); + Vector2 p3_tan_a = new Vector2(center.x - rh, center.y + radius); + Vector2 p3_tan_b = new Vector2(center.x + rh, center.y + radius); + + Vector2 p4 = new Vector2(center.x - radius, center.y); + Vector2 p4_tan_a = new Vector2(center.x - radius, center.y - rh); + Vector2 p4_tan_b = new Vector2(center.x - radius, center.y + rh); + + DrawBezierLine(p1, p1_tan_b, p2, p2_tan_a, color, width, antiAlias, segmentsPerQuarter); + DrawBezierLine(p2, p2_tan_b, p3, p3_tan_b, color, width, antiAlias, segmentsPerQuarter); + DrawBezierLine(p3, p3_tan_a, p4, p4_tan_b, color, width, antiAlias, segmentsPerQuarter); + DrawBezierLine(p4, p4_tan_a, p1, p1_tan_a, color, width, antiAlias, segmentsPerQuarter); + } + + // Other than method name, DrawBezierLine is unchanged from Linusmartensson's original implementation. + public static void DrawBezierLine(Vector2 start, Vector2 startTangent, Vector2 end, Vector2 endTangent, Color color, float width, + bool antiAlias, int segments) { + Vector2 lastV = CubeBezier(start, startTangent, end, endTangent, 0); + for (int i = 1; i < segments + 1; ++i) { + Vector2 v = CubeBezier(start, startTangent, end, endTangent, i / (float) segments); + DrawLine(lastV, v, color, width, antiAlias); + lastV = v; + } + } + + + private static Vector2 CubeBezier(Vector2 s, Vector2 st, Vector2 e, Vector2 et, float t) { + float rt = 1 - t; + return rt * rt * rt * s + 3 * rt * rt * t * st + 3 * rt * t * t * et + t * t * t * e; + } + + // This static initializer works for runtime, but apparently isn't called when + // Editor play mode stops, so DrawLine will re-initialize if needed. + static Drawing() { + Initialize(); + } + + private static void Initialize() { + if (lineTex == null) { + lineTex = new Texture2D(1, 1, TextureFormat.ARGB32, false); + lineTex.SetPixel(0, 1, Color.white); + lineTex.Apply(); + } + + if (aaLineTex == null) { + // TODO: better anti-aliasing of wide lines with a larger texture? or use Graphics.DrawTexture with border settings + aaLineTex = new Texture2D(1, 3, TextureFormat.ARGB32, false); + aaLineTex.SetPixel(0, 0, new Color(1, 1, 1, 0)); + aaLineTex.SetPixel(0, 1, Color.white); + aaLineTex.SetPixel(0, 2, new Color(1, 1, 1, 0)); + aaLineTex.Apply(); + } + + // GUI.blitMaterial and GUI.blendMaterial are used internally by GUI.DrawTexture, + // depending on the alphaBlend parameter. Use reflection to "borrow" these references. + blitMaterial = (Material) typeof(GUI).GetMethod("get_blitMaterial", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null); + blendMaterial = (Material) typeof(GUI).GetMethod("get_blendMaterial", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null); + } + } +} \ No newline at end of file diff --git a/Source/Hitbox/HitboxRender.cs b/Source/Hitbox/HitboxRender.cs new file mode 100644 index 0000000..68ba1b6 --- /dev/null +++ b/Source/Hitbox/HitboxRender.cs @@ -0,0 +1,190 @@ +using System; +using System.Collections.Generic; +using GlobalEnums; +using UnityEngine; + +namespace DebugMod.Hitbox +{ + public class HitboxRender : MonoBehaviour + { + // ReSharper disable once StructCanBeMadeReadOnly + private struct HitboxType: IComparable + { + public static readonly HitboxType Knight = new(Color.yellow, 0); + public static readonly HitboxType Enemy = new(new Color(0.8f, 0, 0), 1); + public static readonly HitboxType Attack = new(Color.cyan, 2); + public static readonly HitboxType Terrain = new(new Color(0, 0.8f, 0), 3); + public static readonly HitboxType Trigger = new(new Color(0.5f, 0.5f, 1f), 4); + public static readonly HitboxType Other = new(new Color(0.9f, 0.6f, 0.4f), 5); + + public readonly Color Color; + public readonly int Depth; + + private HitboxType(Color color, int depth) + { + Color = color; + Depth = depth; + } + + public int CompareTo(HitboxType other) + { + return other.Depth.CompareTo(Depth); + } + } + + private readonly SortedDictionary> colliders = new() + { + {HitboxType.Knight, new HashSet()}, + {HitboxType.Enemy, new HashSet()}, + {HitboxType.Attack, new HashSet()}, + {HitboxType.Terrain, new HashSet()}, + {HitboxType.Trigger, new HashSet()}, + {HitboxType.Other, new HashSet()}, + }; + + private float LineWidth => Math.Max(0.7f, Screen.width / 960f * GameCameras.instance.tk2dCam.ZoomFactor); + + private void Start() + { + foreach (Collider2D col in Resources.FindObjectsOfTypeAll()) + { + TryAddHitboxes(col); + } + } + + public void UpdateHitbox(GameObject go) + { + foreach (Collider2D col in go.GetComponentsInChildren(true)) + { + TryAddHitboxes(col); + } + } + + private Vector2 LocalToScreenPoint(Camera camera, Collider2D collider2D, Vector2 point) + { + Vector2 result = camera.WorldToScreenPoint(collider2D.transform.TransformPoint(point + collider2D.offset)); + return new Vector2((int) Math.Round(result.x), (int) Math.Round(Screen.height - result.y)); + } + + private void TryAddHitboxes(Collider2D collider2D) + { + if (collider2D == null) + { + return; + } + + if (collider2D is BoxCollider2D or PolygonCollider2D or EdgeCollider2D or CircleCollider2D) + { + GameObject go = collider2D.gameObject; + if (collider2D.GetComponent() || collider2D.gameObject.LocateMyFSM("damages_hero")) + { + colliders[HitboxType.Enemy].Add(collider2D); + } else if (go.LocateMyFSM("health_manager_enemy") || go.LocateMyFSM("health_manager")) + { + colliders[HitboxType.Other].Add(collider2D); + } else if (go.layer == (int) PhysLayers.TERRAIN) + { + colliders[HitboxType.Terrain].Add(collider2D); + } else if (go == HeroController.instance?.gameObject && !collider2D.isTrigger) + { + colliders[HitboxType.Knight].Add(collider2D); + } else if (go.LocateMyFSM("damages_enemy")) + { + colliders[HitboxType.Attack].Add(collider2D); + } else if (collider2D.isTrigger && (collider2D.GetComponent() || collider2D.GetComponent())) + { + colliders[HitboxType.Trigger].Add(collider2D); + } else if (collider2D.GetComponent()) + { + NonBouncer bounce = collider2D.GetComponent(); + if (bounce == null || !bounce.active) + { + colliders[HitboxType.Trigger].Add(collider2D); + } + } else if (HitboxViewer.State == 2) + { + colliders[HitboxType.Other].Add(collider2D); + } + } + } + + private void OnGUI() + { + if (Event.current?.type != EventType.Repaint || GameManager.instance.isPaused || Camera.main == null) + { + return; + } + + GUI.depth = int.MaxValue; + Camera camera = Camera.main; + float lineWidth = LineWidth; + foreach (var pair in colliders) + { + foreach (Collider2D collider2D in pair.Value) + { + DrawHitbox(camera, collider2D, pair.Key, lineWidth); + } + } + } + + private void DrawHitbox(Camera camera, Collider2D collider2D, HitboxType hitboxType, float lineWidth) + { + if (collider2D == null || !collider2D.isActiveAndEnabled) + { + return; + } + + int origDepth = GUI.depth; + GUI.depth = hitboxType.Depth; + if (collider2D is BoxCollider2D or EdgeCollider2D or PolygonCollider2D) + { + List points = null; + switch (collider2D) + { + case BoxCollider2D boxCollider2D: + { + Vector2 halfSize = boxCollider2D.size / 2f; + Vector2 topLeft = new(-halfSize.x, halfSize.y); + Vector2 topRight = halfSize; + Vector2 bottomRight = new(halfSize.x, -halfSize.y); + Vector2 bottomLeft = -halfSize; + points = new List + { + topLeft, topRight, bottomRight, bottomLeft, topLeft + }; + break; + } + case EdgeCollider2D edgeCollider2D: + points = new List(edgeCollider2D.points); + break; + case PolygonCollider2D polygonCollider2D: + { + points = new List(polygonCollider2D.points); + if (points.Count > 0) + { + points.Add(points[0]); + } + + break; + } + } + + for (int i = 0; i < points.Count - 1; i++) + { + Vector2 pointA = LocalToScreenPoint(camera, collider2D, points[i]); + Vector2 pointB = LocalToScreenPoint(camera, collider2D, points[i + 1]); + Drawing.DrawLine(pointA, pointB, hitboxType.Color, lineWidth, true); + } + } else if (collider2D is CircleCollider2D circleCollider2D) + { + Vector2 offset = circleCollider2D.offset; + Vector2 center = LocalToScreenPoint(camera, collider2D, offset); + Vector2 centerRight = LocalToScreenPoint(camera, collider2D, new Vector2(offset.x + circleCollider2D.radius, offset.y)); + int radius = (int) Math.Round(Math.Abs(centerRight.x - center.x)); + Drawing.DrawCircle(center, radius, hitboxType.Color, lineWidth, true, Math.Max(8, radius / 16)); + } + + GUI.depth = origDepth; + } + } +} \ No newline at end of file diff --git a/Source/Hitbox/HitboxViewer.cs b/Source/Hitbox/HitboxViewer.cs new file mode 100644 index 0000000..9293725 --- /dev/null +++ b/Source/Hitbox/HitboxViewer.cs @@ -0,0 +1,58 @@ +using Modding; +using UnityEngine; +using UnityEngine.SceneManagement; +using Object = UnityEngine.Object; + +namespace DebugMod.Hitbox +{ + public class HitboxViewer + { + public static int State { get; private set; } + private HitboxRender hitboxRender; + + public void Load() + { + State = DebugMod.settings.ShowHitBoxes; + Unload(); + UnityEngine.SceneManagement.SceneManager.activeSceneChanged += CreateHitboxRender; + ModHooks.Instance.ColliderCreateHook += UpdateHitboxRender; + CreateHitboxRender(); + } + + public void Unload() + { + State = DebugMod.settings.ShowHitBoxes; + UnityEngine.SceneManagement.SceneManager.activeSceneChanged -= CreateHitboxRender; + ModHooks.Instance.ColliderCreateHook -= UpdateHitboxRender; + DestroyHitboxRender(); + } + + private void CreateHitboxRender(Scene current, Scene next) => CreateHitboxRender(); + + private void CreateHitboxRender() + { + DestroyHitboxRender(); + if (GameManager.instance.IsGameplayScene()) + { + hitboxRender = new GameObject().AddComponent(); + } + } + + private void DestroyHitboxRender() + { + if (hitboxRender != null) + { + Object.Destroy(hitboxRender); + hitboxRender = null; + } + } + + private void UpdateHitboxRender(GameObject go) + { + if (hitboxRender != null) + { + hitboxRender.UpdateHitbox(go); + } + } + } +} \ No newline at end of file diff --git a/Source/HitboxViewer.cs b/Source/HitboxViewer.cs deleted file mode 100644 index 9e4a226..0000000 --- a/Source/HitboxViewer.cs +++ /dev/null @@ -1,332 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using GlobalEnums; -using Modding; -using UnityEngine; -using UnityEngine.SceneManagement; - -using Object = UnityEngine.Object; - -namespace DebugMod -{ - //public class ShowHitboxes : Mod, ITogglableMod - public class ShowHitboxes - { - public static int State; - - private static Material greenMat; - private static Material redMat; - private static Material yellowMat; - private static Material blueMat; - - private Dictionary lines = new Dictionary(); - private List colliders = new List(); - - public ShowHitboxes() - { - State = 0; - - greenMat = new Material(Shader.Find("Diffuse")); - greenMat.renderQueue = 4000; - greenMat.color = Color.green; - - redMat = new Material(Shader.Find("Diffuse")); - redMat.renderQueue = 4000; - redMat.color = Color.red; - - yellowMat = new Material(Shader.Find("Diffuse")); - yellowMat.renderQueue = 4000; - yellowMat.color = Color.yellow; - - blueMat = new Material(Shader.Find("Diffuse")); - blueMat.renderQueue = 4000; - blueMat.color = Color.blue; - } - - public void Load() - { - Unload(); - UnityEngine.SceneManagement.SceneManager.activeSceneChanged += SpawnHitboxes; - ModHooks.Instance.HeroUpdateHook += UpdateHitboxes; - State = DebugMod.settings.ShowHitBoxes; - - SpawnHitboxes(); - } - - - public void Unload() - { - UnityEngine.SceneManagement.SceneManager.activeSceneChanged -= SpawnHitboxes; - ModHooks.Instance.HeroUpdateHook -= UpdateHitboxes; - State = DebugMod.settings.ShowHitBoxes; - - foreach (GameObject obj in Object.FindObjectsOfType()) - { - if (obj.name == "Mod Hitbox") - { - Object.Destroy(obj); - } - } - } - - private void DestroyBorder(IEnumerable borders) - { - foreach (GameObject border in borders) - { - Object.Destroy(border); - } - } - - private void SpawnHitboxes() - { - if (!GameManager.instance.IsGameplayScene()) - { - return; - } - - DestroyBorder(Object.FindObjectsOfType().Where(x => x.name.Contains("sceneborder"))); - - foreach (Collider2D col in lines.Keys.ToArray()) - { - if (col != null && lines[col] != null) - { - Object.Destroy(lines[col].gameObject); - } - } - - switch (State) - { - case 1: - State1Boxes(); - break; - case 2: - State2Boxes(); - break; - } - } - - private void State1Boxes() - { - colliders = new List(); - lines = new Dictionary(); - - foreach (Collider2D col in Object.FindObjectsOfType()) - { - if (colliders.Contains(col)) - { - continue; - } - - if (col.gameObject.layer == (int)PhysLayers.TERRAIN) - { - lines.Add(col, SetupLineRenderer(col, null, greenMat)); - } - else if (col.GetComponent()) - { - lines.Add(col, SetupLineRenderer(col, null, blueMat)); - } - else if (col.GetComponent() || col.gameObject.LocateMyFSM("damages_hero") != null) - { - colliders.Add(col); - lines.Add(col, SetupLineRenderer(col, null, redMat)); - } - else if (col.gameObject == HeroController.instance.gameObject && !col.isTrigger) - { - colliders.Add(col); - lines.Add(col, SetupLineRenderer(col, null, yellowMat)); - } - else if (col.GetComponent()) - { - NonBouncer bounce = col.GetComponent(); - if (bounce == null || !bounce.active) - { - colliders.Add(col); - lines.Add(col, SetupLineRenderer(col, null, blueMat)); - } - } - } - } - - - private void State2Boxes() - { - colliders = new List(); - lines = new Dictionary(); - - foreach (Collider2D col in Object.FindObjectsOfType()) - { - if (colliders.Contains(col)) - { - continue; - } - - if (col.gameObject.layer == (int)PhysLayers.TERRAIN) - { - lines.Add(col, SetupLineRenderer(col, null, greenMat)); - } - else if (col.GetComponent()) - { - lines.Add(col, SetupLineRenderer(col, null, blueMat)); - } - else if (col.GetComponent() || col.gameObject.LocateMyFSM("damages_hero") != null) - { - colliders.Add(col); - lines.Add(col, SetupLineRenderer(col, null, redMat)); - } - else if (col.GetComponent()) - { - NonBouncer bounce = col.GetComponent(); - if (bounce == null || !bounce.active) - { - colliders.Add(col); - lines.Add(col, SetupLineRenderer(col, null, blueMat)); - } - } - else if (col.isTrigger && col.gameObject.GetComponent() != null) - { - colliders.Add(col); - lines.Add(col, this.SetupLineRenderer(col, null, blueMat)); - } - else if ((col.isTrigger && col.gameObject.GetComponent() == null) - || (col.gameObject == HeroController.instance.gameObject && !col.isTrigger)) - { - colliders.Add(col); - lines.Add(col, this.SetupLineRenderer(col, null, yellowMat)); - } - } - } - - private void SpawnHitboxes(Scene from, Scene to) => SpawnHitboxes(); - - private void UpdateHitboxes() - { - if (colliders == null || lines == null) - { - return; - } - - foreach (Collider2D col in colliders) - { - if (col == null || !col.enabled) - { - if (lines[col] != null) - { - Object.Destroy(lines[col].gameObject); - } - - continue; - } - - lines[col] = SetupLineRenderer(col, lines[col]); - } - } - - private LineRenderer SetupLineRenderer(Collider2D col, LineRenderer line = null, Material mat = null) - { - if (line == null) - { - if (mat == null) - { - mat = greenMat; - } - - GameObject obj = new GameObject("Mod Hitbox"); - obj.transform.SetParent(col.transform); - obj.transform.position = Vector3.zero; - - line = obj.AddComponent(); - line.SetWidth(.05f, .05f); - line.sharedMaterial = mat; - } - - if (col is BoxCollider2D box) - { - Vector2 topRight = box.size / 2f; - Vector2 bottomLeft = -topRight; - Vector2 bottomRight = new Vector2(topRight.x, bottomLeft.y); - Vector2 topLeft = -bottomRight; - - line.SetVertexCount(5); - line.SetPositions(new Vector3[] - { - col.transform.TransformPoint(bottomLeft + box.offset), - col.transform.TransformPoint(topLeft + box.offset), - col.transform.TransformPoint(topRight + box.offset), - col.transform.TransformPoint(bottomRight + box.offset), - col.transform.TransformPoint(bottomLeft + box.offset) - }); - } - else if (col is CircleCollider2D circle) - { - Vector3 center = circle.transform.position + (Vector3)circle.offset; - - Vector3[] points = new Vector3[30]; - float sliceSize = Mathf.PI * 2f / points.Length; - - for (int i = 0; i < points.Length - 1; i++) - { - float theta = sliceSize * i; - float sin = (float)Math.Sin(theta); - float cos = (float)Math.Cos(theta); - - points[i] = new Vector2( - (cos - sin) * circle.transform.localScale.x * circle.radius, - (cos + sin) * circle.transform.localScale.y * circle.radius); - } - - points[points.Length - 1] = points[0]; - - line.SetVertexCount(points.Length); - line.SetPositions(points); - } - else if (col is PolygonCollider2D poly) - { - Vector3[] points = new Vector3[poly.points.Length + 1]; - for (int i = 0; i < poly.points.Length; i++) - { - points[i] = poly.transform.TransformPoint(poly.points[i]); - } - - points[points.Length - 1] = points[0]; - line.SetVertexCount(points.Length); - line.SetPositions(points); - } - else if (col is EdgeCollider2D edge) - { - Vector3[] points = new Vector3[edge.points.Length]; - for (int i = 0; i < edge.points.Length; i++) - { - points[i] = edge.transform.TransformPoint(edge.points[i]); - } - - line.SetVertexCount(points.Length); - line.SetPositions(points); - } - - return line; - } - - private bool IsChildOf(GameObject child, GameObject parent) - { - if (child == null || parent == null) - { - return false; - } - - Transform t = child.transform; - - while (t != null) - { - if (t.gameObject == parent) - { - return true; - } - - t = t.parent; - } - - return false; - } - } -} From b28018e39e6f225d75ef8ab085da2b91555ecf52 Mon Sep 17 00:00:00 2001 From: DemoJameson Date: Sat, 5 Jun 2021 11:11:26 +0800 Subject: [PATCH 41/91] Add "Toggle Camera Shake" feature --- Source/BindableFunctions.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 65a54ce..5fb92b1 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -300,6 +300,14 @@ public static void ToggleHUD() } } + [BindableMethod(name = "Toggle Camera Shake", category = "Visual")] + public static void ToggleCameraShake() + { + bool newValue = !GameCameras.instance.cameraShakeFSM.enabled; + GameCameras.instance.cameraShakeFSM.enabled = newValue; + Console.AddLine($"{(newValue ? "Enabling" : "Disabling")} Camera Shake..."); + } + [BindableMethod(name = "Reset Camera Zoom", category = "Visual")] public static void ResetZoom() { From 13b021cc90929ef91be1df621dec1641d4b3b0ea Mon Sep 17 00:00:00 2001 From: DemoJameson Date: Sat, 5 Jun 2021 23:59:51 +0800 Subject: [PATCH 42/91] Draw baby flukes attack hitboxes --- Source/Hitbox/HitboxRender.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Hitbox/HitboxRender.cs b/Source/Hitbox/HitboxRender.cs index 68ba1b6..8359c2e 100644 --- a/Source/Hitbox/HitboxRender.cs +++ b/Source/Hitbox/HitboxRender.cs @@ -88,7 +88,7 @@ private void TryAddHitboxes(Collider2D collider2D) } else if (go == HeroController.instance?.gameObject && !collider2D.isTrigger) { colliders[HitboxType.Knight].Add(collider2D); - } else if (go.LocateMyFSM("damages_enemy")) + } else if (go.LocateMyFSM("damages_enemy") || go.name == "Damager" && go.LocateMyFSM("Damage")) { colliders[HitboxType.Attack].Add(collider2D); } else if (collider2D.isTrigger && (collider2D.GetComponent() || collider2D.GetComponent())) From 9b093bf0b17e4aedd7b5d74c91994191faa1220b Mon Sep 17 00:00:00 2001 From: DemoJameson Date: Sun, 6 Jun 2021 00:15:56 +0800 Subject: [PATCH 43/91] Fix the radius of circular hitboxes are sometimes inaccurate --- Source/Hitbox/HitboxRender.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Hitbox/HitboxRender.cs b/Source/Hitbox/HitboxRender.cs index 8359c2e..bceadad 100644 --- a/Source/Hitbox/HitboxRender.cs +++ b/Source/Hitbox/HitboxRender.cs @@ -179,9 +179,9 @@ private void DrawHitbox(Camera camera, Collider2D collider2D, HitboxType hitboxT { Vector2 offset = circleCollider2D.offset; Vector2 center = LocalToScreenPoint(camera, collider2D, offset); - Vector2 centerRight = LocalToScreenPoint(camera, collider2D, new Vector2(offset.x + circleCollider2D.radius, offset.y)); - int radius = (int) Math.Round(Math.Abs(centerRight.x - center.x)); - Drawing.DrawCircle(center, radius, hitboxType.Color, lineWidth, true, Math.Max(8, radius / 16)); + Vector2 right = LocalToScreenPoint(camera, collider2D, new Vector2(offset.x + circleCollider2D.radius, offset.y)); + int radius = (int) Math.Round(Vector2.Distance(center, right)); + Drawing.DrawCircle(center, radius, hitboxType.Color, lineWidth, true, Mathf.Clamp(radius / 16, 4, 32)); } GUI.depth = origDepth; From f0441540e82817f8effcbdfcae21498e7a798d2f Mon Sep 17 00:00:00 2001 From: cerpintext Date: Mon, 7 Jun 2021 02:09:27 +0200 Subject: [PATCH 44/91] fixed some text pos --- Source/MinimalInfoPanel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/MinimalInfoPanel.cs b/Source/MinimalInfoPanel.cs index 006fcf8..3c586f3 100644 --- a/Source/MinimalInfoPanel.cs +++ b/Source/MinimalInfoPanel.cs @@ -39,9 +39,9 @@ public static void BuildMenu(GameObject canvas) altPanel.AddText("Alt Scene Name Label", "Scene Name", new Vector2(10f, 90f), Vector2.zero, GUIController.Instance.arial, 15); altPanel.AddText("Alt Current Save State Lable", "Current SaveState", new Vector2(10f, 110f), Vector2.zero, GUIController.Instance.arial, 15); - altPanel.AddText("Alt SaveState AutoSlot", "Autoslot", new Vector2(10f, 130f), Vector2.zero, GUIController.Instance.arial, 15); + //altPanel.AddText("Alt SaveState AutoSlot", "Autoslot", new Vector2(10f, 130f), Vector2.zero, GUIController.Instance.arial, 15); altPanel.AddText("Alt SaveState CurrentSlot", "Current slot", new Vector2(110f, 130f), Vector2.zero, GUIController.Instance.arial, 15); - altPanel.AddText("Alt WillHardfall", "Hardfall", new Vector2(10f, 150f), Vector2.zero, GUIController.Instance.arial, 15); + altPanel.AddText("Alt WillHardfall", "Hardfall", new Vector2(10f, 130f), Vector2.zero, GUIController.Instance.arial, 15); //Values altPanel.AddText("Vel", "", new Vector2(40f, 14f), Vector2.zero, GUIController.Instance.trajanNormal); From ba9a8cb255d2b25f44c791208842ef49c98b6ffc Mon Sep 17 00:00:00 2001 From: cerpintext Date: Mon, 7 Jun 2021 03:25:09 +0200 Subject: [PATCH 45/91] version up + added credits to readme --- README.md | 26 ++++++++++++++------------ Source/DebugMod.cs | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 85b906e..722bbcb 100644 --- a/README.md +++ b/README.md @@ -80,22 +80,24 @@ Specifies slot number, then loads savestate from that file directly. Known Issues ---------------------------------------------------------------------------------------- ## Savestates: -* Charm effects not updating properly after loading savestates +* Charm effects not updating properly after loading savestates. Workaround: quitout and load back in or bench to manually apply the new charms. * UI not refreshing properly to remove obsolete vessel fragments -* Soul meter stuck at full if in that state before loading +* ~~Soul meter stuck at full if in that state before loading~~ * Softlocks if loading savestate during dream transitions -* If loading savestate during transition visual glitch. Either press 'esc' twice to get control of the knight and walk through a transition if this happens, or quit to menu and load back in before loading the savestate +* If loading savestate during transition visuals will not load. Either press 'esc' twice to get control of the knight and walk through a transition if this happens, or quit to menu and load back in before loading the savestate * (All savestates are loaded in RAM, which means fast loading from savestates fetched from files BUT potentially general performance issues) ---------------------------------------------------------------------------------------- CREDITS ---------------------------------------------------------------------------------------- -Seresharp -56 -Yurihaia -Krythom -The Embraced One -Katie -KeinZantezuken -MyEyes/Firzen -Cerpintext +Seresharp +56 +Yurihaia +Krythom +The Embraced One +Katie +KeinZantezuken +MyEyes/Firzen +Cerpintext +Mulhima +DemoJameson \ No newline at end of file diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 0490d63..22106b8 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -170,7 +170,7 @@ public override void Initialize() public override string GetVersion() { - return "1.4.2"; + return "1.4.3"; } public override bool IsCurrent() From 26643d1d7e2aab39ec5e68fe3a23e3dcee0fc466 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Fri, 24 Sep 2021 18:08:33 -0400 Subject: [PATCH 46/91] Add savestate pages. added 10 pages of 10 (max) savestates, added binds to scroll through pages, edited readme to reflect said changes. other --- README.md | 78 ++++++++------ Source/BindableFunctions.cs | 28 +++++- Source/Drawing.cs | 187 ++++++++++++++++++++++++++++++++++ Source/HitboxRender.cs | 190 +++++++++++++++++++++++++++++++++++ Source/HitboxViewer.cs | 58 +++++++++++ Source/Resources.Designer.cs | 63 ++++++++++++ Source/SaveState.cs | 2 +- Source/SaveStateManager.cs | 23 +++-- Source/SaveStatesPanel.cs | 7 +- Source/Settings.cs | 5 +- 10 files changed, 591 insertions(+), 50 deletions(-) create mode 100644 Source/Drawing.cs create mode 100644 Source/HitboxRender.cs create mode 100644 Source/HitboxViewer.cs create mode 100644 Source/Resources.Designer.cs diff --git a/README.md b/README.md index 722bbcb..88e4738 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,46 @@ + +# This is a modification of DebugMod. by default, it will not use your old savestates. Dont panic, they didn't get deleted. + +---------------------------------------------------------------------------------------- + SAVESTATE BASICS +---------------------------------------------------------------------------------------- + +## Savestates +In order to acess your new save-states, bind Next Page and Prev Page to a key (2nd page of binds in debug mod) +There are 10 pages of 10 savestates. +Prev/Next Page will scroll through these. +then, just do what you would do in normal debug mod to save and load states. + +To use your old savestates, go to this folder %APPDATA%\..\LocalLow\Team Cherry\Hollow Knight\Savestates-1221 +copy the files in this folder into the folder labeled 0 ( if it doesn't exist, make it. ) +Start the game and you will have your old saves plus the 90 empty slots. + +*If you have performance issues, please report it.* + +To use numpad for slot select; after installing debugmod, start and stop the game, +then go to the Hollow Knight saves-directory and open the `DebugMod.GlobalSettings` json-file. +In that file find `"NumPadForSaveStates"`, and change the corresponding value from 0 to 1. + +To change the amount of available Savestate-slots per page (default: 6), find `MaxSaveStates` and set the corresponding value between 0 and 10 respective of how many slots you want. + +Savestates files are located in `%APPDATA%\..\LocalLow\Team Cherry\Hollow Knight\Savestates-1221\`. They use the name format `savestate.json`. +After saving a savestate to file, you can edit the name of that savestate. To do this, open the file in any text-editor, and the first variable/line should be something like `"saveStateIdentifier": "",`. Change `` inside the pair of `"`-s to whatever you want that savestate named in the select savestate in-game menu. + +## Quickslot: +The main savestate used. Not saved permanently, cleared when the game restarts. + +## Quickslot save to file +Specifies slot number, then saves the current Quickslot from temporary memory to a numbered json-file in the game save directory, overwriting any files with identical number as the selected one. + +## Load file to quickslot +Asks to specify slot number, then reads the json-file with that number from the game save directory and loads it into the Quickslot, overwriting any current savestate there. + +## Save new state to file +Specifies slot number, then makes a new savestate and saves to a json-file with the given slot number. + +## Load new state from file +Specifies slot number, then loads savestate from that file directly. + ---------------------------------------------------------------------------------------- FEATURES ---------------------------------------------------------------------------------------- @@ -44,38 +87,6 @@ 1) Make a folder `Source/References/`, then 2) add `Assembly-CSharp.dll` (with modding-api), and `PlayMaker.dll`, `UnityEngine.dll` and `UnityEngine.UI.dll` from your `Hollow Knight/hollow_knight_Data/Managed/`-folder ----------------------------------------------------------------------------------------- - SAVESTATE BASICS ----------------------------------------------------------------------------------------- - -## Savestates - -*If you have performance issues, please report it.* - -To use numpad for slot select; after installing debugmod, start and stop the game, -then go to the Hollow Knight saves-directory and open the `DebugMod.GlobalSettings` json-file. -In that file find `"NumPadForSaveStates"`, and change the corresponding value from 0 to 1. - -To change the amount of available Savestate-slots (default: 6), find `MaxSaveStates` and set the corresponding value between 0 and 10 respective of how many slots you want. - -Savestates files are located in `%APPDATA%\..\LocalLow\Team Cherry\Hollow Knight\Savestates-1221\`. They use the name format `savestate.json`. -After saving a savestate to file, you can edit the name of that savestate. To do this, open the file in any text-editor, and the first variable/line should be something like `"saveStateIdentifier": "",`. Change `` inside the pair of `"`-s to whatever you want that savestate named in the select savestate in-game menu. - -## Quickslot: -The main savestate used. Not saved permanently, cleared when the game restarts. - -## Quickslot save to file -Specifies slot number, then saves the current Quickslot from temporary memory to a numbered json-file in the game save directory, overwriting any files with identical number as the selected one. - -## Load file to quickslot -Asks to specify slot number, then reads the json-file with that number from the game save directory and loads it into the Quickslot, overwriting any current savestate there. - -## Save new state to file -Specifies slot number, then makes a new savestate and saves to a json-file with the given slot number. - -## Load new state from file -Specifies slot number, then loads savestate from that file directly. - ---------------------------------------------------------------------------------------- Known Issues ---------------------------------------------------------------------------------------- @@ -100,4 +111,5 @@ KeinZantezuken MyEyes/Firzen Cerpintext Mulhima -DemoJameson \ No newline at end of file +DemoJameson + diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 5fb92b1..cc8457f 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -14,7 +14,6 @@ public static class BindableFunctions { private static readonly FieldInfo TimeSlowed = typeof(GameManager).GetField("timeSlowed", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); private static readonly FieldInfo IgnoreUnpause = typeof(UIManager).GetField("ignoreUnpause", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); - internal static readonly FieldInfo cameraGameplayScene = typeof(CameraController).GetField("isGameplayScene", BindingFlags.Instance | BindingFlags.NonPublic); #region Misc @@ -233,11 +232,36 @@ public static void LoadFromFile() { DebugMod.saveStateManager.LoadState(SaveStateType.SkipOne); } + [BindableMethod(name = "Next Save Page", category = "Savestates")] + public static void NextStatePage() + { + SaveStateManager.currentStateFolder++; + if (SaveStateManager.currentStateFolder == SaveStateManager.savePages) { SaveStateManager.currentStateFolder = 0; } //rollback to 0 if 10, keep folder between 0 and 9 + SaveStateManager.path = ( + Application.persistentDataPath + + "/Savestates-1221/" + + SaveStateManager.currentStateFolder.ToString() + + "/"); //change path + DebugMod.saveStateManager.RefreshStateMenu(); // updaate menu + } + [BindableMethod(name = "Prev Save Page", category = "Savestates")] + public static void PrevStatePage() + { + SaveStateManager.currentStateFolder--; + if (SaveStateManager.currentStateFolder == -1) { SaveStateManager.currentStateFolder = SaveStateManager.savePages-1; } //rollback to max if past limit, keep folder between 0 and 9 + SaveStateManager.path = ( + Application.persistentDataPath + + "/Savestates-1221/" + + SaveStateManager.currentStateFolder.ToString() + + "/"); //change path + DebugMod.saveStateManager.RefreshStateMenu(); // update menu + } + /* [BindableMethod(name = "Toggle auto slot", category = "Savestates")] public static void ToggleAutoSlot() - { + { DebugMod.saveStateManager.ToggleAutoSlot(); } diff --git a/Source/Drawing.cs b/Source/Drawing.cs new file mode 100644 index 0000000..8bbb841 --- /dev/null +++ b/Source/Drawing.cs @@ -0,0 +1,187 @@ +using System.Reflection; +using UnityEngine; + +namespace DebugMod.Hitbox { + // Line drawing routine originally courtesy of Linusmartensson: + // http://forum.unity3d.com/threads/71979-Drawing-lines-in-the-editor + // + // Rewritten to improve performance by Yossarian King / August 2013. + // + // Circle drawing functionality added by Cherno + // http://answers.unity.com/answers/713428/view.html + // + // This version produces virtually identical results to the original (tested by drawing + // one over the other and observing errors of one pixel or less), but for large numbers + // of lines this version is more than four times faster than the original, and comes + // within about 70% of the raw performance of Graphics.DrawTexture. + // + // Peak performance on my laptop is around 200,000 lines per second. The laptop is + // Windows 7 64-bit, Intel Core2 Duo CPU 2.53GHz, 4G RAM, NVIDIA GeForce GT 220M. + // Line width and anti-aliasing had negligible impact on performance. + // + // For a graph of benchmark results in a standalone Windows build, see this image: + // https://app.box.com/s/hyuhi565dtolqdm97e00 + // + // For a Google spreadsheet with full benchmark results, see: + // https://docs.google.com/spreadsheet/ccc?key=0AvJlJlbRO26VdHhzeHNRMVF2UHZHMXFCTVFZN011V1E&usp=sharing + + public static class Drawing { + private static Texture2D aaLineTex = null; + private static Texture2D lineTex = null; + private static Material blitMaterial = null; + private static Material blendMaterial = null; + private static Rect lineRect = new Rect(0, 0, 1, 1); + + // Draw a line in screen space, suitable for use from OnGUI calls from either + // MonoBehaviour or EditorWindow. Note that this should only be called during repaint + // events, when (Event.current.type == EventType.Repaint). + // + // Works by computing a matrix that transforms a unit square -- Rect(0,0,1,1) -- into + // a scaled, rotated, and offset rectangle that corresponds to the line and its width. + // A DrawTexture call used to draw a line texture into the transformed rectangle. + // + // More specifically: + // scale x by line length, y by line width + // rotate around z by the angle of the line + // offset by the position of the upper left corner of the target rectangle + // + // By working out the matrices and applying some trigonometry, the matrix calculation comes + // out pretty simple. See https://app.box.com/s/xi08ow8o8ujymazg100j for a picture of my + // notebook with the calculations. + public static void DrawLine(Vector2 pointA, Vector2 pointB, Color color, float width, bool antiAlias) { + // Normally the static initializer does this, but to handle texture reinitialization + // after editor play mode stops we need this check in the Editor. +#if UNITY_EDITOR + if (!lineTex) + { + Initialize(); + } +#endif + + // Note that theta = atan2(dy, dx) is the angle we want to rotate by, but instead + // of calculating the angle we just use the sine (dy/len) and cosine (dx/len). + float dx = pointB.x - pointA.x; + float dy = pointB.y - pointA.y; + float len = Mathf.Sqrt(dx * dx + dy * dy); + + // Early out on tiny lines to avoid divide by zero. + // Plus what's the point of drawing a line 1/1000th of a pixel long?? + if (len < 0.001f) { + return; + } + + // Pick texture and material (and tweak width) based on anti-alias setting. + Texture2D tex; + Material mat; + if (antiAlias) { + // Multiplying by three is fine for anti-aliasing width-1 lines, but make a wide "fringe" + // for thicker lines, which may or may not be desirable. + width = width * 3.0f; + tex = aaLineTex; + mat = blendMaterial; + } else { + tex = lineTex; + mat = blitMaterial; + } + + float wdx = width * dy / len; + float wdy = width * dx / len; + + Matrix4x4 matrix = Matrix4x4.identity; + matrix.m00 = dx; + matrix.m01 = -wdx; + matrix.m03 = pointA.x + 0.5f * wdx; + matrix.m10 = dy; + matrix.m11 = wdy; + matrix.m13 = pointA.y - 0.5f * wdy; + + // Use GL matrix and Graphics.DrawTexture rather than GUI.matrix and GUI.DrawTexture, + // for better performance. (Setting GUI.matrix is slow, and GUI.DrawTexture is just a + // wrapper on Graphics.DrawTexture.) + GL.PushMatrix(); + GL.MultMatrix(matrix); + + Graphics.DrawTexture(lineRect, tex, lineRect, 0, 0, 0, 0, color, mat); + // 启用抗锯齿时颜色似乎是半透明的,所以重复绘制一次使其更清晰 + if (antiAlias) { + Graphics.DrawTexture(lineRect, tex, lineRect, 0, 0, 0, 0, color, mat); + } + + GL.PopMatrix(); + } + + public static void DrawCircle(Vector2 center, int radius, Color color, float width, int segmentsPerQuarter) { + DrawCircle(center, radius, color, width, false, segmentsPerQuarter); + } + + public static void DrawCircle(Vector2 center, int radius, Color color, float width, bool antiAlias, int segmentsPerQuarter) { + float rh = (float) radius * 0.551915024494f; + + Vector2 p1 = new Vector2(center.x, center.y - radius); + Vector2 p1_tan_a = new Vector2(center.x - rh, center.y - radius); + Vector2 p1_tan_b = new Vector2(center.x + rh, center.y - radius); + + Vector2 p2 = new Vector2(center.x + radius, center.y); + Vector2 p2_tan_a = new Vector2(center.x + radius, center.y - rh); + Vector2 p2_tan_b = new Vector2(center.x + radius, center.y + rh); + + Vector2 p3 = new Vector2(center.x, center.y + radius); + Vector2 p3_tan_a = new Vector2(center.x - rh, center.y + radius); + Vector2 p3_tan_b = new Vector2(center.x + rh, center.y + radius); + + Vector2 p4 = new Vector2(center.x - radius, center.y); + Vector2 p4_tan_a = new Vector2(center.x - radius, center.y - rh); + Vector2 p4_tan_b = new Vector2(center.x - radius, center.y + rh); + + DrawBezierLine(p1, p1_tan_b, p2, p2_tan_a, color, width, antiAlias, segmentsPerQuarter); + DrawBezierLine(p2, p2_tan_b, p3, p3_tan_b, color, width, antiAlias, segmentsPerQuarter); + DrawBezierLine(p3, p3_tan_a, p4, p4_tan_b, color, width, antiAlias, segmentsPerQuarter); + DrawBezierLine(p4, p4_tan_a, p1, p1_tan_a, color, width, antiAlias, segmentsPerQuarter); + } + + // Other than method name, DrawBezierLine is unchanged from Linusmartensson's original implementation. + public static void DrawBezierLine(Vector2 start, Vector2 startTangent, Vector2 end, Vector2 endTangent, Color color, float width, + bool antiAlias, int segments) { + Vector2 lastV = CubeBezier(start, startTangent, end, endTangent, 0); + for (int i = 1; i < segments + 1; ++i) { + Vector2 v = CubeBezier(start, startTangent, end, endTangent, i / (float) segments); + DrawLine(lastV, v, color, width, antiAlias); + lastV = v; + } + } + + + private static Vector2 CubeBezier(Vector2 s, Vector2 st, Vector2 e, Vector2 et, float t) { + float rt = 1 - t; + return rt * rt * rt * s + 3 * rt * rt * t * st + 3 * rt * t * t * et + t * t * t * e; + } + + // This static initializer works for runtime, but apparently isn't called when + // Editor play mode stops, so DrawLine will re-initialize if needed. + static Drawing() { + Initialize(); + } + + private static void Initialize() { + if (lineTex == null) { + lineTex = new Texture2D(1, 1, TextureFormat.ARGB32, false); + lineTex.SetPixel(0, 1, Color.white); + lineTex.Apply(); + } + + if (aaLineTex == null) { + // TODO: better anti-aliasing of wide lines with a larger texture? or use Graphics.DrawTexture with border settings + aaLineTex = new Texture2D(1, 3, TextureFormat.ARGB32, false); + aaLineTex.SetPixel(0, 0, new Color(1, 1, 1, 0)); + aaLineTex.SetPixel(0, 1, Color.white); + aaLineTex.SetPixel(0, 2, new Color(1, 1, 1, 0)); + aaLineTex.Apply(); + } + + // GUI.blitMaterial and GUI.blendMaterial are used internally by GUI.DrawTexture, + // depending on the alphaBlend parameter. Use reflection to "borrow" these references. + blitMaterial = (Material) typeof(GUI).GetMethod("get_blitMaterial", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null); + blendMaterial = (Material) typeof(GUI).GetMethod("get_blendMaterial", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null); + } + } +} \ No newline at end of file diff --git a/Source/HitboxRender.cs b/Source/HitboxRender.cs new file mode 100644 index 0000000..bceadad --- /dev/null +++ b/Source/HitboxRender.cs @@ -0,0 +1,190 @@ +using System; +using System.Collections.Generic; +using GlobalEnums; +using UnityEngine; + +namespace DebugMod.Hitbox +{ + public class HitboxRender : MonoBehaviour + { + // ReSharper disable once StructCanBeMadeReadOnly + private struct HitboxType: IComparable + { + public static readonly HitboxType Knight = new(Color.yellow, 0); + public static readonly HitboxType Enemy = new(new Color(0.8f, 0, 0), 1); + public static readonly HitboxType Attack = new(Color.cyan, 2); + public static readonly HitboxType Terrain = new(new Color(0, 0.8f, 0), 3); + public static readonly HitboxType Trigger = new(new Color(0.5f, 0.5f, 1f), 4); + public static readonly HitboxType Other = new(new Color(0.9f, 0.6f, 0.4f), 5); + + public readonly Color Color; + public readonly int Depth; + + private HitboxType(Color color, int depth) + { + Color = color; + Depth = depth; + } + + public int CompareTo(HitboxType other) + { + return other.Depth.CompareTo(Depth); + } + } + + private readonly SortedDictionary> colliders = new() + { + {HitboxType.Knight, new HashSet()}, + {HitboxType.Enemy, new HashSet()}, + {HitboxType.Attack, new HashSet()}, + {HitboxType.Terrain, new HashSet()}, + {HitboxType.Trigger, new HashSet()}, + {HitboxType.Other, new HashSet()}, + }; + + private float LineWidth => Math.Max(0.7f, Screen.width / 960f * GameCameras.instance.tk2dCam.ZoomFactor); + + private void Start() + { + foreach (Collider2D col in Resources.FindObjectsOfTypeAll()) + { + TryAddHitboxes(col); + } + } + + public void UpdateHitbox(GameObject go) + { + foreach (Collider2D col in go.GetComponentsInChildren(true)) + { + TryAddHitboxes(col); + } + } + + private Vector2 LocalToScreenPoint(Camera camera, Collider2D collider2D, Vector2 point) + { + Vector2 result = camera.WorldToScreenPoint(collider2D.transform.TransformPoint(point + collider2D.offset)); + return new Vector2((int) Math.Round(result.x), (int) Math.Round(Screen.height - result.y)); + } + + private void TryAddHitboxes(Collider2D collider2D) + { + if (collider2D == null) + { + return; + } + + if (collider2D is BoxCollider2D or PolygonCollider2D or EdgeCollider2D or CircleCollider2D) + { + GameObject go = collider2D.gameObject; + if (collider2D.GetComponent() || collider2D.gameObject.LocateMyFSM("damages_hero")) + { + colliders[HitboxType.Enemy].Add(collider2D); + } else if (go.LocateMyFSM("health_manager_enemy") || go.LocateMyFSM("health_manager")) + { + colliders[HitboxType.Other].Add(collider2D); + } else if (go.layer == (int) PhysLayers.TERRAIN) + { + colliders[HitboxType.Terrain].Add(collider2D); + } else if (go == HeroController.instance?.gameObject && !collider2D.isTrigger) + { + colliders[HitboxType.Knight].Add(collider2D); + } else if (go.LocateMyFSM("damages_enemy") || go.name == "Damager" && go.LocateMyFSM("Damage")) + { + colliders[HitboxType.Attack].Add(collider2D); + } else if (collider2D.isTrigger && (collider2D.GetComponent() || collider2D.GetComponent())) + { + colliders[HitboxType.Trigger].Add(collider2D); + } else if (collider2D.GetComponent()) + { + NonBouncer bounce = collider2D.GetComponent(); + if (bounce == null || !bounce.active) + { + colliders[HitboxType.Trigger].Add(collider2D); + } + } else if (HitboxViewer.State == 2) + { + colliders[HitboxType.Other].Add(collider2D); + } + } + } + + private void OnGUI() + { + if (Event.current?.type != EventType.Repaint || GameManager.instance.isPaused || Camera.main == null) + { + return; + } + + GUI.depth = int.MaxValue; + Camera camera = Camera.main; + float lineWidth = LineWidth; + foreach (var pair in colliders) + { + foreach (Collider2D collider2D in pair.Value) + { + DrawHitbox(camera, collider2D, pair.Key, lineWidth); + } + } + } + + private void DrawHitbox(Camera camera, Collider2D collider2D, HitboxType hitboxType, float lineWidth) + { + if (collider2D == null || !collider2D.isActiveAndEnabled) + { + return; + } + + int origDepth = GUI.depth; + GUI.depth = hitboxType.Depth; + if (collider2D is BoxCollider2D or EdgeCollider2D or PolygonCollider2D) + { + List points = null; + switch (collider2D) + { + case BoxCollider2D boxCollider2D: + { + Vector2 halfSize = boxCollider2D.size / 2f; + Vector2 topLeft = new(-halfSize.x, halfSize.y); + Vector2 topRight = halfSize; + Vector2 bottomRight = new(halfSize.x, -halfSize.y); + Vector2 bottomLeft = -halfSize; + points = new List + { + topLeft, topRight, bottomRight, bottomLeft, topLeft + }; + break; + } + case EdgeCollider2D edgeCollider2D: + points = new List(edgeCollider2D.points); + break; + case PolygonCollider2D polygonCollider2D: + { + points = new List(polygonCollider2D.points); + if (points.Count > 0) + { + points.Add(points[0]); + } + + break; + } + } + + for (int i = 0; i < points.Count - 1; i++) + { + Vector2 pointA = LocalToScreenPoint(camera, collider2D, points[i]); + Vector2 pointB = LocalToScreenPoint(camera, collider2D, points[i + 1]); + Drawing.DrawLine(pointA, pointB, hitboxType.Color, lineWidth, true); + } + } else if (collider2D is CircleCollider2D circleCollider2D) + { + Vector2 offset = circleCollider2D.offset; + Vector2 center = LocalToScreenPoint(camera, collider2D, offset); + Vector2 right = LocalToScreenPoint(camera, collider2D, new Vector2(offset.x + circleCollider2D.radius, offset.y)); + int radius = (int) Math.Round(Vector2.Distance(center, right)); + Drawing.DrawCircle(center, radius, hitboxType.Color, lineWidth, true, Mathf.Clamp(radius / 16, 4, 32)); + } + + GUI.depth = origDepth; + } + } +} \ No newline at end of file diff --git a/Source/HitboxViewer.cs b/Source/HitboxViewer.cs new file mode 100644 index 0000000..9293725 --- /dev/null +++ b/Source/HitboxViewer.cs @@ -0,0 +1,58 @@ +using Modding; +using UnityEngine; +using UnityEngine.SceneManagement; +using Object = UnityEngine.Object; + +namespace DebugMod.Hitbox +{ + public class HitboxViewer + { + public static int State { get; private set; } + private HitboxRender hitboxRender; + + public void Load() + { + State = DebugMod.settings.ShowHitBoxes; + Unload(); + UnityEngine.SceneManagement.SceneManager.activeSceneChanged += CreateHitboxRender; + ModHooks.Instance.ColliderCreateHook += UpdateHitboxRender; + CreateHitboxRender(); + } + + public void Unload() + { + State = DebugMod.settings.ShowHitBoxes; + UnityEngine.SceneManagement.SceneManager.activeSceneChanged -= CreateHitboxRender; + ModHooks.Instance.ColliderCreateHook -= UpdateHitboxRender; + DestroyHitboxRender(); + } + + private void CreateHitboxRender(Scene current, Scene next) => CreateHitboxRender(); + + private void CreateHitboxRender() + { + DestroyHitboxRender(); + if (GameManager.instance.IsGameplayScene()) + { + hitboxRender = new GameObject().AddComponent(); + } + } + + private void DestroyHitboxRender() + { + if (hitboxRender != null) + { + Object.Destroy(hitboxRender); + hitboxRender = null; + } + } + + private void UpdateHitboxRender(GameObject go) + { + if (hitboxRender != null) + { + hitboxRender.UpdateHitbox(go); + } + } + } +} \ No newline at end of file diff --git a/Source/Resources.Designer.cs b/Source/Resources.Designer.cs new file mode 100644 index 0000000..ea88a69 --- /dev/null +++ b/Source/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DebugMod.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DebugMod.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Source/SaveState.cs b/Source/SaveState.cs index a6d32c4..aab1eb1 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -84,7 +84,7 @@ public void SaveStateToFile(int paramSlot) File.WriteAllText ( string.Concat(new object[] { SaveStateManager.path, - "/savestate", + "savestate", paramSlot, ".json" }), diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index d333f8d..0da227a 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -27,11 +27,12 @@ public enum SaveStateType internal class SaveStateManager { public static int maxSaveStates = DebugMod.settings.MaxSaveStates; - + public static int currentStateFolder = 0; public static SaveState quickState; public static bool inSelectSlotState = false; // a mutex, in practice? + public static int savePages = 10; public static int currentStateSlot = -1; - public static string path = Application.persistentDataPath + "/Savestates-1221/"; + public static string path = Application.persistentDataPath + "/Savestates-1221/0/"; public static string currentStateOperation = null; private static string[] stateStrings = @@ -59,14 +60,16 @@ internal SaveStateManager() //autoSlot = false; DebugMod.settings.SaveStatePanelVisible = false; quickState = new SaveState(); - - if (!Directory.Exists(path)) + for (int i = 0; i <= savePages; i++) { - Directory.CreateDirectory(path); - } - else - { - RefreshStateMenu(); + if (!Directory.Exists(Application.persistentDataPath + "/Savestates-1221/" + i.ToString())) + { + Directory.CreateDirectory(Application.persistentDataPath + "/Savestates-1221/" + i.ToString()); + } + else + { + RefreshStateMenu(); + } } } catch (Exception) @@ -113,6 +116,7 @@ public void LoadState(SaveStateType stateType) } break; case SaveStateType.File or SaveStateType.SkipOne: + if (!inSelectSlotState) { RefreshStateMenu(); @@ -312,6 +316,7 @@ public void RefreshStateMenu() try { //SaveState tempSave = new SaveState(); + saveStateFiles.Clear(); string shortFileName; string[] files = Directory.GetFiles(path); //DebugMod.instance.Log( diff --git a/Source/SaveStatesPanel.cs b/Source/SaveStatesPanel.cs index dadd678..fdf3481 100644 --- a/Source/SaveStatesPanel.cs +++ b/Source/SaveStatesPanel.cs @@ -22,10 +22,10 @@ public static void BuildMenu(GameObject canvas) GUIController.Instance.images["BlankVertical"].height ) ); - + statePanel.AddText("CurrentFolder", "In slot "+(SaveStateManager.currentStateFolder + 1).ToString(), new Vector2(20,10), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("Mode", "mode: ", new Vector2(8, 20), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("currentmode", "-", new Vector2(60, 20), Vector2.zero, GUIController.Instance.arial, 15); - + for (int i = 0; i < SaveStateManager.maxSaveStates; i++) { //Labels @@ -58,7 +58,6 @@ public static void BuildMenu(GameObject canvas) statePanel.AddText("9", "", new Vector2(50f, 200f), Vector2.zero, GUIController.Instance.arial, 15); */ } - public static void Update() { if (statePanel == null) @@ -88,7 +87,7 @@ public static void Update() if (statePanel.active) { statePanel.GetText("currentmode").UpdateText(SaveStateManager.currentStateOperation); - + statePanel.GetText("CurrentFolder").UpdateText("In slot " + (SaveStateManager.currentStateFolder + 1).ToString()+"/"+SaveStateManager.savePages); for (int i = 0; i < SaveStateManager.maxSaveStates; i++) { statePanel.GetText(i.ToString()).UpdateText("open"); diff --git a/Source/Settings.cs b/Source/Settings.cs index c2a36a5..a6efec8 100644 --- a/Source/Settings.cs +++ b/Source/Settings.cs @@ -2,7 +2,10 @@ namespace DebugMod { - //Empty class required for DebugMod class definition + // + // + // + //class required for DebugMod class definition public class SaveSettings : IModSettings { } public class GlobalSettings : IModSettings From bed462f7938786469a11f10de29712b9cc4e4efc Mon Sep 17 00:00:00 2001 From: MagneticPizza <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Fri, 24 Sep 2021 18:11:50 -0400 Subject: [PATCH 47/91] Update README.md --- README.md | 55 ++++++++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 88e4738..eec0f9c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,29 @@ - -# This is a modification of DebugMod. by default, it will not use your old savestates. Dont panic, they didn't get deleted. - +---------------------------------------------------------------------------------------- + FEATURES +---------------------------------------------------------------------------------------- +* A toggleable UI in-game that provides the following functions: +* Cheats such as invincibility and noclip +* The ability to unlock all charms or repair broken ones +* Change which skills the player has +* Change which items the player has +* Give the player more of consumable resources such as geo and essence +* Respawn bosses +* Hold multiple dream gate positions +* Change the player's respawn point to anywhere in the current scene +* Recall to the set respawn point +* Kill all enemies +* Add HP bars to enemies +* Draw collision boxes for enemies +* Clone or delete any enemy +* Set an enemy's health to 9999 +* Change the player's nail damage +* Damage the player +* Change the camera zoom level +* Disable the in game HUD +* Make the player invisible +* Disable the lighting around the player +* Disable the vignette drawn around the player +* Change the time scale of the game ---------------------------------------------------------------------------------------- SAVESTATE BASICS ---------------------------------------------------------------------------------------- @@ -41,32 +64,6 @@ Specifies slot number, then makes a new savestate and saves to a json-file with ## Load new state from file Specifies slot number, then loads savestate from that file directly. ----------------------------------------------------------------------------------------- - FEATURES ----------------------------------------------------------------------------------------- -* A toggleable UI in-game that provides the following functions: -* Cheats such as invincibility and noclip -* The ability to unlock all charms or repair broken ones -* Change which skills the player has -* Change which items the player has -* Give the player more of consumable resources such as geo and essence -* Respawn bosses -* Hold multiple dream gate positions -* Change the player's respawn point to anywhere in the current scene -* Recall to the set respawn point -* Kill all enemies -* Add HP bars to enemies -* Draw collision boxes for enemies -* Clone or delete any enemy -* Set an enemy's health to 9999 -* Change the player's nail damage -* Damage the player -* Change the camera zoom level -* Disable the in game HUD -* Make the player invisible -* Disable the lighting around the player -* Disable the vignette drawn around the player -* Change the time scale of the game ---------------------------------------------------------------------------------------- INSTALLATION ---------------------------------------------------------------------------------------- From c53ac6110910c626348d21a601fce51209231a50 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Fri, 24 Sep 2021 18:13:37 -0400 Subject: [PATCH 48/91] Update README.md --- README.md | 92 ++++++++++++++++++++++++++----------------------------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 88e4738..4d4a4b0 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,3 @@ - -# This is a modification of DebugMod. by default, it will not use your old savestates. Dont panic, they didn't get deleted. - ----------------------------------------------------------------------------------------- - SAVESTATE BASICS ----------------------------------------------------------------------------------------- - -## Savestates -In order to acess your new save-states, bind Next Page and Prev Page to a key (2nd page of binds in debug mod) -There are 10 pages of 10 savestates. -Prev/Next Page will scroll through these. -then, just do what you would do in normal debug mod to save and load states. - -To use your old savestates, go to this folder %APPDATA%\..\LocalLow\Team Cherry\Hollow Knight\Savestates-1221 -copy the files in this folder into the folder labeled 0 ( if it doesn't exist, make it. ) -Start the game and you will have your old saves plus the 90 empty slots. - -*If you have performance issues, please report it.* - -To use numpad for slot select; after installing debugmod, start and stop the game, -then go to the Hollow Knight saves-directory and open the `DebugMod.GlobalSettings` json-file. -In that file find `"NumPadForSaveStates"`, and change the corresponding value from 0 to 1. - -To change the amount of available Savestate-slots per page (default: 6), find `MaxSaveStates` and set the corresponding value between 0 and 10 respective of how many slots you want. - -Savestates files are located in `%APPDATA%\..\LocalLow\Team Cherry\Hollow Knight\Savestates-1221\`. They use the name format `savestate.json`. -After saving a savestate to file, you can edit the name of that savestate. To do this, open the file in any text-editor, and the first variable/line should be something like `"saveStateIdentifier": "",`. Change `` inside the pair of `"`-s to whatever you want that savestate named in the select savestate in-game menu. - -## Quickslot: -The main savestate used. Not saved permanently, cleared when the game restarts. - -## Quickslot save to file -Specifies slot number, then saves the current Quickslot from temporary memory to a numbered json-file in the game save directory, overwriting any files with identical number as the selected one. - -## Load file to quickslot -Asks to specify slot number, then reads the json-file with that number from the game save directory and loads it into the Quickslot, overwriting any current savestate there. - -## Save new state to file -Specifies slot number, then makes a new savestate and saves to a json-file with the given slot number. - -## Load new state from file -Specifies slot number, then loads savestate from that file directly. - ---------------------------------------------------------------------------------------- FEATURES ---------------------------------------------------------------------------------------- @@ -73,10 +30,10 @@ Specifies slot number, then loads savestate from that file directly. ## (STEAM/GOG, WINDOWS) 1) Download the modding API for Hollow Knight 1.2.2.1 - At the time of writing, 1.2.2.1-41 is the most up-to-date release: https://cdn.discordapp.com/attachments/298798821402607618/817653175586783242/Assembly-CSharp.dll + At the time of writing, 1.2.2.1-41 is the most up-to-date release: https://cdn.discordapp.com/attachments/298798821402607618/817653175586783242/Assembly-CSharp.dll 2) Right click Hollow Knight in Steam -> Properties -> Local Files -> Browse Local Files - OR - In GOG galaxy 2 -> Click button to the right of Update -> Manage Installation -> Show Folder + OR + In GOG galaxy 2 -> Click button to the right of Update -> Manage Installation -> Show Folder 3) Create a backup of the game files located here 4) Copy the contents of the modding API zip into this folder (Overwrite files when asked) 5) Copy the contents of this zip into the folder (Overwrite files when asked) @@ -87,6 +44,46 @@ Specifies slot number, then loads savestate from that file directly. 1) Make a folder `Source/References/`, then 2) add `Assembly-CSharp.dll` (with modding-api), and `PlayMaker.dll`, `UnityEngine.dll` and `UnityEngine.UI.dll` from your `Hollow Knight/hollow_knight_Data/Managed/`-folder +---------------------------------------------------------------------------------------- + SAVESTATE BASICS +---------------------------------------------------------------------------------------- + +## Savestates +In order to acess your new save-states, bind Next Page and Prev Page to a key (2nd page of binds in debug mod) +There are 10 pages of 10 savestates. +Prev/Next Page will scroll through these. +then, just do what you would do in normal debug mod to save and load states. + +To use your old savestates, go to this folder %APPDATA%\..\LocalLow\Team Cherry\Hollow Knight\Savestates-1221 +copy the files in this folder into the folder labeled 0 ( if it doesn't exist, make it. ) +Start the game and you will have your old saves plus the 90 empty slots. + +*If you have performance issues, please report it.* + +To use numpad for slot select; after installing debugmod, start and stop the game, +then go to the Hollow Knight saves-directory and open the `DebugMod.GlobalSettings` json-file. +In that file find `"NumPadForSaveStates"`, and change the corresponding value from 0 to 1. + +To change the amount of available Savestate-slots per page (default: 6), find `MaxSaveStates` and set the corresponding value between 0 and 10 respective of how many slots you want. + +Savestates files are located in `%APPDATA%\..\LocalLow\Team Cherry\Hollow Knight\Savestates-1221\`. They use the name format `savestate.json`. +After saving a savestate to file, you can edit the name of that savestate. To do this, open the file in any text-editor, and the first variable/line should be something like `"saveStateIdentifier": "",`. Change `` inside the pair of `"`-s to whatever you want that savestate named in the select savestate in-game menu. + +## Quickslot: +The main savestate used. Not saved permanently, cleared when the game restarts. + +## Quickslot save to file +Specifies slot number, then saves the current Quickslot from temporary memory to a numbered json-file in the game save directory, overwriting any files with identical number as the selected one. + +## Load file to quickslot +Asks to specify slot number, then reads the json-file with that number from the game save directory and loads it into the Quickslot, overwriting any current savestate there. + +## Save new state to file +Specifies slot number, then makes a new savestate and saves to a json-file with the given slot number. + +## Load new state from file +Specifies slot number, then loads savestate from that file directly. + ---------------------------------------------------------------------------------------- Known Issues ---------------------------------------------------------------------------------------- @@ -111,5 +108,4 @@ KeinZantezuken MyEyes/Firzen Cerpintext Mulhima -DemoJameson - +DemoJameson \ No newline at end of file From bd1e33122b583079ff744f3b875f6c0261056c34 Mon Sep 17 00:00:00 2001 From: MagneticPizza <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Fri, 24 Sep 2021 18:15:02 -0400 Subject: [PATCH 49/91] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eec0f9c..7a26260 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ ---------------------------------------------------------------------------------------- ## Savestates -In order to acess your new save-states, bind Next Page and Prev Page to a key (2nd page of binds in debug mod) +In order to acess your new save-states, bind Next Page and Prev Page to a key (2nd page of keybinds) There are 10 pages of 10 savestates. Prev/Next Page will scroll through these. then, just do what you would do in normal debug mod to save and load states. From 4ea3afc5e0cd64f005d98e674ed32b239703b906 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Fri, 24 Sep 2021 18:22:00 -0400 Subject: [PATCH 50/91] fixing a dumb mistake --- Source/Drawing.cs | 187 ---------------------------------------- Source/HitboxRender.cs | 190 ----------------------------------------- Source/HitboxViewer.cs | 58 ------------- 3 files changed, 435 deletions(-) delete mode 100644 Source/Drawing.cs delete mode 100644 Source/HitboxRender.cs delete mode 100644 Source/HitboxViewer.cs diff --git a/Source/Drawing.cs b/Source/Drawing.cs deleted file mode 100644 index 8bbb841..0000000 --- a/Source/Drawing.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System.Reflection; -using UnityEngine; - -namespace DebugMod.Hitbox { - // Line drawing routine originally courtesy of Linusmartensson: - // http://forum.unity3d.com/threads/71979-Drawing-lines-in-the-editor - // - // Rewritten to improve performance by Yossarian King / August 2013. - // - // Circle drawing functionality added by Cherno - // http://answers.unity.com/answers/713428/view.html - // - // This version produces virtually identical results to the original (tested by drawing - // one over the other and observing errors of one pixel or less), but for large numbers - // of lines this version is more than four times faster than the original, and comes - // within about 70% of the raw performance of Graphics.DrawTexture. - // - // Peak performance on my laptop is around 200,000 lines per second. The laptop is - // Windows 7 64-bit, Intel Core2 Duo CPU 2.53GHz, 4G RAM, NVIDIA GeForce GT 220M. - // Line width and anti-aliasing had negligible impact on performance. - // - // For a graph of benchmark results in a standalone Windows build, see this image: - // https://app.box.com/s/hyuhi565dtolqdm97e00 - // - // For a Google spreadsheet with full benchmark results, see: - // https://docs.google.com/spreadsheet/ccc?key=0AvJlJlbRO26VdHhzeHNRMVF2UHZHMXFCTVFZN011V1E&usp=sharing - - public static class Drawing { - private static Texture2D aaLineTex = null; - private static Texture2D lineTex = null; - private static Material blitMaterial = null; - private static Material blendMaterial = null; - private static Rect lineRect = new Rect(0, 0, 1, 1); - - // Draw a line in screen space, suitable for use from OnGUI calls from either - // MonoBehaviour or EditorWindow. Note that this should only be called during repaint - // events, when (Event.current.type == EventType.Repaint). - // - // Works by computing a matrix that transforms a unit square -- Rect(0,0,1,1) -- into - // a scaled, rotated, and offset rectangle that corresponds to the line and its width. - // A DrawTexture call used to draw a line texture into the transformed rectangle. - // - // More specifically: - // scale x by line length, y by line width - // rotate around z by the angle of the line - // offset by the position of the upper left corner of the target rectangle - // - // By working out the matrices and applying some trigonometry, the matrix calculation comes - // out pretty simple. See https://app.box.com/s/xi08ow8o8ujymazg100j for a picture of my - // notebook with the calculations. - public static void DrawLine(Vector2 pointA, Vector2 pointB, Color color, float width, bool antiAlias) { - // Normally the static initializer does this, but to handle texture reinitialization - // after editor play mode stops we need this check in the Editor. -#if UNITY_EDITOR - if (!lineTex) - { - Initialize(); - } -#endif - - // Note that theta = atan2(dy, dx) is the angle we want to rotate by, but instead - // of calculating the angle we just use the sine (dy/len) and cosine (dx/len). - float dx = pointB.x - pointA.x; - float dy = pointB.y - pointA.y; - float len = Mathf.Sqrt(dx * dx + dy * dy); - - // Early out on tiny lines to avoid divide by zero. - // Plus what's the point of drawing a line 1/1000th of a pixel long?? - if (len < 0.001f) { - return; - } - - // Pick texture and material (and tweak width) based on anti-alias setting. - Texture2D tex; - Material mat; - if (antiAlias) { - // Multiplying by three is fine for anti-aliasing width-1 lines, but make a wide "fringe" - // for thicker lines, which may or may not be desirable. - width = width * 3.0f; - tex = aaLineTex; - mat = blendMaterial; - } else { - tex = lineTex; - mat = blitMaterial; - } - - float wdx = width * dy / len; - float wdy = width * dx / len; - - Matrix4x4 matrix = Matrix4x4.identity; - matrix.m00 = dx; - matrix.m01 = -wdx; - matrix.m03 = pointA.x + 0.5f * wdx; - matrix.m10 = dy; - matrix.m11 = wdy; - matrix.m13 = pointA.y - 0.5f * wdy; - - // Use GL matrix and Graphics.DrawTexture rather than GUI.matrix and GUI.DrawTexture, - // for better performance. (Setting GUI.matrix is slow, and GUI.DrawTexture is just a - // wrapper on Graphics.DrawTexture.) - GL.PushMatrix(); - GL.MultMatrix(matrix); - - Graphics.DrawTexture(lineRect, tex, lineRect, 0, 0, 0, 0, color, mat); - // 启用抗锯齿时颜色似乎是半透明的,所以重复绘制一次使其更清晰 - if (antiAlias) { - Graphics.DrawTexture(lineRect, tex, lineRect, 0, 0, 0, 0, color, mat); - } - - GL.PopMatrix(); - } - - public static void DrawCircle(Vector2 center, int radius, Color color, float width, int segmentsPerQuarter) { - DrawCircle(center, radius, color, width, false, segmentsPerQuarter); - } - - public static void DrawCircle(Vector2 center, int radius, Color color, float width, bool antiAlias, int segmentsPerQuarter) { - float rh = (float) radius * 0.551915024494f; - - Vector2 p1 = new Vector2(center.x, center.y - radius); - Vector2 p1_tan_a = new Vector2(center.x - rh, center.y - radius); - Vector2 p1_tan_b = new Vector2(center.x + rh, center.y - radius); - - Vector2 p2 = new Vector2(center.x + radius, center.y); - Vector2 p2_tan_a = new Vector2(center.x + radius, center.y - rh); - Vector2 p2_tan_b = new Vector2(center.x + radius, center.y + rh); - - Vector2 p3 = new Vector2(center.x, center.y + radius); - Vector2 p3_tan_a = new Vector2(center.x - rh, center.y + radius); - Vector2 p3_tan_b = new Vector2(center.x + rh, center.y + radius); - - Vector2 p4 = new Vector2(center.x - radius, center.y); - Vector2 p4_tan_a = new Vector2(center.x - radius, center.y - rh); - Vector2 p4_tan_b = new Vector2(center.x - radius, center.y + rh); - - DrawBezierLine(p1, p1_tan_b, p2, p2_tan_a, color, width, antiAlias, segmentsPerQuarter); - DrawBezierLine(p2, p2_tan_b, p3, p3_tan_b, color, width, antiAlias, segmentsPerQuarter); - DrawBezierLine(p3, p3_tan_a, p4, p4_tan_b, color, width, antiAlias, segmentsPerQuarter); - DrawBezierLine(p4, p4_tan_a, p1, p1_tan_a, color, width, antiAlias, segmentsPerQuarter); - } - - // Other than method name, DrawBezierLine is unchanged from Linusmartensson's original implementation. - public static void DrawBezierLine(Vector2 start, Vector2 startTangent, Vector2 end, Vector2 endTangent, Color color, float width, - bool antiAlias, int segments) { - Vector2 lastV = CubeBezier(start, startTangent, end, endTangent, 0); - for (int i = 1; i < segments + 1; ++i) { - Vector2 v = CubeBezier(start, startTangent, end, endTangent, i / (float) segments); - DrawLine(lastV, v, color, width, antiAlias); - lastV = v; - } - } - - - private static Vector2 CubeBezier(Vector2 s, Vector2 st, Vector2 e, Vector2 et, float t) { - float rt = 1 - t; - return rt * rt * rt * s + 3 * rt * rt * t * st + 3 * rt * t * t * et + t * t * t * e; - } - - // This static initializer works for runtime, but apparently isn't called when - // Editor play mode stops, so DrawLine will re-initialize if needed. - static Drawing() { - Initialize(); - } - - private static void Initialize() { - if (lineTex == null) { - lineTex = new Texture2D(1, 1, TextureFormat.ARGB32, false); - lineTex.SetPixel(0, 1, Color.white); - lineTex.Apply(); - } - - if (aaLineTex == null) { - // TODO: better anti-aliasing of wide lines with a larger texture? or use Graphics.DrawTexture with border settings - aaLineTex = new Texture2D(1, 3, TextureFormat.ARGB32, false); - aaLineTex.SetPixel(0, 0, new Color(1, 1, 1, 0)); - aaLineTex.SetPixel(0, 1, Color.white); - aaLineTex.SetPixel(0, 2, new Color(1, 1, 1, 0)); - aaLineTex.Apply(); - } - - // GUI.blitMaterial and GUI.blendMaterial are used internally by GUI.DrawTexture, - // depending on the alphaBlend parameter. Use reflection to "borrow" these references. - blitMaterial = (Material) typeof(GUI).GetMethod("get_blitMaterial", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null); - blendMaterial = (Material) typeof(GUI).GetMethod("get_blendMaterial", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null); - } - } -} \ No newline at end of file diff --git a/Source/HitboxRender.cs b/Source/HitboxRender.cs deleted file mode 100644 index bceadad..0000000 --- a/Source/HitboxRender.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System; -using System.Collections.Generic; -using GlobalEnums; -using UnityEngine; - -namespace DebugMod.Hitbox -{ - public class HitboxRender : MonoBehaviour - { - // ReSharper disable once StructCanBeMadeReadOnly - private struct HitboxType: IComparable - { - public static readonly HitboxType Knight = new(Color.yellow, 0); - public static readonly HitboxType Enemy = new(new Color(0.8f, 0, 0), 1); - public static readonly HitboxType Attack = new(Color.cyan, 2); - public static readonly HitboxType Terrain = new(new Color(0, 0.8f, 0), 3); - public static readonly HitboxType Trigger = new(new Color(0.5f, 0.5f, 1f), 4); - public static readonly HitboxType Other = new(new Color(0.9f, 0.6f, 0.4f), 5); - - public readonly Color Color; - public readonly int Depth; - - private HitboxType(Color color, int depth) - { - Color = color; - Depth = depth; - } - - public int CompareTo(HitboxType other) - { - return other.Depth.CompareTo(Depth); - } - } - - private readonly SortedDictionary> colliders = new() - { - {HitboxType.Knight, new HashSet()}, - {HitboxType.Enemy, new HashSet()}, - {HitboxType.Attack, new HashSet()}, - {HitboxType.Terrain, new HashSet()}, - {HitboxType.Trigger, new HashSet()}, - {HitboxType.Other, new HashSet()}, - }; - - private float LineWidth => Math.Max(0.7f, Screen.width / 960f * GameCameras.instance.tk2dCam.ZoomFactor); - - private void Start() - { - foreach (Collider2D col in Resources.FindObjectsOfTypeAll()) - { - TryAddHitboxes(col); - } - } - - public void UpdateHitbox(GameObject go) - { - foreach (Collider2D col in go.GetComponentsInChildren(true)) - { - TryAddHitboxes(col); - } - } - - private Vector2 LocalToScreenPoint(Camera camera, Collider2D collider2D, Vector2 point) - { - Vector2 result = camera.WorldToScreenPoint(collider2D.transform.TransformPoint(point + collider2D.offset)); - return new Vector2((int) Math.Round(result.x), (int) Math.Round(Screen.height - result.y)); - } - - private void TryAddHitboxes(Collider2D collider2D) - { - if (collider2D == null) - { - return; - } - - if (collider2D is BoxCollider2D or PolygonCollider2D or EdgeCollider2D or CircleCollider2D) - { - GameObject go = collider2D.gameObject; - if (collider2D.GetComponent() || collider2D.gameObject.LocateMyFSM("damages_hero")) - { - colliders[HitboxType.Enemy].Add(collider2D); - } else if (go.LocateMyFSM("health_manager_enemy") || go.LocateMyFSM("health_manager")) - { - colliders[HitboxType.Other].Add(collider2D); - } else if (go.layer == (int) PhysLayers.TERRAIN) - { - colliders[HitboxType.Terrain].Add(collider2D); - } else if (go == HeroController.instance?.gameObject && !collider2D.isTrigger) - { - colliders[HitboxType.Knight].Add(collider2D); - } else if (go.LocateMyFSM("damages_enemy") || go.name == "Damager" && go.LocateMyFSM("Damage")) - { - colliders[HitboxType.Attack].Add(collider2D); - } else if (collider2D.isTrigger && (collider2D.GetComponent() || collider2D.GetComponent())) - { - colliders[HitboxType.Trigger].Add(collider2D); - } else if (collider2D.GetComponent()) - { - NonBouncer bounce = collider2D.GetComponent(); - if (bounce == null || !bounce.active) - { - colliders[HitboxType.Trigger].Add(collider2D); - } - } else if (HitboxViewer.State == 2) - { - colliders[HitboxType.Other].Add(collider2D); - } - } - } - - private void OnGUI() - { - if (Event.current?.type != EventType.Repaint || GameManager.instance.isPaused || Camera.main == null) - { - return; - } - - GUI.depth = int.MaxValue; - Camera camera = Camera.main; - float lineWidth = LineWidth; - foreach (var pair in colliders) - { - foreach (Collider2D collider2D in pair.Value) - { - DrawHitbox(camera, collider2D, pair.Key, lineWidth); - } - } - } - - private void DrawHitbox(Camera camera, Collider2D collider2D, HitboxType hitboxType, float lineWidth) - { - if (collider2D == null || !collider2D.isActiveAndEnabled) - { - return; - } - - int origDepth = GUI.depth; - GUI.depth = hitboxType.Depth; - if (collider2D is BoxCollider2D or EdgeCollider2D or PolygonCollider2D) - { - List points = null; - switch (collider2D) - { - case BoxCollider2D boxCollider2D: - { - Vector2 halfSize = boxCollider2D.size / 2f; - Vector2 topLeft = new(-halfSize.x, halfSize.y); - Vector2 topRight = halfSize; - Vector2 bottomRight = new(halfSize.x, -halfSize.y); - Vector2 bottomLeft = -halfSize; - points = new List - { - topLeft, topRight, bottomRight, bottomLeft, topLeft - }; - break; - } - case EdgeCollider2D edgeCollider2D: - points = new List(edgeCollider2D.points); - break; - case PolygonCollider2D polygonCollider2D: - { - points = new List(polygonCollider2D.points); - if (points.Count > 0) - { - points.Add(points[0]); - } - - break; - } - } - - for (int i = 0; i < points.Count - 1; i++) - { - Vector2 pointA = LocalToScreenPoint(camera, collider2D, points[i]); - Vector2 pointB = LocalToScreenPoint(camera, collider2D, points[i + 1]); - Drawing.DrawLine(pointA, pointB, hitboxType.Color, lineWidth, true); - } - } else if (collider2D is CircleCollider2D circleCollider2D) - { - Vector2 offset = circleCollider2D.offset; - Vector2 center = LocalToScreenPoint(camera, collider2D, offset); - Vector2 right = LocalToScreenPoint(camera, collider2D, new Vector2(offset.x + circleCollider2D.radius, offset.y)); - int radius = (int) Math.Round(Vector2.Distance(center, right)); - Drawing.DrawCircle(center, radius, hitboxType.Color, lineWidth, true, Mathf.Clamp(radius / 16, 4, 32)); - } - - GUI.depth = origDepth; - } - } -} \ No newline at end of file diff --git a/Source/HitboxViewer.cs b/Source/HitboxViewer.cs deleted file mode 100644 index 9293725..0000000 --- a/Source/HitboxViewer.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Modding; -using UnityEngine; -using UnityEngine.SceneManagement; -using Object = UnityEngine.Object; - -namespace DebugMod.Hitbox -{ - public class HitboxViewer - { - public static int State { get; private set; } - private HitboxRender hitboxRender; - - public void Load() - { - State = DebugMod.settings.ShowHitBoxes; - Unload(); - UnityEngine.SceneManagement.SceneManager.activeSceneChanged += CreateHitboxRender; - ModHooks.Instance.ColliderCreateHook += UpdateHitboxRender; - CreateHitboxRender(); - } - - public void Unload() - { - State = DebugMod.settings.ShowHitBoxes; - UnityEngine.SceneManagement.SceneManager.activeSceneChanged -= CreateHitboxRender; - ModHooks.Instance.ColliderCreateHook -= UpdateHitboxRender; - DestroyHitboxRender(); - } - - private void CreateHitboxRender(Scene current, Scene next) => CreateHitboxRender(); - - private void CreateHitboxRender() - { - DestroyHitboxRender(); - if (GameManager.instance.IsGameplayScene()) - { - hitboxRender = new GameObject().AddComponent(); - } - } - - private void DestroyHitboxRender() - { - if (hitboxRender != null) - { - Object.Destroy(hitboxRender); - hitboxRender = null; - } - } - - private void UpdateHitboxRender(GameObject go) - { - if (hitboxRender != null) - { - hitboxRender.UpdateHitbox(go); - } - } - } -} \ No newline at end of file From 078abb528b63046297676a9a1a0f25e492ac0853 Mon Sep 17 00:00:00 2001 From: MagneticPizza <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Fri, 24 Sep 2021 18:23:18 -0400 Subject: [PATCH 51/91] Update README.md --- README.md | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 7a26260..0387096 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,32 @@ * Disable the lighting around the player * Disable the vignette drawn around the player * Change the time scale of the game +---------------------------------------------------------------------------------------- + INSTALLATION +---------------------------------------------------------------------------------------- + +## (STEAM/GOG, WINDOWS) +1) Download the modding API for Hollow Knight 1.2.2.1 + At the time of writing, 1.2.2.1-41 is the most up-to-date release: https://cdn.discordapp.com/attachments/298798821402607618/817653175586783242/Assembly-CSharp.dll +2) Right click Hollow Knight in Steam -> Properties -> Local Files -> Browse Local Files + OR + In GOG galaxy 2 -> Click button to the right of Update -> Manage Installation -> Show Folder +3) Create a backup of the game files located here +4) Copy the contents of the modding API zip into this folder (Overwrite files when asked) +5) Copy the contents of this zip into the folder (Overwrite files when asked) +6) This mod should not affect saves negatively, but it is a good idea to back them up anyway. + Saves are located at %AppData%\..\LocalLow\Team Cherry\Hollow Knight\ + +## How to build (for devs): +1) Make a folder `Source/References/`, then +2) add `Assembly-CSharp.dll` (with modding-api), and `PlayMaker.dll`, `UnityEngine.dll` and `UnityEngine.UI.dll` from your `Hollow Knight/hollow_knight_Data/Managed/`-folder + ---------------------------------------------------------------------------------------- SAVESTATE BASICS ---------------------------------------------------------------------------------------- ## Savestates -In order to acess your new save-states, bind Next Page and Prev Page to a key (2nd page of keybinds) +In order to acess your new save-states, bind Next Page and Prev Page to a key (2nd page of binds in debug mod) There are 10 pages of 10 savestates. Prev/Next Page will scroll through these. then, just do what you would do in normal debug mod to save and load states. @@ -64,26 +84,6 @@ Specifies slot number, then makes a new savestate and saves to a json-file with ## Load new state from file Specifies slot number, then loads savestate from that file directly. ----------------------------------------------------------------------------------------- - INSTALLATION ----------------------------------------------------------------------------------------- - -## (STEAM/GOG, WINDOWS) -1) Download the modding API for Hollow Knight 1.2.2.1 - At the time of writing, 1.2.2.1-41 is the most up-to-date release: https://cdn.discordapp.com/attachments/298798821402607618/817653175586783242/Assembly-CSharp.dll -2) Right click Hollow Knight in Steam -> Properties -> Local Files -> Browse Local Files - OR - In GOG galaxy 2 -> Click button to the right of Update -> Manage Installation -> Show Folder -3) Create a backup of the game files located here -4) Copy the contents of the modding API zip into this folder (Overwrite files when asked) -5) Copy the contents of this zip into the folder (Overwrite files when asked) -6) This mod should not affect saves negatively, but it is a good idea to back them up anyway. - Saves are located at %AppData%\..\LocalLow\Team Cherry\Hollow Knight\ - -## How to build (for devs): -1) Make a folder `Source/References/`, then -2) add `Assembly-CSharp.dll` (with modding-api), and `PlayMaker.dll`, `UnityEngine.dll` and `UnityEngine.UI.dll` from your `Hollow Knight/hollow_knight_Data/Managed/`-folder - ---------------------------------------------------------------------------------------- Known Issues ---------------------------------------------------------------------------------------- @@ -109,4 +109,3 @@ MyEyes/Firzen Cerpintext Mulhima DemoJameson - From 388a1ba24dc88448388584ead52bfe8571eecab1 Mon Sep 17 00:00:00 2001 From: MagneticPizza <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Fri, 24 Sep 2021 18:43:25 -0400 Subject: [PATCH 52/91] Delete HitboxRender.cs --- Source/HitboxRender.cs | 190 ----------------------------------------- 1 file changed, 190 deletions(-) delete mode 100644 Source/HitboxRender.cs diff --git a/Source/HitboxRender.cs b/Source/HitboxRender.cs deleted file mode 100644 index bceadad..0000000 --- a/Source/HitboxRender.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System; -using System.Collections.Generic; -using GlobalEnums; -using UnityEngine; - -namespace DebugMod.Hitbox -{ - public class HitboxRender : MonoBehaviour - { - // ReSharper disable once StructCanBeMadeReadOnly - private struct HitboxType: IComparable - { - public static readonly HitboxType Knight = new(Color.yellow, 0); - public static readonly HitboxType Enemy = new(new Color(0.8f, 0, 0), 1); - public static readonly HitboxType Attack = new(Color.cyan, 2); - public static readonly HitboxType Terrain = new(new Color(0, 0.8f, 0), 3); - public static readonly HitboxType Trigger = new(new Color(0.5f, 0.5f, 1f), 4); - public static readonly HitboxType Other = new(new Color(0.9f, 0.6f, 0.4f), 5); - - public readonly Color Color; - public readonly int Depth; - - private HitboxType(Color color, int depth) - { - Color = color; - Depth = depth; - } - - public int CompareTo(HitboxType other) - { - return other.Depth.CompareTo(Depth); - } - } - - private readonly SortedDictionary> colliders = new() - { - {HitboxType.Knight, new HashSet()}, - {HitboxType.Enemy, new HashSet()}, - {HitboxType.Attack, new HashSet()}, - {HitboxType.Terrain, new HashSet()}, - {HitboxType.Trigger, new HashSet()}, - {HitboxType.Other, new HashSet()}, - }; - - private float LineWidth => Math.Max(0.7f, Screen.width / 960f * GameCameras.instance.tk2dCam.ZoomFactor); - - private void Start() - { - foreach (Collider2D col in Resources.FindObjectsOfTypeAll()) - { - TryAddHitboxes(col); - } - } - - public void UpdateHitbox(GameObject go) - { - foreach (Collider2D col in go.GetComponentsInChildren(true)) - { - TryAddHitboxes(col); - } - } - - private Vector2 LocalToScreenPoint(Camera camera, Collider2D collider2D, Vector2 point) - { - Vector2 result = camera.WorldToScreenPoint(collider2D.transform.TransformPoint(point + collider2D.offset)); - return new Vector2((int) Math.Round(result.x), (int) Math.Round(Screen.height - result.y)); - } - - private void TryAddHitboxes(Collider2D collider2D) - { - if (collider2D == null) - { - return; - } - - if (collider2D is BoxCollider2D or PolygonCollider2D or EdgeCollider2D or CircleCollider2D) - { - GameObject go = collider2D.gameObject; - if (collider2D.GetComponent() || collider2D.gameObject.LocateMyFSM("damages_hero")) - { - colliders[HitboxType.Enemy].Add(collider2D); - } else if (go.LocateMyFSM("health_manager_enemy") || go.LocateMyFSM("health_manager")) - { - colliders[HitboxType.Other].Add(collider2D); - } else if (go.layer == (int) PhysLayers.TERRAIN) - { - colliders[HitboxType.Terrain].Add(collider2D); - } else if (go == HeroController.instance?.gameObject && !collider2D.isTrigger) - { - colliders[HitboxType.Knight].Add(collider2D); - } else if (go.LocateMyFSM("damages_enemy") || go.name == "Damager" && go.LocateMyFSM("Damage")) - { - colliders[HitboxType.Attack].Add(collider2D); - } else if (collider2D.isTrigger && (collider2D.GetComponent() || collider2D.GetComponent())) - { - colliders[HitboxType.Trigger].Add(collider2D); - } else if (collider2D.GetComponent()) - { - NonBouncer bounce = collider2D.GetComponent(); - if (bounce == null || !bounce.active) - { - colliders[HitboxType.Trigger].Add(collider2D); - } - } else if (HitboxViewer.State == 2) - { - colliders[HitboxType.Other].Add(collider2D); - } - } - } - - private void OnGUI() - { - if (Event.current?.type != EventType.Repaint || GameManager.instance.isPaused || Camera.main == null) - { - return; - } - - GUI.depth = int.MaxValue; - Camera camera = Camera.main; - float lineWidth = LineWidth; - foreach (var pair in colliders) - { - foreach (Collider2D collider2D in pair.Value) - { - DrawHitbox(camera, collider2D, pair.Key, lineWidth); - } - } - } - - private void DrawHitbox(Camera camera, Collider2D collider2D, HitboxType hitboxType, float lineWidth) - { - if (collider2D == null || !collider2D.isActiveAndEnabled) - { - return; - } - - int origDepth = GUI.depth; - GUI.depth = hitboxType.Depth; - if (collider2D is BoxCollider2D or EdgeCollider2D or PolygonCollider2D) - { - List points = null; - switch (collider2D) - { - case BoxCollider2D boxCollider2D: - { - Vector2 halfSize = boxCollider2D.size / 2f; - Vector2 topLeft = new(-halfSize.x, halfSize.y); - Vector2 topRight = halfSize; - Vector2 bottomRight = new(halfSize.x, -halfSize.y); - Vector2 bottomLeft = -halfSize; - points = new List - { - topLeft, topRight, bottomRight, bottomLeft, topLeft - }; - break; - } - case EdgeCollider2D edgeCollider2D: - points = new List(edgeCollider2D.points); - break; - case PolygonCollider2D polygonCollider2D: - { - points = new List(polygonCollider2D.points); - if (points.Count > 0) - { - points.Add(points[0]); - } - - break; - } - } - - for (int i = 0; i < points.Count - 1; i++) - { - Vector2 pointA = LocalToScreenPoint(camera, collider2D, points[i]); - Vector2 pointB = LocalToScreenPoint(camera, collider2D, points[i + 1]); - Drawing.DrawLine(pointA, pointB, hitboxType.Color, lineWidth, true); - } - } else if (collider2D is CircleCollider2D circleCollider2D) - { - Vector2 offset = circleCollider2D.offset; - Vector2 center = LocalToScreenPoint(camera, collider2D, offset); - Vector2 right = LocalToScreenPoint(camera, collider2D, new Vector2(offset.x + circleCollider2D.radius, offset.y)); - int radius = (int) Math.Round(Vector2.Distance(center, right)); - Drawing.DrawCircle(center, radius, hitboxType.Color, lineWidth, true, Mathf.Clamp(radius / 16, 4, 32)); - } - - GUI.depth = origDepth; - } - } -} \ No newline at end of file From 2aa65beefc182f7a52a0903f0569b9ca02a346ba Mon Sep 17 00:00:00 2001 From: MagneticPizza <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Fri, 24 Sep 2021 18:43:36 -0400 Subject: [PATCH 53/91] Delete HitboxViewer.cs --- Source/HitboxViewer.cs | 58 ------------------------------------------ 1 file changed, 58 deletions(-) delete mode 100644 Source/HitboxViewer.cs diff --git a/Source/HitboxViewer.cs b/Source/HitboxViewer.cs deleted file mode 100644 index 9293725..0000000 --- a/Source/HitboxViewer.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Modding; -using UnityEngine; -using UnityEngine.SceneManagement; -using Object = UnityEngine.Object; - -namespace DebugMod.Hitbox -{ - public class HitboxViewer - { - public static int State { get; private set; } - private HitboxRender hitboxRender; - - public void Load() - { - State = DebugMod.settings.ShowHitBoxes; - Unload(); - UnityEngine.SceneManagement.SceneManager.activeSceneChanged += CreateHitboxRender; - ModHooks.Instance.ColliderCreateHook += UpdateHitboxRender; - CreateHitboxRender(); - } - - public void Unload() - { - State = DebugMod.settings.ShowHitBoxes; - UnityEngine.SceneManagement.SceneManager.activeSceneChanged -= CreateHitboxRender; - ModHooks.Instance.ColliderCreateHook -= UpdateHitboxRender; - DestroyHitboxRender(); - } - - private void CreateHitboxRender(Scene current, Scene next) => CreateHitboxRender(); - - private void CreateHitboxRender() - { - DestroyHitboxRender(); - if (GameManager.instance.IsGameplayScene()) - { - hitboxRender = new GameObject().AddComponent(); - } - } - - private void DestroyHitboxRender() - { - if (hitboxRender != null) - { - Object.Destroy(hitboxRender); - hitboxRender = null; - } - } - - private void UpdateHitboxRender(GameObject go) - { - if (hitboxRender != null) - { - hitboxRender.UpdateHitbox(go); - } - } - } -} \ No newline at end of file From c5035d4f5778d573bcff9cbbad5783ae60c5474d Mon Sep 17 00:00:00 2001 From: MagneticPizza <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Fri, 24 Sep 2021 18:43:54 -0400 Subject: [PATCH 54/91] Delete Drawing.cs --- Source/Drawing.cs | 187 ---------------------------------------------- 1 file changed, 187 deletions(-) delete mode 100644 Source/Drawing.cs diff --git a/Source/Drawing.cs b/Source/Drawing.cs deleted file mode 100644 index 8bbb841..0000000 --- a/Source/Drawing.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System.Reflection; -using UnityEngine; - -namespace DebugMod.Hitbox { - // Line drawing routine originally courtesy of Linusmartensson: - // http://forum.unity3d.com/threads/71979-Drawing-lines-in-the-editor - // - // Rewritten to improve performance by Yossarian King / August 2013. - // - // Circle drawing functionality added by Cherno - // http://answers.unity.com/answers/713428/view.html - // - // This version produces virtually identical results to the original (tested by drawing - // one over the other and observing errors of one pixel or less), but for large numbers - // of lines this version is more than four times faster than the original, and comes - // within about 70% of the raw performance of Graphics.DrawTexture. - // - // Peak performance on my laptop is around 200,000 lines per second. The laptop is - // Windows 7 64-bit, Intel Core2 Duo CPU 2.53GHz, 4G RAM, NVIDIA GeForce GT 220M. - // Line width and anti-aliasing had negligible impact on performance. - // - // For a graph of benchmark results in a standalone Windows build, see this image: - // https://app.box.com/s/hyuhi565dtolqdm97e00 - // - // For a Google spreadsheet with full benchmark results, see: - // https://docs.google.com/spreadsheet/ccc?key=0AvJlJlbRO26VdHhzeHNRMVF2UHZHMXFCTVFZN011V1E&usp=sharing - - public static class Drawing { - private static Texture2D aaLineTex = null; - private static Texture2D lineTex = null; - private static Material blitMaterial = null; - private static Material blendMaterial = null; - private static Rect lineRect = new Rect(0, 0, 1, 1); - - // Draw a line in screen space, suitable for use from OnGUI calls from either - // MonoBehaviour or EditorWindow. Note that this should only be called during repaint - // events, when (Event.current.type == EventType.Repaint). - // - // Works by computing a matrix that transforms a unit square -- Rect(0,0,1,1) -- into - // a scaled, rotated, and offset rectangle that corresponds to the line and its width. - // A DrawTexture call used to draw a line texture into the transformed rectangle. - // - // More specifically: - // scale x by line length, y by line width - // rotate around z by the angle of the line - // offset by the position of the upper left corner of the target rectangle - // - // By working out the matrices and applying some trigonometry, the matrix calculation comes - // out pretty simple. See https://app.box.com/s/xi08ow8o8ujymazg100j for a picture of my - // notebook with the calculations. - public static void DrawLine(Vector2 pointA, Vector2 pointB, Color color, float width, bool antiAlias) { - // Normally the static initializer does this, but to handle texture reinitialization - // after editor play mode stops we need this check in the Editor. -#if UNITY_EDITOR - if (!lineTex) - { - Initialize(); - } -#endif - - // Note that theta = atan2(dy, dx) is the angle we want to rotate by, but instead - // of calculating the angle we just use the sine (dy/len) and cosine (dx/len). - float dx = pointB.x - pointA.x; - float dy = pointB.y - pointA.y; - float len = Mathf.Sqrt(dx * dx + dy * dy); - - // Early out on tiny lines to avoid divide by zero. - // Plus what's the point of drawing a line 1/1000th of a pixel long?? - if (len < 0.001f) { - return; - } - - // Pick texture and material (and tweak width) based on anti-alias setting. - Texture2D tex; - Material mat; - if (antiAlias) { - // Multiplying by three is fine for anti-aliasing width-1 lines, but make a wide "fringe" - // for thicker lines, which may or may not be desirable. - width = width * 3.0f; - tex = aaLineTex; - mat = blendMaterial; - } else { - tex = lineTex; - mat = blitMaterial; - } - - float wdx = width * dy / len; - float wdy = width * dx / len; - - Matrix4x4 matrix = Matrix4x4.identity; - matrix.m00 = dx; - matrix.m01 = -wdx; - matrix.m03 = pointA.x + 0.5f * wdx; - matrix.m10 = dy; - matrix.m11 = wdy; - matrix.m13 = pointA.y - 0.5f * wdy; - - // Use GL matrix and Graphics.DrawTexture rather than GUI.matrix and GUI.DrawTexture, - // for better performance. (Setting GUI.matrix is slow, and GUI.DrawTexture is just a - // wrapper on Graphics.DrawTexture.) - GL.PushMatrix(); - GL.MultMatrix(matrix); - - Graphics.DrawTexture(lineRect, tex, lineRect, 0, 0, 0, 0, color, mat); - // 启用抗锯齿时颜色似乎是半透明的,所以重复绘制一次使其更清晰 - if (antiAlias) { - Graphics.DrawTexture(lineRect, tex, lineRect, 0, 0, 0, 0, color, mat); - } - - GL.PopMatrix(); - } - - public static void DrawCircle(Vector2 center, int radius, Color color, float width, int segmentsPerQuarter) { - DrawCircle(center, radius, color, width, false, segmentsPerQuarter); - } - - public static void DrawCircle(Vector2 center, int radius, Color color, float width, bool antiAlias, int segmentsPerQuarter) { - float rh = (float) radius * 0.551915024494f; - - Vector2 p1 = new Vector2(center.x, center.y - radius); - Vector2 p1_tan_a = new Vector2(center.x - rh, center.y - radius); - Vector2 p1_tan_b = new Vector2(center.x + rh, center.y - radius); - - Vector2 p2 = new Vector2(center.x + radius, center.y); - Vector2 p2_tan_a = new Vector2(center.x + radius, center.y - rh); - Vector2 p2_tan_b = new Vector2(center.x + radius, center.y + rh); - - Vector2 p3 = new Vector2(center.x, center.y + radius); - Vector2 p3_tan_a = new Vector2(center.x - rh, center.y + radius); - Vector2 p3_tan_b = new Vector2(center.x + rh, center.y + radius); - - Vector2 p4 = new Vector2(center.x - radius, center.y); - Vector2 p4_tan_a = new Vector2(center.x - radius, center.y - rh); - Vector2 p4_tan_b = new Vector2(center.x - radius, center.y + rh); - - DrawBezierLine(p1, p1_tan_b, p2, p2_tan_a, color, width, antiAlias, segmentsPerQuarter); - DrawBezierLine(p2, p2_tan_b, p3, p3_tan_b, color, width, antiAlias, segmentsPerQuarter); - DrawBezierLine(p3, p3_tan_a, p4, p4_tan_b, color, width, antiAlias, segmentsPerQuarter); - DrawBezierLine(p4, p4_tan_a, p1, p1_tan_a, color, width, antiAlias, segmentsPerQuarter); - } - - // Other than method name, DrawBezierLine is unchanged from Linusmartensson's original implementation. - public static void DrawBezierLine(Vector2 start, Vector2 startTangent, Vector2 end, Vector2 endTangent, Color color, float width, - bool antiAlias, int segments) { - Vector2 lastV = CubeBezier(start, startTangent, end, endTangent, 0); - for (int i = 1; i < segments + 1; ++i) { - Vector2 v = CubeBezier(start, startTangent, end, endTangent, i / (float) segments); - DrawLine(lastV, v, color, width, antiAlias); - lastV = v; - } - } - - - private static Vector2 CubeBezier(Vector2 s, Vector2 st, Vector2 e, Vector2 et, float t) { - float rt = 1 - t; - return rt * rt * rt * s + 3 * rt * rt * t * st + 3 * rt * t * t * et + t * t * t * e; - } - - // This static initializer works for runtime, but apparently isn't called when - // Editor play mode stops, so DrawLine will re-initialize if needed. - static Drawing() { - Initialize(); - } - - private static void Initialize() { - if (lineTex == null) { - lineTex = new Texture2D(1, 1, TextureFormat.ARGB32, false); - lineTex.SetPixel(0, 1, Color.white); - lineTex.Apply(); - } - - if (aaLineTex == null) { - // TODO: better anti-aliasing of wide lines with a larger texture? or use Graphics.DrawTexture with border settings - aaLineTex = new Texture2D(1, 3, TextureFormat.ARGB32, false); - aaLineTex.SetPixel(0, 0, new Color(1, 1, 1, 0)); - aaLineTex.SetPixel(0, 1, Color.white); - aaLineTex.SetPixel(0, 2, new Color(1, 1, 1, 0)); - aaLineTex.Apply(); - } - - // GUI.blitMaterial and GUI.blendMaterial are used internally by GUI.DrawTexture, - // depending on the alphaBlend parameter. Use reflection to "borrow" these references. - blitMaterial = (Material) typeof(GUI).GetMethod("get_blitMaterial", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null); - blendMaterial = (Material) typeof(GUI).GetMethod("get_blendMaterial", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null); - } - } -} \ No newline at end of file From d442f1b16d1be8bd1689f548bff6121eb3457f46 Mon Sep 17 00:00:00 2001 From: MagneticPizza <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Fri, 24 Sep 2021 18:44:46 -0400 Subject: [PATCH 55/91] Delete Resources.Designer.cs --- Source/Resources.Designer.cs | 63 ------------------------------------ 1 file changed, 63 deletions(-) delete mode 100644 Source/Resources.Designer.cs diff --git a/Source/Resources.Designer.cs b/Source/Resources.Designer.cs deleted file mode 100644 index ea88a69..0000000 --- a/Source/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace DebugMod.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DebugMod.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} From 3696372b08e408bf0827d2fbb618600a1e895624 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Sat, 25 Sep 2021 23:45:04 +0200 Subject: [PATCH 56/91] always uumuu extra + yeet cornifer bind uumuu will always give an extra attack (at least on the first cycle) cornifer is yeeted from all cornifer scenes, basically removes the humming :) --- Source/BindableFunctions.cs | 38 +++++++++++- Source/BossHandler.cs | 111 ++++++++---------------------------- 2 files changed, 61 insertions(+), 88 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 5fb92b1..33834c4 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -14,6 +14,8 @@ public static class BindableFunctions { private static readonly FieldInfo TimeSlowed = typeof(GameManager).GetField("timeSlowed", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); private static readonly FieldInfo IgnoreUnpause = typeof(UIManager).GetField("ignoreUnpause", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); + private static bool corniferYeeteded = false; + internal static readonly FieldInfo cameraGameplayScene = typeof(CameraController).GetField("isGameplayScene", BindingFlags.Instance | BindingFlags.NonPublic); @@ -155,6 +157,38 @@ public static void TimescaleUp() Console.AddLine("Cannot set TimeScale greater than 2.0"); } } + + [BindableMethod(name = "Yeet Cornifer-Toggle", category = "Misc")] + public static void CorniferYeet() + { + corniferYeeteded = !corniferYeeteded; + + if (corniferYeeteded) + { + CorniferYeeted(); + UnityEngine.SceneManagement.SceneManager.activeSceneChanged += CorniferYeeted; + Console.AddLine("Cornifer yeeted on next loads lol"); + } + else + { + UnityEngine.SceneManagement.SceneManager.activeSceneChanged -= CorniferYeeted; + Console.AddLine("Cornifer unyeeted from next loads on???"); + } + } + + private static void CorniferYeeted(Scene current, Scene next) => CorniferYeeted(); + + private static void CorniferYeeted() + { + (from x in UnityEngine.Object.FindObjectsOfType() + where x.name.Contains("Cornifer") + select x).ToList().ForEach(delegate (GameObject x) + { + UnityEngine.Object.Destroy(x); + }); + } + + [BindableMethod(name = "Reset Debug States", category = "Misc")] public static void Reset() { @@ -1047,13 +1081,13 @@ public static void IncreaseQuakeLevel() #region Bosses - /* + [BindableMethod(name = "Force Uumuu extra attack", category = "Bosses")] public static void ForceUumuuExtra() { BossHandler.UumuuExtra(); } - */ + [BindableMethod(name = "Respawn Ghost", category = "Bosses")] public static void RespawnGhost() { diff --git a/Source/BossHandler.cs b/Source/BossHandler.cs index 7096183..89dd323 100644 --- a/Source/BossHandler.cs +++ b/Source/BossHandler.cs @@ -5,7 +5,8 @@ using UnityEngine.SceneManagement; using HutongGames.PlayMaker; using HutongGames.PlayMaker.Actions; -using Vasi; +//using Vasi; +using System; namespace DebugMod { @@ -136,115 +137,53 @@ public static void UumuuExtra() { if (!fsmToggle) { - var go = new GameObject(); - _coro = go.AddComponent(); - //GameManager.instance. - Object.DontDestroyOnLoad(_coro); - Console.AddLine("Uumuu forced extra attack ON"); - - UnityEngine.SceneManagement.SceneManager.sceneLoaded += StartUumuuCoro; + + UnityEngine.SceneManagement.SceneManager.activeSceneChanged += SetUumuuExtra; fsmToggle = true; } else { - Object.Destroy(_coro); - UnityEngine.SceneManagement.SceneManager.sceneLoaded -= StartUumuuCoro; + UnityEngine.SceneManagement.SceneManager.activeSceneChanged -= SetUumuuExtra; fsmToggle = false; Console.AddLine("Uumuu forced extra attack OFF"); } + } - /* - if (DebugMod.GetSceneName() == "Fungus3_archive_02") + private static void SetUumuuExtra(Scene sceneFrom, Scene sceneTo) + { + Console.AddLine("SetUumuuExtra scene check: " + sceneFrom.name + " " + sceneTo.name); + if (sceneTo.name == "Fungus3_archive_02" && sceneTo != null) { - PlayMakerFSM[] components = GameObject.Find("Mega Jellyfish").GetComponents(); - - if (components != null) + try { - foreach (PlayMakerFSM playMakerFSM in components) + if (DebugMod.GM == null) { - //if (playMakerFSM.) - { - playMakerFSM.FsmVariables.GetFsmBool("Activated").Value = false; - Console.AddLine("Boss control for this scene was reset, re-enter scene or warp"); - } + throw new Exception("StartUumuuCoro( ) - gamemanager is null"); } + DebugMod.GM.StartCoroutine(UumuuExtraCoro(sceneTo)); } - else + catch (Exception e) { - Console.AddLine("GO does not exist or no FSM on it"); + DebugMod.instance.Log(e.Message); } } - */ } - private static void StartUumuuCoro(Scene scene, LoadSceneMode lsm) + private static IEnumerator UumuuExtraCoro(Scene activeScene) { - Console.AddLine("Start Uumuu Coro Uumuu test: " + scene.name); - if (scene.name == "Fungus3_archive_02") + Console.AddLine("Coro launched"); + while (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != activeScene.name) { - Console.AddLine("_coro ToString: " + _coro.active.ToString()); - //_coro.StartCoroutine(UumuuExtraCoro()); - - GameObject uumuu = GameObject.Find("Mega Jellyfish"); - Console.AddLine("Uumuu GameObject"); - - if (uumuu != null) { - Console.AddLine("Locating Uumuu FSM"); - PlayMakerFSM fsm = uumuu.LocateMyFSM("Mega Jellyfish"); - - fsm.GetState("Idle").GetAction().timeMax = 1.6f; - } + yield return null; } - } - - private static IEnumerator UumuuExtraCoro() - { - // Find Uumuu and the FSM + // Find Uumuu, their FSM, the specific State, and the Action that dictates the possibility of extra attacks GameObject uumuu = GameObject.Find("Mega Jellyfish"); - Console.AddLine("Uumuu GameObject"); - if (uumuu == null) - yield break; - Console.AddLine("Locating Uumuu FSM"); PlayMakerFSM fsm = uumuu.LocateMyFSM("Mega Jellyfish"); - - fsm.GetState("Idle").GetAction().timeMax = 1.6f; - - - // Fix the waits and the number of attacks - - - //fsm.GetState("Idle").GetAction().timeMax = 1.5f; - //fsm.GetState("Set Timer").GetAction().max = 2f; - //fsm.FsmVariables.GetFsmFloat("Quirrel Time").Value = 4f; - - // Fix the pattern to 2 quick, then 1 long if it still needs to attack - //FsmState choice = fsm.GetState("Choice"); - //choice.RemoveAction(); - //choice.AddMethod(() => SetUumuuPattern(fsm)); - - // Reset the multizap counter to 0 so the pattern remains 2 quick 1 optional long - //fsm.GetState("Recover").AddMethod(() => fsm.FsmVariables.GetFsmInt("Ct Multizap").Value = 0); - - // Set the initial RecoilSpeed to 0 so that dream nailing her on the first cycle doesn't push her - //uumuu.GetComponent().SetRecoilSpeed(0); - - // Set her HP to 1028 value - //uumuu.GetComponent().hp = 250; - - } - - private static void SetUumuuPattern(PlayMakerFSM fsm) - { - if (fsm.FsmVariables.GetFsmInt("Ct Multizap").Value < 2) - { - fsm.Fsm.Event(fsm.FsmEvents.First(e => e.Name == "MULTIZAP")); - fsm.FsmVariables.GetFsmInt("Ct Multizap").Value++; - } - else - { - fsm.Fsm.Event(fsm.FsmEvents.First(e => e.Name == "CHASE")); - } + FsmState fsmState = fsm.FsmStates.First(t => t.Name == "Idle"); + WaitRandom waitRandom = (WaitRandom)fsmState.Actions.OfType().First(); + waitRandom.timeMax.Value = 1.6f; + yield break; } } } From 3df62f79cba0e4e419289e94a48d9651b85c828a Mon Sep 17 00:00:00 2001 From: cerpintext Date: Sun, 26 Sep 2021 17:27:09 +0200 Subject: [PATCH 57/91] version bump, small changes adjusted the savestates page text and position ported "clear white screen" from cp debug --- Source/BindableFunctions.cs | 7 +++++++ Source/DebugMod.cs | 2 +- Source/DebugMod.csproj | 4 ---- Source/SaveStatesPanel.cs | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index d8fa1ea..01f7cac 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -19,6 +19,13 @@ public static class BindableFunctions #region Misc + [BindableMethod(name = "Clear White Screen", category = "Misc")] + public static void ClearWhiteScreen() + { + GameObject.Find("Blanker White").LocateMyFSM("Blanker Control").SendEvent("FADE OUT"); + HeroController.instance.EnableRenderer(); + } + [BindableMethod(name = "Nail Damage +4", category = "Misc")] public static void IncreaseNailDamage() { diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 22106b8..5051d8a 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -170,7 +170,7 @@ public override void Initialize() public override string GetVersion() { - return "1.4.3"; + return "1.4.4"; } public override bool IsCurrent() diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 0b56f2c..6355425 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -73,10 +73,6 @@ .\References\UnityEngine.UI.dll False - - References\Vasi.dll - False - diff --git a/Source/SaveStatesPanel.cs b/Source/SaveStatesPanel.cs index fdf3481..148f017 100644 --- a/Source/SaveStatesPanel.cs +++ b/Source/SaveStatesPanel.cs @@ -22,7 +22,7 @@ public static void BuildMenu(GameObject canvas) GUIController.Instance.images["BlankVertical"].height ) ); - statePanel.AddText("CurrentFolder", "In slot "+(SaveStateManager.currentStateFolder + 1).ToString(), new Vector2(20,10), Vector2.zero, GUIController.Instance.arial, 15); + statePanel.AddText("CurrentFolder", "Page: "+(SaveStateManager.currentStateFolder + 1).ToString(), new Vector2(8,0), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("Mode", "mode: ", new Vector2(8, 20), Vector2.zero, GUIController.Instance.arial, 15); statePanel.AddText("currentmode", "-", new Vector2(60, 20), Vector2.zero, GUIController.Instance.arial, 15); @@ -87,7 +87,7 @@ public static void Update() if (statePanel.active) { statePanel.GetText("currentmode").UpdateText(SaveStateManager.currentStateOperation); - statePanel.GetText("CurrentFolder").UpdateText("In slot " + (SaveStateManager.currentStateFolder + 1).ToString()+"/"+SaveStateManager.savePages); + statePanel.GetText("CurrentFolder").UpdateText("Page: " + (SaveStateManager.currentStateFolder + 1).ToString()+"/"+SaveStateManager.savePages); for (int i = 0; i < SaveStateManager.maxSaveStates; i++) { statePanel.GetText(i.ToString()).UpdateText("open"); From 0c310e6ccff072a730ed79888d3d3f8dbc79c1e7 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Mon, 27 Sep 2021 01:46:01 +0200 Subject: [PATCH 58/91] slight savestate page ux updates small changes to readme change number of savestate pages to set in debugmod-settings slight visual changes savestates save states of room (broken doors, etc) --- README.md | 14 ++++++------ Source/BindableFunctions.cs | 36 ++++++++++++++++-------------- Source/DebugMod.cs | 1 + Source/SaveState.cs | 44 ++++++++++++++++++------------------- Source/SaveStateManager.cs | 4 +++- Source/Settings.cs | 6 +++++ 6 files changed, 59 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 4d4a4b0..46f6878 100644 --- a/README.md +++ b/README.md @@ -49,22 +49,22 @@ ---------------------------------------------------------------------------------------- ## Savestates -In order to acess your new save-states, bind Next Page and Prev Page to a key (2nd page of binds in debug mod) -There are 10 pages of 10 savestates. +In order to acess the new save-states, bind `Next Page` and `Prev Page` to any keys you want (2nd page of binds in debug mod) +You can select as many total pages you want (default: 10) in the `DebugMod.GlobalSettings-1.2.2.1` in your saves folder. Prev/Next Page will scroll through these. -then, just do what you would do in normal debug mod to save and load states. +After this, you can just do what you would do in normal debug mod to save and load states. To use your old savestates, go to this folder %APPDATA%\..\LocalLow\Team Cherry\Hollow Knight\Savestates-1221 copy the files in this folder into the folder labeled 0 ( if it doesn't exist, make it. ) -Start the game and you will have your old saves plus the 90 empty slots. +Start the game and you will have your old saves plus 9 other pages full of empty slots by default. *If you have performance issues, please report it.* To use numpad for slot select; after installing debugmod, start and stop the game, -then go to the Hollow Knight saves-directory and open the `DebugMod.GlobalSettings` json-file. -In that file find `"NumPadForSaveStates"`, and change the corresponding value from 0 to 1. +then go to the Hollow Knight saves-directory and open the `DebugMod.GlobalSettings-1.2.2.1` json-file. +In that file find `"NumPadForSaveStates"`, and change the corresponding value from `0` to `1`. -To change the amount of available Savestate-slots per page (default: 6), find `MaxSaveStates` and set the corresponding value between 0 and 10 respective of how many slots you want. +To change the amount of available Savestate-slots per page (default: 6), find `MaxSaveStates` and set the corresponding value between `0` and `10` respective of how many slots you want. Savestates files are located in `%APPDATA%\..\LocalLow\Team Cherry\Hollow Knight\Savestates-1221\`. They use the name format `savestate.json`. After saving a savestate to file, you can edit the name of that savestate. To do this, open the file in any text-editor, and the first variable/line should be something like `"saveStateIdentifier": "",`. Change `` inside the pair of `"`-s to whatever you want that savestate named in the select savestate in-game menu. diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 01f7cac..b26232b 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -275,26 +275,30 @@ public static void LoadFromFile() [BindableMethod(name = "Next Save Page", category = "Savestates")] public static void NextStatePage() { - SaveStateManager.currentStateFolder++; - if (SaveStateManager.currentStateFolder == SaveStateManager.savePages) { SaveStateManager.currentStateFolder = 0; } //rollback to 0 if 10, keep folder between 0 and 9 - SaveStateManager.path = ( - Application.persistentDataPath + - "/Savestates-1221/" + - SaveStateManager.currentStateFolder.ToString() + - "/"); //change path - DebugMod.saveStateManager.RefreshStateMenu(); // updaate menu + if (SaveStateManager.inSelectSlotState) { + SaveStateManager.currentStateFolder++; + if (SaveStateManager.currentStateFolder == SaveStateManager.savePages) { SaveStateManager.currentStateFolder = 0; } //rollback to 0 if 10, keep folder between 0 and 9 + SaveStateManager.path = ( + Application.persistentDataPath + + "/Savestates-1221/" + + SaveStateManager.currentStateFolder.ToString() + + "/"); //change path + DebugMod.saveStateManager.RefreshStateMenu(); // update menu + } } [BindableMethod(name = "Prev Save Page", category = "Savestates")] public static void PrevStatePage() { - SaveStateManager.currentStateFolder--; - if (SaveStateManager.currentStateFolder == -1) { SaveStateManager.currentStateFolder = SaveStateManager.savePages-1; } //rollback to max if past limit, keep folder between 0 and 9 - SaveStateManager.path = ( - Application.persistentDataPath + - "/Savestates-1221/" + - SaveStateManager.currentStateFolder.ToString() + - "/"); //change path - DebugMod.saveStateManager.RefreshStateMenu(); // update menu + if (SaveStateManager.inSelectSlotState) { + SaveStateManager.currentStateFolder--; + if (SaveStateManager.currentStateFolder == -1) { SaveStateManager.currentStateFolder = SaveStateManager.savePages-1; } //rollback to max if past limit, keep folder between 0 and 9 + SaveStateManager.path = ( + Application.persistentDataPath + + "/Savestates-1221/" + + SaveStateManager.currentStateFolder.ToString() + + "/"); //change path + DebugMod.saveStateManager.RefreshStateMenu(); // update menu + } } diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 5051d8a..3b22a2f 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -91,6 +91,7 @@ public override void Initialize() settings.SaveStatePanelVisible = false; settings.NumPadForSaveStates = false; settings.MaxSaveStates = 6; + settings.SaveStatePages = 10; settings.binds.Clear(); settings.binds.Add("Toggle All UI", (int)KeyCode.F1); diff --git a/Source/SaveState.cs b/Source/SaveState.cs index aab1eb1..72aa5c4 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -53,6 +53,7 @@ internal SaveState() public void SaveTempState() { + DebugMod.GM.SaveLevelState(); data.saveScene = GameManager.instance.GetSceneNameString(); data.saveStateIdentifier = "(tmp)_" + data.saveScene + "-" + DateTime.Now.ToString("H:mm_d-MMM"); data.savedPd = JsonUtility.FromJson(JsonUtility.ToJson(PlayerData.instance)); @@ -155,7 +156,7 @@ public void LoadStateFromFile(int paramSlot) data.savePos = tmpData.savePos; data.saveScene = tmpData.saveScene; data.lockArea = tmpData.lockArea; - DebugMod.instance.Log("Load SaveState ready: " + data.saveStateIdentifier); + DebugMod.instance.LogFine("Load SaveState ready: " + data.saveStateIdentifier); } catch (Exception ex) { @@ -181,6 +182,9 @@ private IEnumerator LoadStateCoro() } */ //Console.AddLine("LoadStateCoro line1: " + data.savedPd.hazardRespawnLocation.ToString()); + int oldMPReserveMax = PlayerData.instance.MPReserveMax; + int oldMP = PlayerData.instance.MPCharge; + data.cameraLockArea = (data.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); GameManager.instance.ChangeToScene("Room_Sly_Storeroom", "", 0f); while (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != "Room_Sly_Storeroom") @@ -188,11 +192,8 @@ private IEnumerator LoadStateCoro() yield return null; } GameManager.instance.sceneData = (SceneData.instance = JsonUtility.FromJson(JsonUtility.ToJson(data.savedSd))); - //if (!BindableFunctions.preserveThroughStates) - //{ - //Console.AddLine("Before ResetSemiPersistentItems(): " + data.savedPd.hazardRespawnLocation.ToString()); GameManager.instance.ResetSemiPersistentItems(); - //} + yield return null; HeroController.instance.gameObject.transform.position = data.savePos; PlayerData.instance = (GameManager.instance.playerData = (HeroController.instance.playerData = JsonUtility.FromJson(JsonUtility.ToJson(data.savedPd)))); @@ -211,30 +212,25 @@ private IEnumerator LoadStateCoro() HeroController.instance.playerData = PlayerData.instance; HeroController.instance.geoCounter.playerData = PlayerData.instance; HeroController.instance.geoCounter.TakeGeo(0); - if (PlayerData.instance.MPCharge >= PlayerData.instance.maxMP) + + if (PlayerData.instance.MPCharge >= 99 || oldMP >= 99) { - int tmpMp = PlayerData.instance.MPCharge; - HeroController.instance.TakeMP(PlayerData.instance.MPCharge); + if (PlayerData.instance.MPReserve > 0) + { + HeroController.instance.TakeReserveMP(1); + HeroController.instance.AddMPChargeSpa(1); + } + HeroController.instance.TakeMP(1); yield return null; - HeroController.instance.AddMPChargeSpa(tmpMp); + HeroController.instance.AddMPCharge(1); } else { - HeroController.instance.AddMPChargeSpa(1); - yield return null; + HeroController.instance.AddMPCharge(1); HeroController.instance.TakeMP(1); } - if (PlayerData.instance.MPReserveMax > 0) - { - int tmpReserve = PlayerData.instance.MPReserve; - HeroController.instance.TakeReserveMP(PlayerData.instance.MPReserve); - yield return null; - HeroController.instance.AddMPChargeSpa(tmpReserve); - } - - //Console.AddLine("LoadStateCoro end of func: " + data.savedPd.hazardRespawnLocation.ToString()); - //HeroController.instance.SetHazardRespawn(savedPd.hazardRespawnLocation, savedPd.hazardRespawnFacingRight); - HeroController.instance.proxyFSM.SendEvent("HeroCtrl-HeroDamaged"); + + HeroController.instance.proxyFSM.SendEvent("HeroCtrl-HeroLanded"); HeroAnimationController component = HeroController.instance.GetComponent(); typeof(HeroAnimationController).GetField("pd", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(component, PlayerData.instance); @@ -245,6 +241,10 @@ private IEnumerator LoadStateCoro() HeroController.instance.AddHealth(1); GameManager.instance.inputHandler.RefreshPlayerData(); + + //UnityEngine.Object.Destroy(GameCameras.instance.gameObject); + //yield return null; + //DebugMod.GM.SetupSceneRefs(); yield break; // need to redraw UI somehow } diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index 0da227a..ba1ff40 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -30,7 +30,7 @@ internal class SaveStateManager public static int currentStateFolder = 0; public static SaveState quickState; public static bool inSelectSlotState = false; // a mutex, in practice? - public static int savePages = 10; + public static int savePages; public static int currentStateSlot = -1; public static string path = Application.persistentDataPath + "/Savestates-1221/0/"; public static string currentStateOperation = null; @@ -59,6 +59,8 @@ internal SaveStateManager() inSelectSlotState = false; //autoSlot = false; DebugMod.settings.SaveStatePanelVisible = false; + if (DebugMod.settings.SaveStatePages == -1) DebugMod.settings.SaveStatePages = 10; + savePages = DebugMod.settings.SaveStatePages; quickState = new SaveState(); for (int i = 0; i <= savePages; i++) { diff --git a/Source/Settings.cs b/Source/Settings.cs index a6efec8..d5ad192 100644 --- a/Source/Settings.cs +++ b/Source/Settings.cs @@ -79,6 +79,12 @@ public int MaxSaveStates set => SetInt(value); } + public int SaveStatePages + { + get => GetInt(-1); + set => SetInt(value); + } + public float AmountToMove { get => GetFloat(0.1f); From 2aa531b02189976d2545e31775d614656215b6ef Mon Sep 17 00:00:00 2001 From: cerpintext Date: Mon, 27 Sep 2021 03:01:36 +0200 Subject: [PATCH 59/91] uumuu extra without reloading scene --- Source/BossHandler.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/BossHandler.cs b/Source/BossHandler.cs index 89dd323..cd51f38 100644 --- a/Source/BossHandler.cs +++ b/Source/BossHandler.cs @@ -137,8 +137,7 @@ public static void UumuuExtra() { if (!fsmToggle) { - Console.AddLine("Uumuu forced extra attack ON"); - + SetUumuuExtra(UnityEngine.SceneManagement.SceneManager.GetActiveScene(), DebugMod.GM.nextScene); UnityEngine.SceneManagement.SceneManager.activeSceneChanged += SetUumuuExtra; fsmToggle = true; } From 5f9623e4e42fb39ed25e6a0cd9d91eaa3200284d Mon Sep 17 00:00:00 2001 From: flukebull Date: Sun, 3 Oct 2021 00:13:14 -0700 Subject: [PATCH 60/91] Add buttons to directly run bindable actions Plenty of practice/experimentation/etc functionality isn't typically used in time-sensitive conditions, like loading savestates or nudging player position, but I don't have keybinds set up for absolutely everything. It's annoying to have to find a free key to bind, only to use it a couple times or immediately unbind it. This lets you trigger anything by clicking on the icon. --- Source/DebugMod.csproj | 3 ++- Source/Images/ButtonRun.png | Bin 0 -> 1938 bytes Source/KeyBindPanel.cs | 12 +++++++++++- 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 Source/Images/ButtonRun.png diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 6355425..72cc037 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -121,6 +121,7 @@ + @@ -185,4 +186,4 @@ - \ No newline at end of file + diff --git a/Source/Images/ButtonRun.png b/Source/Images/ButtonRun.png new file mode 100644 index 0000000000000000000000000000000000000000..8c968799f9e7f1af6485e17918d3a9628e8a9d58 GIT binary patch literal 1938 zcmV;D2W|L?P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U=H6lG`8*hTl0wkANhE#Bnf~nckqs?+3Hz^~BmBTc#ZpLWo=eUVS1PG+MaAQB)s<6BD?c9gvyC3@;c8%* z1f?90p3nX_J6!@tQBl)7A#Z2H_SjI;sqarh=R`7B#HjRBsGLH=M+2P#_1IR-#qE9z z+qr{t{NV=NVP;}W`x1G6P6qFFg;AJyA&JOY_*j6aocGB0*56i`OGfTT>ez2QdQ#?3%-eYtRW9-N7 zYRYhFJ~wsS%BrE`2A9hkmXQp%qHZe{BoBz*20A^qxFIzv#PI&0M4c)P+E>}AVTp-% zHk8Z_pr*~mxNwsgz%0!~gH4KbanNeOE3opl7FzR`HC-de#GTNS31T!^hXwo_(x*aW z%#bIFe)$UP;u(Zk#w0g$^a2nXw>Z+};9GjWCRYJLU2b-4u*U6>*p$xLnsFoxw4kG+ zJYEa3ehR=vm|L+J5)g=)L@84=W+Q?h9egT;oF(xF1f~G=@g`f^bjzDP}_p;Z4P#ZGR(2<7?A7#{w8ifPvhxB!7bfd3n~2* zH@=Yz6Ww=^3lrTZp|llRbuhW~3z{?}DK3tJYr(;f#j1mgv#t)V zf*|+-;^yY0=prTlFDbN$@!+^0@9sVB-T^|R!c?+H=vDG21AHR!9McVpc!PLm)6zNb6NgzzQi#uq#|*k4 z@gvt|m)|%S9Ts?I*vO>jiNnNVv4iCfW+g)+gyEO|_ zlWtNd1_WMg`(p&?-UXU<+x|Yb?dA#Ke+I6!w!hi{WoO54hX` z2A*`ukQ~WRQz#UG_cQvY9MFFY1lQc&TKhPC05a6o@(pls2#gjfd)?#RJ)OP%d#2Uj z4{!K#ria-ERR91024YJ`L;y7aG5|D|*-63x000SaNLh0L01FcU01FcV0GgZ_00007 zbV*G`2jvO_1vVSk>J6*_00NRpL_t(Y$IX{LXcSQp$A9mVmF62P5fCnE06UqyO${O z!LiHE$N&A`%$u2mO->a5zb{%VEI z&UGmkkTuj4@2O-r z8M>ds_Jumr3+VeWe4tKevbs4j9kzzAnJR;+jOlH4EC*Hl)NSf^wXee0SokQIPpy?m z^BL2zl6*itq+U_4s)yD78sG)<`Hl$}nOMYhx`TWu!thG{9I+g!I{rBJBIdJy+|%sJ z%yn@vq@GdVsNdA*>P2;r+Nc1Z%dXmRE;tr~pM|b~+KyR!Zq{MbZw%{qF;I04IR+z^FRVu~_`_*~+mB;PH4a_E_Bdfy2P1C^iSx zEnRdMbF4;IeTa&*p8CE8I1S7I`@00?T% ztT&!xHA;b>=#l9P@D#WX+yb7Zl)iV-oyf5orBrWrDfgiv!a4(p)yMcz!W{y<= zw<0dXz{wiGtH4{}25<*>pHf;~!{%i8&I?KHCNZcURiCKu)NAVQ4K<0HZLv??ubz!f z9;n%q*KUhdgFrU+Y>i)|259vlP-pb%VP@-X^r<=QrEYQUW!U?_#@kID=r{E*%)eYe Y0YchJ!ru=ywEzGB07*qoM6N<$g0YH`kpKVy literal 0 HcmV?d00001 diff --git a/Source/KeyBindPanel.cs b/Source/KeyBindPanel.cs index 7a4b0f5..074e114 100644 --- a/Source/KeyBindPanel.cs +++ b/Source/KeyBindPanel.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using UnityEngine; namespace DebugMod @@ -53,7 +54,8 @@ public static void BuildMenu(GameObject canvas) for (int i = 0; i < 11; i++) { - panel.AddButton(i.ToString(), GUIController.Instance.images["Scrollbar_point"], new Vector2(300f, 45f + 17.5f * i), Vector2.zero, ChangeBind, new Rect(0, 0, GUIController.Instance.images["Scrollbar_point"].width, GUIController.Instance.images["Scrollbar_point"].height)); + panel.AddButton(i.ToString(), GUIController.Instance.images["Scrollbar_point"], new Vector2(290f, 45f + 17.5f * i), Vector2.zero, ChangeBind, new Rect(0, 0, GUIController.Instance.images["Scrollbar_point"].width, GUIController.Instance.images["Scrollbar_point"].height)); + panel.AddButton($"run{i}", GUIController.Instance.images["ButtonRun"], new Vector2(308f, 51f + 17.5f * i), new Vector2(12f, 12f), RunBind, new Rect(0, 0, GUIController.Instance.images["ButtonRun"].width, GUIController.Instance.images["ButtonRun"].height)); } //Build pages based on categories @@ -152,6 +154,13 @@ private static void ChangeBind(string buttonName) UpdateHelpText(); } + private static void RunBind(string buttonName) { + int bindIndex = Convert.ToInt32(buttonName.Substring(3)); // strip leading "run" + string bindName = bindPages[pageKeys[page]][bindIndex]; + MethodInfo method = (MethodInfo)DebugMod.bindMethods[bindName].Second; + method.Invoke(null, null); + } + public static void Update() { if (panel == null) @@ -183,6 +192,7 @@ public static void Update() for (int i = 0; i < 11; i++) { panel.GetButton(i.ToString()).SetActive(bindPages[pageKeys[page]].Count > i); + panel.GetButton($"run{i}").SetActive(bindPages[pageKeys[page]].Count > i); } } } From da108fecdcd817907d4d1d91472070ff4982294d Mon Sep 17 00:00:00 2001 From: cerpintext Date: Tue, 5 Oct 2021 16:39:36 +0200 Subject: [PATCH 61/91] version bump 1.4.5 tiny fix with folders created for savestates being 1 higher than amount of pages --- Source/DebugMod.cs | 2 +- Source/SaveStateManager.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 3b22a2f..644fcb5 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -171,7 +171,7 @@ public override void Initialize() public override string GetVersion() { - return "1.4.4"; + return "1.4.5"; } public override bool IsCurrent() diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index ba1ff40..1a920d5 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -62,7 +62,7 @@ internal SaveStateManager() if (DebugMod.settings.SaveStatePages == -1) DebugMod.settings.SaveStatePages = 10; savePages = DebugMod.settings.SaveStatePages; quickState = new SaveState(); - for (int i = 0; i <= savePages; i++) + for (int i = 0; i < savePages; i++) { if (!Directory.Exists(Application.persistentDataPath + "/Savestates-1221/" + i.ToString())) { From 47ed8aa974b16f5672ea699be67acc46a40064ac Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Thu, 7 Oct 2021 22:48:25 -0400 Subject: [PATCH 62/91] Add force shade fb Adds a bind to force a shade fireball --- Source/BindableFunctions.cs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index b26232b..a382b51 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -7,6 +7,7 @@ using GlobalEnums; using HutongGames.PlayMaker; using UnityEngine.SceneManagement; +using HutongGames.PlayMaker.Actions; namespace DebugMod { @@ -1114,8 +1115,28 @@ public static void IncreaseQuakeLevel() #endregion #region Bosses - - + + + [BindableMethod(name = "Force Shade fireball", category = "Bosses")] + public static void ShadeFireball() + { + + try + { + GameObject shade = GameObject.Find("Hollow Shade(Clone)"); + PlayMakerFSM fsm = shade.LocateMyFSM("Shade Control"); + //FsmState fsmState = fsm.FsmStates.First(t => t.Name == "Attack Choice"); i couldnt get this to work. the current solution works good enough. + //SendRandomEvent sendRandom = fsmState.Actions.OfType().First(); + //sendRandom.weights[0] = 0f; + //sendRandom.weights[1] = 1; + fsm.SetState("Fireball Pos"); + } + catch (Exception e) + { + Console.AddLine("Ignore below message if no shade is in scene"); + Console.AddLine(e.Message); + } + } [BindableMethod(name = "Force Uumuu extra attack", category = "Bosses")] public static void ForceUumuuExtra() { From 3d3dff311bb3fcd7d14b826e3ba79dff857b9d97 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Tue, 9 Nov 2021 20:07:08 +0100 Subject: [PATCH 63/91] refresh enemy panel when loading savestate --- Source/DebugMod.cs | 2 +- Source/SaveState.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 644fcb5..ec1997a 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -171,7 +171,7 @@ public override void Initialize() public override string GetVersion() { - return "1.4.5"; + return "1.4.6-early"; } public override bool IsCurrent() diff --git a/Source/SaveState.cs b/Source/SaveState.cs index 72aa5c4..9245ab4 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -242,6 +242,7 @@ private IEnumerator LoadStateCoro() GameManager.instance.inputHandler.RefreshPlayerData(); + if (DebugMod.settings.EnemiesPanelVisible) EnemiesPanel.RefreshEnemyList(); //UnityEngine.Object.Destroy(GameCameras.instance.gameObject); //yield return null; //DebugMod.GM.SetupSceneRefs(); From a3d2032c0a37fdcb4c57d156ced1f8cfbdaca439 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Wed, 10 Nov 2021 15:36:58 -0500 Subject: [PATCH 64/91] Optimize Savestates should have no downsides. also made savestates work in sly room. changed to Room_Mender_House Because it loads faster --- Source/SaveState.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Source/SaveState.cs b/Source/SaveState.cs index 9245ab4..6afaac1 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -186,10 +186,18 @@ private IEnumerator LoadStateCoro() int oldMP = PlayerData.instance.MPCharge; data.cameraLockArea = (data.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); - GameManager.instance.ChangeToScene("Room_Sly_Storeroom", "", 0f); - while (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != "Room_Sly_Storeroom") + if (data.saveScene == UnityEngine.SceneManagement.SceneManager.GetActiveScene().name) { - yield return null; + string scene = "Room_Mender_House"; + if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == "Room_Mender_House") + { + scene = "Room_Sly_Storeroom"; + } + GameManager.instance.ChangeToScene(scene, "", 0f);// i hate that i have to do this. + while (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != scene) + { + yield return null; + } } GameManager.instance.sceneData = (SceneData.instance = JsonUtility.FromJson(JsonUtility.ToJson(data.savedSd))); GameManager.instance.ResetSemiPersistentItems(); From ae122c84f6e3c0f7bd3045784d16c5f2f5492459 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Thu, 11 Nov 2021 14:38:54 -0500 Subject: [PATCH 65/91] Update SaveState.cs --- Source/SaveState.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/Source/SaveState.cs b/Source/SaveState.cs index 6afaac1..97c3ab3 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -186,8 +186,6 @@ private IEnumerator LoadStateCoro() int oldMP = PlayerData.instance.MPCharge; data.cameraLockArea = (data.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); - if (data.saveScene == UnityEngine.SceneManagement.SceneManager.GetActiveScene().name) - { string scene = "Room_Mender_House"; if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == "Room_Mender_House") { @@ -198,7 +196,6 @@ private IEnumerator LoadStateCoro() { yield return null; } - } GameManager.instance.sceneData = (SceneData.instance = JsonUtility.FromJson(JsonUtility.ToJson(data.savedSd))); GameManager.instance.ResetSemiPersistentItems(); From d5a94fd22f8b739f13f3f263ece476ae5098e3c4 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Fri, 12 Nov 2021 09:44:23 -0500 Subject: [PATCH 66/91] position states --- Source/BindableFunctions.cs | 11 +++- Source/DebugMod.csproj | 3 +- Source/EnemiesPanel.cs | 2 +- Source/SavePositionManager.cs | 101 ++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 Source/SavePositionManager.cs diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index a382b51..01b049e 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -237,7 +237,16 @@ public static void Reset() #endregion #region SaveStates - + [BindableMethod(name = "Position Save", category = "SaveStates")] + public static void SavePosition() + { + SavePositionManager.SavePosition(); + } + [BindableMethod(name = "Position Load", category = "SaveStates")] + public static void LoadPosition() + { + SavePositionManager.LoadPosition(); + } [BindableMethod(name = "Quickslot (save)", category = "Savestates")] public static void SaveState() { diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 72cc037..7ae63bf 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -76,6 +76,7 @@ + @@ -186,4 +187,4 @@ - + \ No newline at end of file diff --git a/Source/EnemiesPanel.cs b/Source/EnemiesPanel.cs index c15ddde..664219f 100644 --- a/Source/EnemiesPanel.cs +++ b/Source/EnemiesPanel.cs @@ -13,7 +13,7 @@ public static class EnemiesPanel public static bool autoUpdate; private static float lastTime; public static List enemyPool = new List(); - private static GameObject parent; + public static GameObject parent; public static bool hpBars; public static bool hitboxes; public static readonly MethodInfo takeDamage = typeof(HeroController).GetMethod("TakeDamage"); diff --git a/Source/SavePositionManager.cs b/Source/SavePositionManager.cs new file mode 100644 index 0000000..9447e12 --- /dev/null +++ b/Source/SavePositionManager.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using static DebugMod.EnemiesPanel; +namespace DebugMod +{ + public class SavePositionManager + { + public static List FSMs = new List(); + public static List FSMs2 = new List(); + static Vector3 vect = new(0,0,0); + public static void SavePosition() + { + vect = DebugMod.RefKnight.transform.position; + // save fsms :eyes: + + FSMs = GetAllEnemies(FSMs); + FSMs.ForEach(delegate (EnemyData dat) + { + dat.gameObject.SetActive(false); + }); + + } + public static void LoadPosition() + { + + //debuging(); + //create and name fsms2 + RemoveAll(); + FSMs2 = Create(); + + DebugMod.RefKnight.transform.position = vect; + DebugMod.RefCamera.SnapTo(DebugMod.RefKnight.transform.position.x, DebugMod.RefKnight.transform.position.y); + + } + + public static List Create() + { + List data = new List(); + //EnemyData dat = enemyPool.FindAll(ed => ed.gameObject != null && ed.gameObject.activeSelf)[num - 1]; + FSMs.ForEach(delegate (EnemyData dat) + { + GameObject gameObject2 = UnityEngine.Object.Instantiate(dat.gameObject, dat.gameObject.transform.position, dat.gameObject.transform.rotation) as GameObject; + Component component = gameObject2.GetComponent(); + PlayMakerFSM playMakerFSM2 = FSMUtility.LocateFSM(gameObject2, dat.FSM.FsmName); + int value8 = playMakerFSM2.FsmVariables.GetFsmInt("HP").Value; + gameObject2.SetActive(true); + data.Add(new EnemyData(value8, playMakerFSM2, component, parent, gameObject2)); + Console.AddLine(dat.gameObject.name+"Cloning enemy as: " + gameObject2.name); + }); + return data; + } + public static void RemoveAll() + { + //get all created + FSMs2.ForEach(delegate (EnemyData dat) + { + // if (!FSMs.Any(ed => ed.gameObject == dat.gameObject)) + //{ + UnityEngine.Object.Destroy(dat.gameObject); + //} + + }); + + } + public static List GetAllEnemies(List Include) + { + float boxSize = 250f; + List ret = new List(); + if (HeroController.instance != null && !HeroController.instance.cState.transitioning && DebugMod.GM.IsGameplayScene()) + { + int layerMask = 133120; + Collider2D[] array = Physics2D.OverlapBoxAll(DebugMod.RefKnight.transform.position, new Vector2(boxSize, boxSize), 1f, layerMask); + if (array != null) + { + for (int i = 0; i < array.Length; i++) + { + PlayMakerFSM playMakerFSM = FSMUtility.LocateFSM(array[i].gameObject, "health_manager_enemy"); + if (playMakerFSM == null) + { + FSMUtility.LocateFSM(array[i].gameObject, "health_manager"); + } + if (playMakerFSM && array[i].gameObject.activeSelf && !(Include.Any(ed => ed.gameObject == array[i].gameObject)) && !Ignore(array[i].gameObject.name)) + { + Component component = array[i].gameObject.GetComponent(); + if (component == null) + { + component = null; + } + int value = playMakerFSM.FsmVariables.GetFsmInt("HP").Value; + ret.Add(new EnemyData(value, playMakerFSM, component, parent, array[i].gameObject)); + } + } + } + } + return ret; + } + } +} From 8932c7160b56182433d146fe24b833f597f49d28 Mon Sep 17 00:00:00 2001 From: MagneticPizza Date: Fri, 12 Nov 2021 14:35:34 -0500 Subject: [PATCH 67/91] stuff ugh --- Source/BossHandler.cs | 2 +- Source/DebugMod.csproj | 7 + Source/ReflectionHelper.cs | 410 ++++++++++++++++++++++++++++++++++ Source/SavePositionManager.cs | 59 ++++- Source/packages.config | 4 + 5 files changed, 476 insertions(+), 6 deletions(-) create mode 100644 Source/ReflectionHelper.cs create mode 100644 Source/packages.config diff --git a/Source/BossHandler.cs b/Source/BossHandler.cs index cd51f38..7b751b0 100644 --- a/Source/BossHandler.cs +++ b/Source/BossHandler.cs @@ -18,7 +18,7 @@ public static class BossHandler public static bool ghostFound; private static bool fsmToggle = false; - private static NonBouncer _coro; +// private static NonBouncer _coro; public static void LookForBoss(string sceneName) { diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 7ae63bf..2abdc85 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -73,9 +73,13 @@ .\References\UnityEngine.UI.dll False + + ..\packages\ValueTupleBridge.0.1.5\lib\net35\ValueTupleBridge.dll + + @@ -175,6 +179,9 @@ + + + <_PostBuildHookTimestamp>@(IntermediateAssembly->'%(FullPath).timestamp') diff --git a/Source/ReflectionHelper.cs b/Source/ReflectionHelper.cs new file mode 100644 index 0000000..3de1396 --- /dev/null +++ b/Source/ReflectionHelper.cs @@ -0,0 +1,410 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; +using System.Reflection.Emit; +using JetBrains.Annotations; + +namespace Modding +{ + /// + /// A class to aid in reflection while caching it. + /// + public static class ReflectionHelper + { + private static readonly Dictionary> Fields = + new Dictionary>(); + + private static readonly Dictionary Getters = new Dictionary(); + + private static readonly Dictionary Setters = new Dictionary(); + + private static bool _preloaded; + + internal static T2 GetField(T1 instance, string v) + { + throw new NotImplementedException(); + } + + /// + /// Caches all fields on a type to frontload cost of reflection + /// + /// The type to cache + public static void CacheFields() + { + Type t = typeof(T); + if (!Fields.TryGetValue(t, out Dictionary tFields)) + { + tFields = new Dictionary(); + } + + // Not gonna redesign this class to avoid reflection, this shouldn't be called during gameplay anyway + MethodInfo getGetter = + typeof(ReflectionHelper).GetMethod(nameof(GetGetter), BindingFlags.NonPublic | BindingFlags.Static); + MethodInfo getSetter = + typeof(ReflectionHelper).GetMethod(nameof(GetSetter), BindingFlags.NonPublic | BindingFlags.Static); + + foreach (FieldInfo field in t.GetFields(BindingFlags.NonPublic | BindingFlags.Public | + BindingFlags.Instance | BindingFlags.Static)) + { + tFields[field.Name] = field; + + if (!field.IsLiteral) + { + getGetter?.MakeGenericMethod(t, field.FieldType).Invoke(null, new object[] { field }); + } + + if (!field.IsLiteral && !field.IsInitOnly) + { + getSetter?.MakeGenericMethod(t, field.FieldType).Invoke(null, new object[] { field }); + } + } + } + + internal static void SetField(T1 instance, string v, object newValue) + { + throw new NotImplementedException(); + } + + /// + /// Gets a field on a type + /// + /// Type + /// Field name + /// + /// FieldInfo for field or null if field does not exist. + public static FieldInfo GetField(Type t, string field, bool instance = true) + { + if (!Fields.TryGetValue(t, out Dictionary typeFields)) + { + Fields.Add(t, typeFields = new Dictionary()); + } + + if (typeFields.TryGetValue(field, out FieldInfo fi)) + { + return fi; + } + + fi = t.GetField(field, + BindingFlags.NonPublic | BindingFlags.Public | + (instance ? BindingFlags.Instance : BindingFlags.Static)); + + if (fi != null) + { + typeFields.Add(field, fi); + } + + return fi; + } + + internal static void PreloadCommonTypes() + { + if (_preloaded) + { + return; + } + + Stopwatch watch = new Stopwatch(); + watch.Start(); + + CacheFields(); + CacheFields(); + CacheFields(); + CacheFields(); + + watch.Stop(); + +// Logger.APILogger.Log($"Preloaded reflection in {watch.ElapsedMilliseconds}ms"); + + _preloaded = true; + } + + /// + /// Gets delegate getting field on type + /// + /// FieldInfo for field. + /// Function which gets value of field + private static Delegate GetGetter(FieldInfo fi) + { + if (Getters.TryGetValue(fi, out Delegate d)) + { + return d; + } + + if (fi.IsLiteral) + { + throw new ArgumentException("Field cannot be const", nameof(fi)); + } + + d = fi.IsStatic + ? CreateGetStaticFieldDelegate(fi) + : CreateGetFieldDelegate(fi); + + Getters.Add(fi, d); + + return d; + } + + /// + /// Gets delegate setting field on type + /// + /// FieldInfo for field. + /// Function which sets field passed as FieldInfo + private static Delegate GetSetter(FieldInfo fi) + { + if (Setters.TryGetValue(fi, out Delegate d)) + { + return d; + } + + if (fi.IsLiteral || fi.IsInitOnly) + { + throw new ArgumentException("Field cannot be readonly or const", nameof(fi)); + } + + d = fi.IsStatic + ? CreateSetStaticFieldDelegate(fi) + : CreateSetFieldDelegate(fi); + + Setters.Add(fi, d); + + return d; + } + + /// + /// Create delegate returning value of static field. + /// + /// FieldInfo of field + /// Field type + /// Type which field resides upon + /// Function returning static field + private static Delegate CreateGetStaticFieldDelegate(FieldInfo fi) + { + DynamicMethod dm = new DynamicMethod + ( + "FieldAccess" + fi.DeclaringType?.Name + fi.Name, + typeof(TField), + new Type[0], + typeof(TType) + ); + + ILGenerator gen = dm.GetILGenerator(); + + gen.Emit(OpCodes.Ldsfld, fi); + gen.Emit(OpCodes.Ret); + + return dm.CreateDelegate(typeof(Func)); + } + + /// + /// Create delegate returning value of field of object + /// + /// + /// + /// + /// Function which returns value of field of object parameter + private static Delegate CreateGetFieldDelegate(FieldInfo fi) + { + DynamicMethod dm = new DynamicMethod + ( + "FieldAccess" + fi.DeclaringType?.Name + fi.Name, + typeof(TField), + new[] { typeof(TType) }, + typeof(TType) + ); + + ILGenerator gen = dm.GetILGenerator(); + + gen.Emit(OpCodes.Ldarg_0); + gen.Emit(OpCodes.Ldfld, fi); + gen.Emit(OpCodes.Ret); + + return dm.CreateDelegate(typeof(Func)); + } + + private static Delegate CreateSetFieldDelegate(FieldInfo fi) + { + DynamicMethod dm = new DynamicMethod + ( + "FieldSet" + fi.DeclaringType?.Name + fi.Name, + typeof(void), + new[] { typeof(TType), typeof(TField) }, + typeof(TType) + ); + + ILGenerator gen = dm.GetILGenerator(); + + gen.Emit(OpCodes.Ldarg_0); + gen.Emit(OpCodes.Ldarg_1); + gen.Emit(OpCodes.Stfld, fi); + gen.Emit(OpCodes.Ret); + + return dm.CreateDelegate(typeof(Action)); + } + + private static Delegate CreateSetStaticFieldDelegate(FieldInfo fi) + { + DynamicMethod dm = new DynamicMethod + ( + "FieldSet" + fi.DeclaringType?.Name + fi.Name, + typeof(void), + new[] { typeof(TField) }, + typeof(TType) + ); + + ILGenerator gen = dm.GetILGenerator(); + + gen.Emit(OpCodes.Ldarg_0); + gen.Emit(OpCodes.Stsfld, fi); + gen.Emit(OpCodes.Ret); + + return dm.CreateDelegate(typeof(Action)); + } + + /// + /// Get a field on an object using a string. Cast to TCast before returning and if field doesn't exist return default. + /// + /// Object/Object of type which the field is on + /// Name of the field + /// Default return + /// Type of field + /// Type of object being passed in + /// Type of return. + /// The value of a field on an object/type + [PublicAPI] + public static TCast GetAttr(TObject obj, string name, TCast @default = default(TCast)) + { + FieldInfo fi = GetField(typeof(TObject), name); + + return fi == null + ? @default + : (TCast)(object)((Func)GetGetter(fi))(obj); + } + + /// + /// Get a field on an object using a string. + /// + /// Object/Object of type which the field is on + /// Name of the field + /// Type of field + /// Type of object being passed in + /// The value of a field on an object/type + [PublicAPI] + public static TField GetAttr(TObject obj, string name) + { + FieldInfo fi = GetField(typeof(TObject), name) ?? throw new MissingFieldException(); + + return ((Func)GetGetter(fi))(obj); + } + + /// + /// Get a static field on an type using a string. + /// + /// Name of the field + /// Type which static field resides upon + /// Type of field + /// The value of a field on an object/type + [PublicAPI] + public static TField GetAttr(string name) + { + FieldInfo fi = GetField(typeof(TType), name, false); + + return fi == null ? default(TField) : ((Func)GetGetter(fi))(); + } + + /// + /// Set a field on an object using a string. + /// + /// Object/Object of type which the field is on + /// Name of the field + /// Value to set the field to + /// Type of field + /// Type of object being passed in + [PublicAPI] + public static void SetAttrSafe(TObject obj, string name, TField value) + { + FieldInfo fi = GetField(typeof(TObject), name); + + if (fi == null) + { + return; + } + + ((Action)GetSetter(fi))(obj, value); + } + + /// + /// Set a field on an object using a string. + /// + /// Object/Object of type which the field is on + /// Name of the field + /// Value to set the field to + /// Type of field + /// Type of object being passed in + [PublicAPI] + public static void SetAttr(TObject obj, string name, TField value) + { + FieldInfo fi = GetField(typeof(TObject), name) ?? + throw new MissingFieldException($"Field {name} does not exist!"); + + ((Action)GetSetter(fi))(obj, value); + } + + /// + /// Set a static field on an type using a string. + /// + /// Name of the field + /// Value to set the field to + /// Type which static field resides upon + /// Type of field + [PublicAPI] + public static void SetAttr(string name, TField value) + { + ((Action)GetGetter(GetField(typeof(TType), name, false)))(value); + } + + #region Obsolete + + /// + /// Set a field on an object using a string. + /// + /// Object/Object of type which the field is on + /// Name of the field + /// Value to set the field to to + /// Whether or not to get an instance field or a static field + /// Type of the object which the field holds. + [PublicAPI] + [Obsolete("Use SetAttr and SetAttr.")] + public static void SetAttr(object obj, string name, T val, bool instance = true) + { + if (obj == null || string.IsNullOrEmpty(name)) + { + return; + } + + GetField(obj.GetType(), name, instance)?.SetValue(obj, val); + } + + /// + /// Get a field on an object/type using a string. + /// + /// Object/Object of type which the field is on + /// Name of the field + /// Whether or not to get an instance field or a static field + /// Type of the object which the field holds. + /// The value of a field on an object/type + [PublicAPI] + [Obsolete("Use GetAttr.")] + public static T GetAttr(object obj, string name, bool instance = true) + { + if (obj == null || string.IsNullOrEmpty(name)) + { + return default(T); + } + + return (T)GetField(obj.GetType(), name, instance)?.GetValue(obj); + } + + #endregion + } +} \ No newline at end of file diff --git a/Source/SavePositionManager.cs b/Source/SavePositionManager.cs index 9447e12..edfbb22 100644 --- a/Source/SavePositionManager.cs +++ b/Source/SavePositionManager.cs @@ -2,20 +2,62 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using static Modding.ReflectionHelper; using UnityEngine; using static DebugMod.EnemiesPanel; namespace DebugMod { public class SavePositionManager { + public class floats + { + public float[] value; + public string[] name; + } + public class ints + { + public int[] value; + public string[] name; + } + public class bools + { + public bool[] value; + public string[] name; + } + public static floats floata = new floats(); + public static List FSMs = new List(); public static List FSMs2 = new List(); - static Vector3 vect = new(0,0,0); + //public static List; + //public static List + // too complicated public static PlayMakerFSM KnightFsm = DebugMod.RefKnight.LocateMyFSM("Knight-ProxyFSM") ; + public static Vector3 KnightPos; + public static Vector3 CamPos; + //get => return GetAttr; + public void set (float[] ar) { + for (int i = 0; i < ar.Length; i++) + { + SetAttr(HeroController.instance, "dash_timer", ar[i]); + } + } + + + public static Vector2 KnightVel; + // public static List + public static float dash_timer; public static void SavePosition() { - vect = DebugMod.RefKnight.transform.position; - // save fsms :eyes: + dash_timer = GetField(HeroController.instance, "dash_timer"); + KnightPos = DebugMod.RefKnight.gameObject.transform.position; + KnightVel = HeroController.instance.current_velocity; + CamPos = DebugMod.RefCamera.gameObject.transform.position; + + + + //schmove = DebugMod.RefKnight. + // save fsms :eyes: + FSMs = GetAllEnemies(FSMs); FSMs.ForEach(delegate (EnemyData dat) { @@ -30,9 +72,16 @@ public static void LoadPosition() //create and name fsms2 RemoveAll(); FSMs2 = Create(); + // Move knight to saved location, change velocity to saved velocity, Move Camera to saved campos, + SetField(HeroController.instance, "dash_timer", dash_timer); + DebugMod.RefKnight.gameObject.transform.position = KnightPos; + HeroController.instance.current_velocity = KnightVel; + DebugMod.RefCamera.gameObject.transform.position = CamPos; + //HeroController.instance.DASH_COOLDOWN = + //HeroController.instance.DASH_COOLDOWN_CH = + //HeroController.instance.dash - DebugMod.RefKnight.transform.position = vect; - DebugMod.RefCamera.SnapTo(DebugMod.RefKnight.transform.position.x, DebugMod.RefKnight.transform.position.y); + //DebugMod.RefCamera.SnapTo(DebugMod.RefKnight.transform.position.x, DebugMod.RefKnight.transform.position.y); } diff --git a/Source/packages.config b/Source/packages.config new file mode 100644 index 0000000..a1b93e0 --- /dev/null +++ b/Source/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From a46da71a89cc7a54e0899fbe5abf5106539bd83f Mon Sep 17 00:00:00 2001 From: MagneticPizza Date: Fri, 12 Nov 2021 18:33:35 -0500 Subject: [PATCH 68/91] fix --- Source/ReflectionHelper.cs | 4 ++-- Source/SavePositionManager.cs | 38 +++++++---------------------------- 2 files changed, 9 insertions(+), 33 deletions(-) diff --git a/Source/ReflectionHelper.cs b/Source/ReflectionHelper.cs index 3de1396..050ba94 100644 --- a/Source/ReflectionHelper.cs +++ b/Source/ReflectionHelper.cs @@ -61,10 +61,10 @@ public static void CacheFields() } } - internal static void SetField(T1 instance, string v, object newValue) + /* internal static void SetField(T1 instance, string v, object newValue) { throw new NotImplementedException(); - } + }*/ /// /// Gets a field on a type diff --git a/Source/SavePositionManager.cs b/Source/SavePositionManager.cs index edfbb22..5d53a0a 100644 --- a/Source/SavePositionManager.cs +++ b/Source/SavePositionManager.cs @@ -2,30 +2,13 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using static Modding.ReflectionHelper; +using System.Reflection; using UnityEngine; using static DebugMod.EnemiesPanel; namespace DebugMod { public class SavePositionManager { - public class floats - { - public float[] value; - public string[] name; - } - public class ints - { - public int[] value; - public string[] name; - } - public class bools - { - public bool[] value; - public string[] name; - } - public static floats floata = new floats(); - public static List FSMs = new List(); public static List FSMs2 = new List(); //public static List; @@ -33,22 +16,12 @@ public class bools // too complicated public static PlayMakerFSM KnightFsm = DebugMod.RefKnight.LocateMyFSM("Knight-ProxyFSM") ; public static Vector3 KnightPos; public static Vector3 CamPos; - //get => return GetAttr; - public void set (float[] ar) { - for (int i = 0; i < ar.Length; i++) - { - SetAttr(HeroController.instance, "dash_timer", ar[i]); - } - } - - public static Vector2 KnightVel; - // public static List - public static float dash_timer; + // public static List public static void SavePosition() { - dash_timer = GetField(HeroController.instance, "dash_timer"); + //float dash_timer = ReflectionHelper.GetField(HeroController.instance, "dash_timer") KnightPos = DebugMod.RefKnight.gameObject.transform.position; KnightVel = HeroController.instance.current_velocity; CamPos = DebugMod.RefCamera.gameObject.transform.position; @@ -70,10 +43,13 @@ public static void LoadPosition() //debuging(); //create and name fsms2 + float time = Time.realtimeSinceStartup; RemoveAll(); + Console.AddLine((Time.realtimeSinceStartup - time).ToString()); FSMs2 = Create(); + Console.AddLine((Time.realtimeSinceStartup - time).ToString()); // Move knight to saved location, change velocity to saved velocity, Move Camera to saved campos, - SetField(HeroController.instance, "dash_timer", dash_timer); + //ReflectionHelper.SetField(HeroController.instance, "dash_timer", newValue); DebugMod.RefKnight.gameObject.transform.position = KnightPos; HeroController.instance.current_velocity = KnightVel; DebugMod.RefCamera.gameObject.transform.position = CamPos; From 4016eb1acbd43d5c1edc1939ccbcd3b27ccb5304 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Sun, 14 Nov 2021 00:34:29 -0500 Subject: [PATCH 69/91] fixage --- Source/EnemiesPanel.cs | 2 + Source/SavePositionManager.cs | 72 ++++++++++++++++++++--------------- 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/Source/EnemiesPanel.cs b/Source/EnemiesPanel.cs index 664219f..68c3e34 100644 --- a/Source/EnemiesPanel.cs +++ b/Source/EnemiesPanel.cs @@ -59,6 +59,7 @@ private static void DelClicked(string buttonName) private static void CloneClicked(string buttonName) { + float time = Time.realtimeSinceStartup; int num = Convert.ToInt32(buttonName.Substring(5)); EnemyData dat = enemyPool.FindAll(ed => ed.gameObject != null && ed.gameObject.activeSelf)[num - 1]; @@ -68,6 +69,7 @@ private static void CloneClicked(string buttonName) int value8 = playMakerFSM2.FsmVariables.GetFsmInt("HP").Value; enemyPool.Add(new EnemyData(value8, playMakerFSM2, component, parent, gameObject2)); Console.AddLine("Cloning enemy as: " + gameObject2.name); + Console.AddLine((Time.realtimeSinceStartup - time).ToString()); } private static void InfClicked(string buttonName) diff --git a/Source/SavePositionManager.cs b/Source/SavePositionManager.cs index 5d53a0a..a2b7d24 100644 --- a/Source/SavePositionManager.cs +++ b/Source/SavePositionManager.cs @@ -1,10 +1,11 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Text; -using System.Reflection; using UnityEngine; +using System.Reflection; using static DebugMod.EnemiesPanel; +using System; + namespace DebugMod { public class SavePositionManager @@ -31,7 +32,7 @@ public static void SavePosition() //schmove = DebugMod.RefKnight. // save fsms :eyes: - FSMs = GetAllEnemies(FSMs); + FSMs = GetAllEnemies(FSMs2); FSMs.ForEach(delegate (EnemyData dat) { dat.gameObject.SetActive(false); @@ -40,19 +41,21 @@ public static void SavePosition() } public static void LoadPosition() { - - //debuging(); - //create and name fsms2 - float time = Time.realtimeSinceStartup; - RemoveAll(); - Console.AddLine((Time.realtimeSinceStartup - time).ToString()); - FSMs2 = Create(); - Console.AddLine((Time.realtimeSinceStartup - time).ToString()); - // Move knight to saved location, change velocity to saved velocity, Move Camera to saved campos, - //ReflectionHelper.SetField(HeroController.instance, "dash_timer", newValue); - DebugMod.RefKnight.gameObject.transform.position = KnightPos; - HeroController.instance.current_velocity = KnightVel; - DebugMod.RefCamera.gameObject.transform.position = CamPos; + try + { + RemoveAll(); + FSMs2 = Create(); + // Move knight to saved location, change velocity to saved velocity, Move Camera to saved campos, + //ReflectionHelper.SetField(HeroController.instance, "dash_timer", newValue); + DebugMod.RefKnight.gameObject.transform.position = KnightPos; + HeroController.instance.current_velocity = KnightVel; + DebugMod.RefCamera.gameObject.transform.position = CamPos; + } + catch(Exception e) + { + Console.AddLine(e.Message); + Console.AddLine(e.StackTrace); + } //HeroController.instance.DASH_COOLDOWN = //HeroController.instance.DASH_COOLDOWN_CH = //HeroController.instance.dash @@ -64,33 +67,40 @@ public static void LoadPosition() public static List Create() { List data = new List(); - //EnemyData dat = enemyPool.FindAll(ed => ed.gameObject != null && ed.gameObject.activeSelf)[num - 1]; - FSMs.ForEach(delegate (EnemyData dat) + // FSMs.ForEach(delegate (EnemyData dat) + // if (FSMs.FindAll(ed => ed.gameObject != null && ed.gameObject.activeSelf)){ + + // } + for (int i = 0; i < FSMs.Count; i++) { - GameObject gameObject2 = UnityEngine.Object.Instantiate(dat.gameObject, dat.gameObject.transform.position, dat.gameObject.transform.rotation) as GameObject; + Console.AddLine(i.ToString()); + EnemyData dattemp = FSMs.FindAll(ed => ed.gameObject != null)[i]; + float time = Time.realtimeSinceStartup; + //Console.AddLine((Time.realtimeSinceStartup - time).ToString()); + + GameObject gameObject2 = UnityEngine.Object.Instantiate(dattemp.FSM.gameObject, dattemp.gameObject.transform.position, dattemp.gameObject.transform.rotation) as GameObject; Component component = gameObject2.GetComponent(); - PlayMakerFSM playMakerFSM2 = FSMUtility.LocateFSM(gameObject2, dat.FSM.FsmName); + + PlayMakerFSM playMakerFSM2 = FSMUtility.LocateFSM(gameObject2, dattemp.FSM.FsmName); + int value8 = playMakerFSM2.FsmVariables.GetFsmInt("HP").Value; gameObject2.SetActive(true); data.Add(new EnemyData(value8, playMakerFSM2, component, parent, gameObject2)); - Console.AddLine(dat.gameObject.name+"Cloning enemy as: " + gameObject2.name); - }); - return data; - } + }; + return data; + } public static void RemoveAll() { //get all created FSMs2.ForEach(delegate (EnemyData dat) { - // if (!FSMs.Any(ed => ed.gameObject == dat.gameObject)) - //{ - UnityEngine.Object.Destroy(dat.gameObject); - //} + if (!FSMs.Any(ed => ed.gameObject == dat.gameObject)) + GameObject.Destroy(dat.gameObject.gameObject.gameObject.gameObject); }); } - public static List GetAllEnemies(List Include) + public static List GetAllEnemies(List Exclude) { float boxSize = 250f; List ret = new List(); @@ -107,7 +117,7 @@ public static List GetAllEnemies(List Include) { FSMUtility.LocateFSM(array[i].gameObject, "health_manager"); } - if (playMakerFSM && array[i].gameObject.activeSelf && !(Include.Any(ed => ed.gameObject == array[i].gameObject)) && !Ignore(array[i].gameObject.name)) + if (playMakerFSM && array[i].gameObject.activeSelf && !(Exclude.Any(ed => ed.gameObject == array[i].gameObject)) && !Ignore(array[i].gameObject.name)) { Component component = array[i].gameObject.GetComponent(); if (component == null) From 62b324243ad1d8ee8ffc69583fff9aae30a7ff7b Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Mon, 29 Nov 2021 01:19:14 -0500 Subject: [PATCH 70/91] Update EnemiesPanel.cs --- Source/EnemiesPanel.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Source/EnemiesPanel.cs b/Source/EnemiesPanel.cs index 68c3e34..212c281 100644 --- a/Source/EnemiesPanel.cs +++ b/Source/EnemiesPanel.cs @@ -59,7 +59,6 @@ private static void DelClicked(string buttonName) private static void CloneClicked(string buttonName) { - float time = Time.realtimeSinceStartup; int num = Convert.ToInt32(buttonName.Substring(5)); EnemyData dat = enemyPool.FindAll(ed => ed.gameObject != null && ed.gameObject.activeSelf)[num - 1]; @@ -69,7 +68,6 @@ private static void CloneClicked(string buttonName) int value8 = playMakerFSM2.FsmVariables.GetFsmInt("HP").Value; enemyPool.Add(new EnemyData(value8, playMakerFSM2, component, parent, gameObject2)); Console.AddLine("Cloning enemy as: " + gameObject2.name); - Console.AddLine((Time.realtimeSinceStartup - time).ToString()); } private static void InfClicked(string buttonName) @@ -243,7 +241,7 @@ public static void Update() position.x *= 1920f / Screen.width; position.y *= 1080f / Screen.height; position.y = 1080f - position.y; - + dat.hitbox.SetPosition(position); dat.hitbox.ResizeBG(size); } @@ -328,7 +326,7 @@ public static void Update() public static void Reset() { - foreach(EnemyData dat in enemyPool) + foreach (EnemyData dat in enemyPool) { dat.hitbox.Destroy(); dat.hpBar.Destroy(); @@ -507,4 +505,4 @@ private static void EnemyDescendants(Transform transform) } } } -} +} \ No newline at end of file From 443998f78638b551625ec3807184e5fde34a3e0f Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Mon, 29 Nov 2021 01:25:43 -0500 Subject: [PATCH 71/91] remove usused things --- Source/BindableFunctions.cs | 1 + Source/BossHandler.cs | 2 +- Source/EnemiesPanel.cs | 4 ++-- Source/ReflectionHelper.cs | 11 ----------- 4 files changed, 4 insertions(+), 14 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 01b049e..1ded406 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -237,6 +237,7 @@ public static void Reset() #endregion #region SaveStates + [BindableMethod(name = "Position Save", category = "SaveStates")] public static void SavePosition() { diff --git a/Source/BossHandler.cs b/Source/BossHandler.cs index 7b751b0..cd51f38 100644 --- a/Source/BossHandler.cs +++ b/Source/BossHandler.cs @@ -18,7 +18,7 @@ public static class BossHandler public static bool ghostFound; private static bool fsmToggle = false; -// private static NonBouncer _coro; + private static NonBouncer _coro; public static void LookForBoss(string sceneName) { diff --git a/Source/EnemiesPanel.cs b/Source/EnemiesPanel.cs index 212c281..35c9691 100644 --- a/Source/EnemiesPanel.cs +++ b/Source/EnemiesPanel.cs @@ -326,7 +326,7 @@ public static void Update() public static void Reset() { - foreach (EnemyData dat in enemyPool) + foreach(EnemyData dat in enemyPool) { dat.hitbox.Destroy(); dat.hpBar.Destroy(); @@ -505,4 +505,4 @@ private static void EnemyDescendants(Transform transform) } } } -} \ No newline at end of file +} diff --git a/Source/ReflectionHelper.cs b/Source/ReflectionHelper.cs index 050ba94..9184538 100644 --- a/Source/ReflectionHelper.cs +++ b/Source/ReflectionHelper.cs @@ -21,11 +21,6 @@ public static class ReflectionHelper private static bool _preloaded; - internal static T2 GetField(T1 instance, string v) - { - throw new NotImplementedException(); - } - /// /// Caches all fields on a type to frontload cost of reflection /// @@ -60,12 +55,6 @@ public static void CacheFields() } } } - - /* internal static void SetField(T1 instance, string v, object newValue) - { - throw new NotImplementedException(); - }*/ - /// /// Gets a field on a type /// From b4faf0d2fdd78768e943b75dfb0090f24c4a9809 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Mon, 29 Nov 2021 01:28:10 -0500 Subject: [PATCH 72/91] fix indentation --- Source/SaveState.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Source/SaveState.cs b/Source/SaveState.cs index 97c3ab3..0624d9b 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -186,16 +186,16 @@ private IEnumerator LoadStateCoro() int oldMP = PlayerData.instance.MPCharge; data.cameraLockArea = (data.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); - string scene = "Room_Mender_House"; - if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == "Room_Mender_House") - { - scene = "Room_Sly_Storeroom"; - } - GameManager.instance.ChangeToScene(scene, "", 0f);// i hate that i have to do this. - while (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != scene) - { - yield return null; - } + string scene = "Room_Mender_House"; + if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == "Room_Mender_House") + { + scene = "Room_Sly_Storeroom"; + } + GameManager.instance.ChangeToScene(scene, "", 0f);// i hate that i have to do this. + while (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != scene) + { + yield return null; + } GameManager.instance.sceneData = (SceneData.instance = JsonUtility.FromJson(JsonUtility.ToJson(data.savedSd))); GameManager.instance.ResetSemiPersistentItems(); From 7033d54546853fdfff62bac82ecf08b84de54f3c Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Sat, 11 Dec 2021 20:31:02 -0500 Subject: [PATCH 73/91] remove fast pause for accuracy --- Source/GUIController.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Source/GUIController.cs b/Source/GUIController.cs index 5a46885..57a211c 100644 --- a/Source/GUIController.cs +++ b/Source/GUIController.cs @@ -274,11 +274,6 @@ public void Update() } } - if (DebugMod.IH.inputActions.pause.WasPressed && DebugMod.GM.IsGamePaused()) - { - UIManager.instance.TogglePauseGame(); - } - if (DebugMod.cameraFollow) { BindableFunctions.cameraGameplayScene.SetValue(DebugMod.RefCamera, false); From d89302e9dda398e88858b88b2cf66dfd1d0b42d2 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Tue, 14 Dec 2021 22:58:36 +0100 Subject: [PATCH 74/91] yoinked flib's demasker func --- Source/BindableFunctions.cs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index a382b51..d51813a 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -335,6 +335,43 @@ public static void ToggleVignette() HeroController.instance.vignette.enabled = !HeroController.instance.vignette.enabled; } + [BindableMethod(name = "Deactivate Visual Masks", category = "Visual")] + public static void DeactivateVisualMasks() { + int ctr = 0; + + void disableMask(GameObject go) { + foreach (Renderer r in go.GetComponentsInChildren()) { + if (r.enabled) { + ctr++; + r.enabled = false; + } + } + } + + float knightZ = HeroController.instance.transform.position.z; + foreach (GameObject go in GameObject.FindObjectsOfType()) { + if (go.transform.position.z > knightZ) continue; + + // A collection of ways to identify masks. It's possible some slip through the cracks I guess + if (go.name.StartsWith("msk_")) + disableMask(go); + else if (go.name.StartsWith("Tut_msk")) + disableMask(go); + else if (go.name.StartsWith("black_solid")) + disableMask(go); + else if (go.name.ToLower().Contains("vignette")) + disableMask(go); + else if (go.LocateMyFSM("unmasker") is PlayMakerFSM) + disableMask(go); + else if (go.LocateMyFSM("remasker_inverse") is PlayMakerFSM) + disableMask(go); + else if (go.LocateMyFSM("remasker") is PlayMakerFSM) + disableMask(go); + } + + Console.AddLine($"Deactivated {ctr} masks"); + } + [BindableMethod(name = "Toggle Hero Light", category = "Visual")] public static void ToggleHeroLight() { From dccde388ad5172b60dd33882d0318c45b124e2f9 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Wed, 15 Dec 2021 23:47:52 -0500 Subject: [PATCH 75/91] Don't load states while transitioning or dead --- Source/PlayerDeathWatcher.cs | 2 +- Source/SaveState.cs | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Source/PlayerDeathWatcher.cs b/Source/PlayerDeathWatcher.cs index 3c0df2d..cc082b2 100644 --- a/Source/PlayerDeathWatcher.cs +++ b/Source/PlayerDeathWatcher.cs @@ -2,7 +2,7 @@ { public static class PlayerDeathWatcher { - private static bool playerDead; + public static bool playerDead; public static void Reset() { diff --git a/Source/SaveState.cs b/Source/SaveState.cs index 0624d9b..a796f40 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -120,7 +120,14 @@ public void SaveStateToFile(int paramSlot) public void LoadTempState() { - HeroController.instance.StartCoroutine(LoadStateCoro()); + //Don't load states if not alive/in transition (breaks savestates) + if (!PlayerDeathWatcher.playerDead && !HeroController.instance.cState.transitioning) { + HeroController.instance.StartCoroutine(LoadStateCoro()); + } + else + { + Console.AddLine("Don't load states while dead or in a transition! if you are not, this is a bug."); + } } public void NewLoadStateFromFile() From 9f1162613591b9072bc9b6e73a35f9a102e0e865 Mon Sep 17 00:00:00 2001 From: cerpintext Date: Sun, 9 Jan 2022 15:21:54 +0100 Subject: [PATCH 76/91] tiny UX fixes --- Source/BindableFunctions.cs | 4 +-- Source/DebugMod.cs | 8 +++-- Source/SavePositionManager.cs | 55 ++++++++++++++++++++--------------- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 995d9ae..7786355 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -238,12 +238,12 @@ public static void Reset() #region SaveStates - [BindableMethod(name = "Position Save", category = "SaveStates")] + [BindableMethod(name = "Position Save", category = "Savestates")] public static void SavePosition() { SavePositionManager.SavePosition(); } - [BindableMethod(name = "Position Load", category = "SaveStates")] + [BindableMethod(name = "Position Load", category = "Savestates")] public static void LoadPosition() { SavePositionManager.LoadPosition(); diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index ec1997a..fb4c2c9 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -171,7 +171,11 @@ public override void Initialize() public override string GetVersion() { - return "1.4.6-early"; + string version = "1.5.0"; +#if DEBUG + version = string.Concat(version, "-dev"); +#endif + return version; } public override bool IsCurrent() @@ -186,7 +190,7 @@ public override bool IsCurrent() catch (Exception) { return true; - } + u } */ return true; } diff --git a/Source/SavePositionManager.cs b/Source/SavePositionManager.cs index a2b7d24..c40bcba 100644 --- a/Source/SavePositionManager.cs +++ b/Source/SavePositionManager.cs @@ -18,7 +18,9 @@ public class SavePositionManager public static Vector3 KnightPos; public static Vector3 CamPos; public static Vector2 KnightVel; - // public static List + public static string PositionScene; + public static bool InitialisedPosition = false; + // public static List public static void SavePosition() { @@ -26,42 +28,47 @@ public static void SavePosition() KnightPos = DebugMod.RefKnight.gameObject.transform.position; KnightVel = HeroController.instance.current_velocity; CamPos = DebugMod.RefCamera.gameObject.transform.position; + PositionScene = DebugMod.GetSceneName(); + InitialisedPosition = true; - - //schmove = DebugMod.RefKnight. // save fsms :eyes: - + FSMs = GetAllEnemies(FSMs2); FSMs.ForEach(delegate (EnemyData dat) { dat.gameObject.SetActive(false); }); + Console.AddLine("Positional save set in " + DebugMod.GetSceneName()); + } public static void LoadPosition() { - try - { - RemoveAll(); - FSMs2 = Create(); - // Move knight to saved location, change velocity to saved velocity, Move Camera to saved campos, - //ReflectionHelper.SetField(HeroController.instance, "dash_timer", newValue); - DebugMod.RefKnight.gameObject.transform.position = KnightPos; - HeroController.instance.current_velocity = KnightVel; - DebugMod.RefCamera.gameObject.transform.position = CamPos; - } - catch(Exception e) - { - Console.AddLine(e.Message); - Console.AddLine(e.StackTrace); - } - //HeroController.instance.DASH_COOLDOWN = - //HeroController.instance.DASH_COOLDOWN_CH = - //HeroController.instance.dash - - //DebugMod.RefCamera.SnapTo(DebugMod.RefKnight.transform.position.x, DebugMod.RefKnight.transform.position.y); + if (PositionScene == DebugMod.GetSceneName() && InitialisedPosition) { + try + { + RemoveAll(); + FSMs2 = Create(); + // Move knight to saved location, change velocity to saved velocity, Move Camera to saved campos, + //ReflectionHelper.SetField(HeroController.instance, "dash_timer", newValue); + DebugMod.RefKnight.gameObject.transform.position = KnightPos; + HeroController.instance.current_velocity = KnightVel; + DebugMod.RefCamera.gameObject.transform.position = CamPos; + } + catch(Exception e) + { + Console.AddLine(e.Message); + Console.AddLine(e.StackTrace); + } + //HeroController.instance.DASH_COOLDOWN = + //HeroController.instance.DASH_COOLDOWN_CH = + //HeroController.instance.dash + //DebugMod.RefCamera.SnapTo(DebugMod.RefKnight.transform.position.x, DebugMod.RefKnight.transform.position.y); + } else { + Console.AddLine("No positional save in " + DebugMod.GetSceneName()); + } } public static List Create() From ed0b8fd0fc19cb21fd514a88984f6ece339eebea Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Tue, 22 Feb 2022 19:39:51 -0500 Subject: [PATCH 77/91] add option of turning off room ids in savestate view --- Source/BindableFunctions.cs | 5 +++++ Source/DebugMod.cs | 2 +- Source/SaveState.cs | 1 + Source/SaveStatesPanel.cs | 9 ++++++++- Source/Settings.cs | 6 +++++- 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 7786355..d40c327 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -234,6 +234,11 @@ public static void Reset() pd.isInvincible=false; DebugMod.noclip=false; } + [BindableMethod(name = "Toggle showing room IDs", category = "Misc")] + public static void toggleShowRoomIDs() + { + DebugMod.settings.ShowRoomIDs = !DebugMod.settings.ShowRoomIDs; + } #endregion #region SaveStates diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index fb4c2c9..3847ba5 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -171,7 +171,7 @@ public override void Initialize() public override string GetVersion() { - string version = "1.5.0"; + string version = "1.5.1"; #if DEBUG version = string.Concat(version, "-dev"); #endif diff --git a/Source/SaveState.cs b/Source/SaveState.cs index a796f40..53e084f 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -283,6 +283,7 @@ public string[] GetSaveStateInfo() data.saveStateIdentifier, data.saveScene }; + } public SaveStateData DeepCopy() { diff --git a/Source/SaveStatesPanel.cs b/Source/SaveStatesPanel.cs index 148f017..5ec1a9e 100644 --- a/Source/SaveStatesPanel.cs +++ b/Source/SaveStatesPanel.cs @@ -95,7 +95,14 @@ public static void Update() foreach (KeyValuePair entry in SaveStateManager.GetSaveStatesInfo()) { - statePanel.GetText(entry.Key.ToString()).UpdateText(string.Format("{0} - {1}", entry.Value[0], entry.Value[1])); + if (DebugMod.settings.ShowRoomIDs) + { + statePanel.GetText(entry.Key.ToString()).UpdateText(string.Format("{0} - {1}", entry.Value[0], entry.Value[1])); + } + else + { + statePanel.GetText(entry.Key.ToString()).UpdateText(string.Format("{0}", entry.Value[0])); + } } } } diff --git a/Source/Settings.cs b/Source/Settings.cs index d5ad192..ad31f0d 100644 --- a/Source/Settings.cs +++ b/Source/Settings.cs @@ -54,7 +54,11 @@ public bool TopMenuVisible get => GetBool(true); set => SetBool(value); } - + public bool ShowRoomIDs + { + get => GetBool(true); + set => SetBool(value); + } public bool FirstRun { get => GetBool(true); From fd7827e4a29ecebe267421b50591e7555a2cba95 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Tue, 22 Feb 2022 19:48:29 -0500 Subject: [PATCH 78/91] move to more appropriate category --- Source/BindableFunctions.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index d40c327..e29c8b9 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -234,11 +234,7 @@ public static void Reset() pd.isInvincible=false; DebugMod.noclip=false; } - [BindableMethod(name = "Toggle showing room IDs", category = "Misc")] - public static void toggleShowRoomIDs() - { - DebugMod.settings.ShowRoomIDs = !DebugMod.settings.ShowRoomIDs; - } + #endregion #region SaveStates @@ -507,6 +503,11 @@ public static void ToggleAllPanels() EnemiesPanel.RefreshEnemyList(); } } + [BindableMethod(name = "Toggle showing room IDs", category = "Mod UI")] + public static void toggleShowRoomIDs() + { + DebugMod.settings.ShowRoomIDs = !DebugMod.settings.ShowRoomIDs; + } [BindableMethod(name = "Toggle Binds", category = "Mod UI")] public static void ToggleHelpPanel() From 4bddd5c14f7a8510fa9c19e446fb555cbb985888 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Sat, 5 Mar 2022 23:56:24 -0500 Subject: [PATCH 79/91] correct Variable & Function names --- Source/BindableFunctions.cs | 8 ++-- Source/DebugMod.cs | 4 +- Source/SavePositionManager.cs | 80 ++++++++++++----------------------- 3 files changed, 33 insertions(+), 59 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index e29c8b9..3f92825 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -240,14 +240,14 @@ public static void Reset() #region SaveStates [BindableMethod(name = "Position Save", category = "Savestates")] - public static void SavePosition() + public static void RoomSaveState() { - SavePositionManager.SavePosition(); + SavePositionManager.SaveState(); } [BindableMethod(name = "Position Load", category = "Savestates")] - public static void LoadPosition() + public static void RoomLoadState() { - SavePositionManager.LoadPosition(); + SavePositionManager.LoadState(); } [BindableMethod(name = "Quickslot (save)", category = "Savestates")] public static void SaveState() diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 3847ba5..dd162ba 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -19,7 +19,6 @@ public class DebugMod : Mod, IMod private static PlayMakerFSM _refKnightSlash; private static CameraController _refCamera; private static PlayMakerFSM _refDreamNail; - internal static GameManager GM => _gm != null ? _gm : (_gm = GameManager.instance); internal static InputHandler IH => _ih != null ? _ih : (_ih = GM.inputHandler); internal static HeroController HC => _hc != null ? _hc : (_hc = GM.hero_ctrl); @@ -27,7 +26,8 @@ public class DebugMod : Mod, IMod internal static PlayMakerFSM RefKnightSlash => _refKnightSlash != null ? _refKnightSlash : (_refKnightSlash = RefKnight.transform.Find("Attacks/Slash").GetComponent()); internal static CameraController RefCamera => _refCamera != null ? _refCamera : (_refCamera = GM.cameraCtrl); internal static PlayMakerFSM RefDreamNail => _refDreamNail != null ? _refDreamNail : (_refDreamNail = FSMUtility.LocateFSM(RefKnight, "Dream Nail")); - + internal static Collider2D RefHeroCollider => _refHeroCollider != null ? _refHeroCollider : (_refHeroCollider = RefKnight.GetComponent()); + internal static Collider2D RefHeroBox => _refHeroBox != null ? _refHeroBox : (_refHeroBox = RefKnight.transform.Find("HeroBox").GetComponent()); internal static DebugMod instance; internal static GlobalSettings settings; diff --git a/Source/SavePositionManager.cs b/Source/SavePositionManager.cs index c40bcba..e0637ce 100644 --- a/Source/SavePositionManager.cs +++ b/Source/SavePositionManager.cs @@ -11,7 +11,7 @@ namespace DebugMod public class SavePositionManager { public static List FSMs = new List(); - public static List FSMs2 = new List(); + public static List CreatedFSMs = new List(); //public static List; //public static List // too complicated public static PlayMakerFSM KnightFsm = DebugMod.RefKnight.LocateMyFSM("Knight-ProxyFSM") ; @@ -19,9 +19,9 @@ public class SavePositionManager public static Vector3 CamPos; public static Vector2 KnightVel; public static string PositionScene; - public static bool InitialisedPosition = false; + public static bool InitializedPosition = false; // public static List - public static void SavePosition() + public static void SaveState() { //float dash_timer = ReflectionHelper.GetField(HeroController.instance, "dash_timer") @@ -29,43 +29,28 @@ public static void SavePosition() KnightVel = HeroController.instance.current_velocity; CamPos = DebugMod.RefCamera.gameObject.transform.position; PositionScene = DebugMod.GetSceneName(); - InitialisedPosition = true; - - //schmove = DebugMod.RefKnight. - // save fsms :eyes: - - FSMs = GetAllEnemies(FSMs2); - FSMs.ForEach(delegate (EnemyData dat) - { - dat.gameObject.SetActive(false); - }); - + InitializedPosition = true; + FSMs = GetAllEnemies(new List()); + //TODO: check this . used to be FSMs = GetAllEnemies(CreatedFSMs); + FSMs.ForEach(delegate (EnemyData dat) { dat.gameObject.SetActive(false); }); Console.AddLine("Positional save set in " + DebugMod.GetSceneName()); - } - public static void LoadPosition() + public static void LoadState() { - if (PositionScene == DebugMod.GetSceneName() && InitialisedPosition) { + if (PositionScene == DebugMod.GetSceneName() && InitializedPosition) { try { - RemoveAll(); - FSMs2 = Create(); - // Move knight to saved location, change velocity to saved velocity, Move Camera to saved campos, - //ReflectionHelper.SetField(HeroController.instance, "dash_timer", newValue); + RemoveAllCopies(); + CreatedFSMs = Create(); + // Move knight to saved location, change velocity to saved velocity, Move Camera to saved camera position, DebugMod.RefKnight.gameObject.transform.position = KnightPos; HeroController.instance.current_velocity = KnightVel; DebugMod.RefCamera.gameObject.transform.position = CamPos; } - catch(Exception e) + catch (Exception e) { - Console.AddLine(e.Message); - Console.AddLine(e.StackTrace); + Console.AddLine("No positional save in " + DebugMod.GetSceneName()+", or a bug has occured."); } - //HeroController.instance.DASH_COOLDOWN = - //HeroController.instance.DASH_COOLDOWN_CH = - //HeroController.instance.dash - - //DebugMod.RefCamera.SnapTo(DebugMod.RefKnight.transform.position.x, DebugMod.RefKnight.transform.position.y); } else { Console.AddLine("No positional save in " + DebugMod.GetSceneName()); } @@ -74,39 +59,28 @@ public static void LoadPosition() public static List Create() { List data = new List(); - // FSMs.ForEach(delegate (EnemyData dat) - // if (FSMs.FindAll(ed => ed.gameObject != null && ed.gameObject.activeSelf)){ - - // } for (int i = 0; i < FSMs.Count; i++) { - Console.AddLine(i.ToString()); EnemyData dattemp = FSMs.FindAll(ed => ed.gameObject != null)[i]; - float time = Time.realtimeSinceStartup; - //Console.AddLine((Time.realtimeSinceStartup - time).ToString()); - - GameObject gameObject2 = UnityEngine.Object.Instantiate(dattemp.FSM.gameObject, dattemp.gameObject.transform.position, dattemp.gameObject.transform.rotation) as GameObject; - Component component = gameObject2.GetComponent(); - - PlayMakerFSM playMakerFSM2 = FSMUtility.LocateFSM(gameObject2, dattemp.FSM.FsmName); - - int value8 = playMakerFSM2.FsmVariables.GetFsmInt("HP").Value; - gameObject2.SetActive(true); - data.Add(new EnemyData(value8, playMakerFSM2, component, parent, gameObject2)); + GameObject gameObject = UnityEngine.Object.Instantiate(dattemp.FSM.gameObject, dattemp.gameObject.transform.position, dattemp.gameObject.transform.rotation) as GameObject; + Component component = gameObject.GetComponent(); + PlayMakerFSM playMakerFSM2 = FSMUtility.LocateFSM(gameObject, dattemp.FSM.FsmName); + int health = playMakerFSM2.FsmVariables.GetFsmInt("HP").Value; + gameObject.SetActive(true); + data.Add(new EnemyData(health, playMakerFSM2, component, parent, gameObject)); }; return data; } - public static void RemoveAll() + public static void RemoveAllCopies() { - //get all created - FSMs2.ForEach(delegate (EnemyData dat) + //get all copies and remove them. + CreatedFSMs.ForEach(delegate (EnemyData dat) { if (!FSMs.Any(ed => ed.gameObject == dat.gameObject)) GameObject.Destroy(dat.gameObject.gameObject.gameObject.gameObject); - }); - } + // this works but idk how ?? public static List GetAllEnemies(List Exclude) { float boxSize = 250f; @@ -129,10 +103,10 @@ public static List GetAllEnemies(List Exclude) Component component = array[i].gameObject.GetComponent(); if (component == null) { - component = null; + component = null; //? } - int value = playMakerFSM.FsmVariables.GetFsmInt("HP").Value; - ret.Add(new EnemyData(value, playMakerFSM, component, parent, array[i].gameObject)); + int Health = playMakerFSM.FsmVariables.GetFsmInt("HP").Value; + ret.Add(new EnemyData(Health, playMakerFSM, component, parent, array[i].gameObject)); } } } From febddcffaae49b14aad18ebfd2b08a806a3931f0 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Sat, 5 Mar 2022 23:56:55 -0500 Subject: [PATCH 80/91] Add Toggle Hero Collider --- Source/BindableFunctions.cs | 20 ++++++++++++++++++++ Source/DebugMod.cs | 3 +++ 2 files changed, 23 insertions(+) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 3f92825..9bd324d 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -775,6 +775,26 @@ public static void KillSelf() GameCameras.instance.hudCanvas.gameObject.SetActive(true); } + [BindableMethod(name = "Toggle Hero Collider", category = "Cheats")] + public static void ToggleHeroCollider() + { + if (!DebugMod.RefHeroCollider.enabled) + { + DebugMod.RefHeroCollider.enabled = true; + DebugMod.RefHeroBox.enabled = true; + Console.AddLine("Enabled hero collider" + (DebugMod.noclip ? " and disabled noclip" : "")); + DebugMod.noclip = false; + } + else + { + DebugMod.RefHeroCollider.enabled = false; + DebugMod.RefHeroBox.enabled = false; + Console.AddLine("Disabled hero collider" + (DebugMod.noclip ? "" : " and enabled noclip")); + DebugMod.noclip = true; + DebugMod.noclipPos = DebugMod.RefKnight.transform.position; + } + } + #endregion #region Charms diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index dd162ba..a992084 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -19,6 +19,9 @@ public class DebugMod : Mod, IMod private static PlayMakerFSM _refKnightSlash; private static CameraController _refCamera; private static PlayMakerFSM _refDreamNail; + private static Collider2D _refHeroCollider; + private static Collider2D _refHeroBox; + internal static GameManager GM => _gm != null ? _gm : (_gm = GameManager.instance); internal static InputHandler IH => _ih != null ? _ih : (_ih = GM.inputHandler); internal static HeroController HC => _hc != null ? _hc : (_hc = GM.hero_ctrl); From 0ebb5cf8fdefe5d4bf3a148911fafe7d9905a223 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Sun, 6 Mar 2022 00:07:29 -0500 Subject: [PATCH 81/91] fix minor issue --- Source/SavePositionManager.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Source/SavePositionManager.cs b/Source/SavePositionManager.cs index e0637ce..73f2e4e 100644 --- a/Source/SavePositionManager.cs +++ b/Source/SavePositionManager.cs @@ -10,16 +10,16 @@ namespace DebugMod { public class SavePositionManager { - public static List FSMs = new List(); - public static List CreatedFSMs = new List(); + private static List FSMs = new List(); + private static List CreatedFSMs = new List(); //public static List; //public static List // too complicated public static PlayMakerFSM KnightFsm = DebugMod.RefKnight.LocateMyFSM("Knight-ProxyFSM") ; - public static Vector3 KnightPos; - public static Vector3 CamPos; - public static Vector2 KnightVel; - public static string PositionScene; - public static bool InitializedPosition = false; + private static Vector3 KnightPos; + private static Vector3 CamPos; + private static Vector2 KnightVel; + private static string PositionScene; + private static bool InitializedPosition = false; // public static List public static void SaveState() { @@ -56,7 +56,7 @@ public static void LoadState() } } - public static List Create() + private static List Create() { List data = new List(); for (int i = 0; i < FSMs.Count; i++) @@ -71,7 +71,7 @@ public static List Create() }; return data; } - public static void RemoveAllCopies() + private static void RemoveAllCopies() { //get all copies and remove them. CreatedFSMs.ForEach(delegate (EnemyData dat) @@ -81,7 +81,7 @@ public static void RemoveAllCopies() }); } // this works but idk how ?? - public static List GetAllEnemies(List Exclude) + private static List GetAllEnemies(List Exclude) { float boxSize = 250f; List ret = new List(); From c1d029b58213494db04239165b307c0c25cbdf4b Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Thu, 24 Mar 2022 19:38:17 -0400 Subject: [PATCH 82/91] big qol update for speedrunners mainly helpful for comsob atttempts on THK and Herrah. this will be expanded on soon. --- Source/BindableFunctions.cs | 17 +++++++--- Source/BossHandler.cs | 11 +++++++ Source/DebugMod.csproj | 4 ++- Source/RoomSpecific.cs | 59 +++++++++++++++++++++++++++++++++++ Source/SavePositionManager.cs | 2 +- Source/SaveState.cs | 13 +++++++- Source/Settings.cs | 1 - 7 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 Source/RoomSpecific.cs diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 9bd324d..413e09f 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -13,6 +13,7 @@ namespace DebugMod { public static class BindableFunctions { + public static bool breakChainsOnLoad = false; private static readonly FieldInfo TimeSlowed = typeof(GameManager).GetField("timeSlowed", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); private static readonly FieldInfo IgnoreUnpause = typeof(UIManager).GetField("ignoreUnpause", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); private static bool corniferYeeteded = false; @@ -504,7 +505,7 @@ public static void ToggleAllPanels() } } [BindableMethod(name = "Toggle showing room IDs", category = "Mod UI")] - public static void toggleShowRoomIDs() + public static void ToggleShowRoomIDs() { DebugMod.settings.ShowRoomIDs = !DebugMod.settings.ShowRoomIDs; } @@ -1188,12 +1189,20 @@ public static void IncreaseQuakeLevel() #endregion #region Bosses + [BindableMethod(name = "Toggle auto break thk chains",category = "Bosses")] + public static void ToggleBreakOnLoads() + { + breakChainsOnLoad = !breakChainsOnLoad; + } + [BindableMethod(name = "Break THK chains",category = "Bosses")] + public static void BreakChains() + { + DebugMod.GM.StartCoroutine(BossHandler.BreakTHKChains()); + } - - [BindableMethod(name = "Force Shade fireball", category = "Bosses")] + [BindableMethod(name = "Force Shade Fireball", category = "Bosses")] public static void ShadeFireball() { - try { GameObject shade = GameObject.Find("Hollow Shade(Clone)"); diff --git a/Source/BossHandler.cs b/Source/BossHandler.cs index cd51f38..ca3180b 100644 --- a/Source/BossHandler.cs +++ b/Source/BossHandler.cs @@ -184,5 +184,16 @@ private static IEnumerator UumuuExtraCoro(Scene activeScene) waitRandom.timeMax.Value = 1.6f; yield break; } + public static IEnumerator BreakTHKChains() + { + if (DebugMod.GetSceneName() == "Room_Final_Boss_Core") + { + for (int j = 0; j < 8; j++) + { + PlayMakerFSM.BroadcastEvent("HIT"); + yield return new WaitForSecondsRealtime(0.14f); + } + } + } } } diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 2abdc85..aa731bc 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -21,7 +21,7 @@ false full true - bin\Debug\ + ..\..\..\..\HK 1221\Mods - Copy\hollow_knight_Data\Managed\Mods\ obj\Windows\AnyCPU\Debug bin\Debug\DebugMod.xml DEBUG;PLATFORM_WINDOWS @@ -80,6 +80,7 @@ + @@ -182,6 +183,7 @@ + <_PostBuildHookTimestamp>@(IntermediateAssembly->'%(FullPath).timestamp') diff --git a/Source/RoomSpecific.cs b/Source/RoomSpecific.cs new file mode 100644 index 0000000..5eab1b3 --- /dev/null +++ b/Source/RoomSpecific.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using HutongGames.PlayMaker; +using UnityEngine; + +namespace DebugMod +{ + public static class RoomSpecific + { + //This class is intended to recreate some scenarios, with more accuracy than that of the savestate class. + //This should be eventually included to compatible with savestates, stored in the same location for easier access. + private static IEnumerator EnterSpiderTownTrap(int index) //Deepnest_Spider_Town + { + string supportedScene = "Deepnest_Spider_Town"; + string goName = "RestBench Spider"; + string websFsmName = "Fade"; + string benchFsmName = "Bench Control Spider"; + if (DebugMod.GM.sceneName == supportedScene) + { + PlayMakerFSM websFSM = FindFsmGlobally(goName, websFsmName); + PlayMakerFSM benchFSM = FindFsmGlobally(goName, benchFsmName); + benchFSM.SetState("Start Rest"); + benchFSM.SendEvent("WAIT"); + benchFSM.SendEvent("FINISHED"); + benchFSM.SendEvent("STRUGGLE"); + websFSM.SendEvent("FIRST STRUGGLE"); + websFSM.SendEvent("FINISHED"); + websFSM.SendEvent("FINISHED"); + websFSM.SendEvent("FINISHED"); + websFSM.SendEvent("LAND"); + websFSM.SendEvent("FINISHED"); + if(index == 2) + { + websFSM.SendEvent("FINISHED"); + } + } + yield break; + } + public static void DoRoomSpecific(string scene,int index)//index only used if multiple functionallities in one room, safe to ignore for now. + { + switch (scene) + { + case "Deepnest_Spider_Town": + DebugMod.GM.StartCoroutine(EnterSpiderTownTrap(index)); + break; + default: + Console.AddLine("No Room Specific Function Found In: " + scene); + break; + } + } + private static PlayMakerFSM FindFsmGlobally(string gameObjectName,string fsmName) + { + return GameObject.Find(gameObjectName).LocateMyFSM(fsmName); + } + } +} diff --git a/Source/SavePositionManager.cs b/Source/SavePositionManager.cs index 73f2e4e..2578e5f 100644 --- a/Source/SavePositionManager.cs +++ b/Source/SavePositionManager.cs @@ -47,7 +47,7 @@ public static void LoadState() HeroController.instance.current_velocity = KnightVel; DebugMod.RefCamera.gameObject.transform.position = CamPos; } - catch (Exception e) + catch (Exception) { Console.AddLine("No positional save in " + DebugMod.GetSceneName()+", or a bug has occured."); } diff --git a/Source/SaveState.cs b/Source/SaveState.cs index 53e084f..73a0ab6 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -26,7 +26,7 @@ public class SaveStateData public Vector3 savePos; public FieldInfo cameraLockArea; public string filePath; - + public int useRoomSpecific; internal SaveStateData() { } internal SaveStateData(SaveStateData _data) @@ -38,6 +38,7 @@ internal SaveStateData(SaveStateData _data) savedSd = _data.savedSd; savePos = _data.savePos; lockArea = _data.lockArea; + useRoomSpecific = _data.useRoomSpecific; } } @@ -61,6 +62,7 @@ public void SaveTempState() data.savePos = HeroController.instance.gameObject.transform.position; data.cameraLockArea = (data.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); data.lockArea = data.cameraLockArea.GetValue(GameManager.instance.cameraCtrl); + data.useRoomSpecific = 0; } public void NewSaveStateToFile(int paramSlot) @@ -163,6 +165,7 @@ public void LoadStateFromFile(int paramSlot) data.savePos = tmpData.savePos; data.saveScene = tmpData.saveScene; data.lockArea = tmpData.lockArea; + data.useRoomSpecific = tmpData.useRoomSpecific; DebugMod.instance.LogFine("Load SaveState ready: " + data.saveStateIdentifier); } catch (Exception ex) @@ -258,6 +261,14 @@ private IEnumerator LoadStateCoro() //UnityEngine.Object.Destroy(GameCameras.instance.gameObject); //yield return null; //DebugMod.GM.SetupSceneRefs(); + if (BindableFunctions.breakChainsOnLoad) + { + DebugMod.GM.StartCoroutine(BossHandler.BreakTHKChains()); + } + if(data.useRoomSpecific != 0) + { + RoomSpecific.DoRoomSpecific(data.saveScene,data.useRoomSpecific); + } yield break; // need to redraw UI somehow } diff --git a/Source/Settings.cs b/Source/Settings.cs index ad31f0d..bc95632 100644 --- a/Source/Settings.cs +++ b/Source/Settings.cs @@ -24,7 +24,6 @@ public bool EnemiesPanelVisible get => GetBool(true); set => SetBool(value); } - public bool HelpPanelVisible { get => GetBool(true); From 2de933455be4fe7c1882be886177d9ade0e4757e Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:14:18 -0400 Subject: [PATCH 83/91] QOL and code cleanup -Reflactionhelper. cs removed, as it is unnecessary -Added savestate room-specific functions -moved the auto break to room-specific functions --- Source/BindableFunctions.cs | 12 -- Source/BossHandler.cs | 11 - Source/DebugMod.csproj | 1 - Source/ReflectionHelper.cs | 399 ------------------------------------ Source/RoomSpecific.cs | 58 ++++-- Source/SaveState.cs | 4 - 6 files changed, 36 insertions(+), 449 deletions(-) delete mode 100644 Source/ReflectionHelper.cs diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 413e09f..7a64ff1 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -13,7 +13,6 @@ namespace DebugMod { public static class BindableFunctions { - public static bool breakChainsOnLoad = false; private static readonly FieldInfo TimeSlowed = typeof(GameManager).GetField("timeSlowed", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); private static readonly FieldInfo IgnoreUnpause = typeof(UIManager).GetField("ignoreUnpause", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); private static bool corniferYeeteded = false; @@ -1189,17 +1188,6 @@ public static void IncreaseQuakeLevel() #endregion #region Bosses - [BindableMethod(name = "Toggle auto break thk chains",category = "Bosses")] - public static void ToggleBreakOnLoads() - { - breakChainsOnLoad = !breakChainsOnLoad; - } - [BindableMethod(name = "Break THK chains",category = "Bosses")] - public static void BreakChains() - { - DebugMod.GM.StartCoroutine(BossHandler.BreakTHKChains()); - } - [BindableMethod(name = "Force Shade Fireball", category = "Bosses")] public static void ShadeFireball() { diff --git a/Source/BossHandler.cs b/Source/BossHandler.cs index ca3180b..cd51f38 100644 --- a/Source/BossHandler.cs +++ b/Source/BossHandler.cs @@ -184,16 +184,5 @@ private static IEnumerator UumuuExtraCoro(Scene activeScene) waitRandom.timeMax.Value = 1.6f; yield break; } - public static IEnumerator BreakTHKChains() - { - if (DebugMod.GetSceneName() == "Room_Final_Boss_Core") - { - for (int j = 0; j < 8; j++) - { - PlayMakerFSM.BroadcastEvent("HIT"); - yield return new WaitForSecondsRealtime(0.14f); - } - } - } } } diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index aa731bc..5f1f338 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -79,7 +79,6 @@ - diff --git a/Source/ReflectionHelper.cs b/Source/ReflectionHelper.cs deleted file mode 100644 index 9184538..0000000 --- a/Source/ReflectionHelper.cs +++ /dev/null @@ -1,399 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Reflection; -using System.Reflection.Emit; -using JetBrains.Annotations; - -namespace Modding -{ - /// - /// A class to aid in reflection while caching it. - /// - public static class ReflectionHelper - { - private static readonly Dictionary> Fields = - new Dictionary>(); - - private static readonly Dictionary Getters = new Dictionary(); - - private static readonly Dictionary Setters = new Dictionary(); - - private static bool _preloaded; - - /// - /// Caches all fields on a type to frontload cost of reflection - /// - /// The type to cache - public static void CacheFields() - { - Type t = typeof(T); - if (!Fields.TryGetValue(t, out Dictionary tFields)) - { - tFields = new Dictionary(); - } - - // Not gonna redesign this class to avoid reflection, this shouldn't be called during gameplay anyway - MethodInfo getGetter = - typeof(ReflectionHelper).GetMethod(nameof(GetGetter), BindingFlags.NonPublic | BindingFlags.Static); - MethodInfo getSetter = - typeof(ReflectionHelper).GetMethod(nameof(GetSetter), BindingFlags.NonPublic | BindingFlags.Static); - - foreach (FieldInfo field in t.GetFields(BindingFlags.NonPublic | BindingFlags.Public | - BindingFlags.Instance | BindingFlags.Static)) - { - tFields[field.Name] = field; - - if (!field.IsLiteral) - { - getGetter?.MakeGenericMethod(t, field.FieldType).Invoke(null, new object[] { field }); - } - - if (!field.IsLiteral && !field.IsInitOnly) - { - getSetter?.MakeGenericMethod(t, field.FieldType).Invoke(null, new object[] { field }); - } - } - } - /// - /// Gets a field on a type - /// - /// Type - /// Field name - /// - /// FieldInfo for field or null if field does not exist. - public static FieldInfo GetField(Type t, string field, bool instance = true) - { - if (!Fields.TryGetValue(t, out Dictionary typeFields)) - { - Fields.Add(t, typeFields = new Dictionary()); - } - - if (typeFields.TryGetValue(field, out FieldInfo fi)) - { - return fi; - } - - fi = t.GetField(field, - BindingFlags.NonPublic | BindingFlags.Public | - (instance ? BindingFlags.Instance : BindingFlags.Static)); - - if (fi != null) - { - typeFields.Add(field, fi); - } - - return fi; - } - - internal static void PreloadCommonTypes() - { - if (_preloaded) - { - return; - } - - Stopwatch watch = new Stopwatch(); - watch.Start(); - - CacheFields(); - CacheFields(); - CacheFields(); - CacheFields(); - - watch.Stop(); - -// Logger.APILogger.Log($"Preloaded reflection in {watch.ElapsedMilliseconds}ms"); - - _preloaded = true; - } - - /// - /// Gets delegate getting field on type - /// - /// FieldInfo for field. - /// Function which gets value of field - private static Delegate GetGetter(FieldInfo fi) - { - if (Getters.TryGetValue(fi, out Delegate d)) - { - return d; - } - - if (fi.IsLiteral) - { - throw new ArgumentException("Field cannot be const", nameof(fi)); - } - - d = fi.IsStatic - ? CreateGetStaticFieldDelegate(fi) - : CreateGetFieldDelegate(fi); - - Getters.Add(fi, d); - - return d; - } - - /// - /// Gets delegate setting field on type - /// - /// FieldInfo for field. - /// Function which sets field passed as FieldInfo - private static Delegate GetSetter(FieldInfo fi) - { - if (Setters.TryGetValue(fi, out Delegate d)) - { - return d; - } - - if (fi.IsLiteral || fi.IsInitOnly) - { - throw new ArgumentException("Field cannot be readonly or const", nameof(fi)); - } - - d = fi.IsStatic - ? CreateSetStaticFieldDelegate(fi) - : CreateSetFieldDelegate(fi); - - Setters.Add(fi, d); - - return d; - } - - /// - /// Create delegate returning value of static field. - /// - /// FieldInfo of field - /// Field type - /// Type which field resides upon - /// Function returning static field - private static Delegate CreateGetStaticFieldDelegate(FieldInfo fi) - { - DynamicMethod dm = new DynamicMethod - ( - "FieldAccess" + fi.DeclaringType?.Name + fi.Name, - typeof(TField), - new Type[0], - typeof(TType) - ); - - ILGenerator gen = dm.GetILGenerator(); - - gen.Emit(OpCodes.Ldsfld, fi); - gen.Emit(OpCodes.Ret); - - return dm.CreateDelegate(typeof(Func)); - } - - /// - /// Create delegate returning value of field of object - /// - /// - /// - /// - /// Function which returns value of field of object parameter - private static Delegate CreateGetFieldDelegate(FieldInfo fi) - { - DynamicMethod dm = new DynamicMethod - ( - "FieldAccess" + fi.DeclaringType?.Name + fi.Name, - typeof(TField), - new[] { typeof(TType) }, - typeof(TType) - ); - - ILGenerator gen = dm.GetILGenerator(); - - gen.Emit(OpCodes.Ldarg_0); - gen.Emit(OpCodes.Ldfld, fi); - gen.Emit(OpCodes.Ret); - - return dm.CreateDelegate(typeof(Func)); - } - - private static Delegate CreateSetFieldDelegate(FieldInfo fi) - { - DynamicMethod dm = new DynamicMethod - ( - "FieldSet" + fi.DeclaringType?.Name + fi.Name, - typeof(void), - new[] { typeof(TType), typeof(TField) }, - typeof(TType) - ); - - ILGenerator gen = dm.GetILGenerator(); - - gen.Emit(OpCodes.Ldarg_0); - gen.Emit(OpCodes.Ldarg_1); - gen.Emit(OpCodes.Stfld, fi); - gen.Emit(OpCodes.Ret); - - return dm.CreateDelegate(typeof(Action)); - } - - private static Delegate CreateSetStaticFieldDelegate(FieldInfo fi) - { - DynamicMethod dm = new DynamicMethod - ( - "FieldSet" + fi.DeclaringType?.Name + fi.Name, - typeof(void), - new[] { typeof(TField) }, - typeof(TType) - ); - - ILGenerator gen = dm.GetILGenerator(); - - gen.Emit(OpCodes.Ldarg_0); - gen.Emit(OpCodes.Stsfld, fi); - gen.Emit(OpCodes.Ret); - - return dm.CreateDelegate(typeof(Action)); - } - - /// - /// Get a field on an object using a string. Cast to TCast before returning and if field doesn't exist return default. - /// - /// Object/Object of type which the field is on - /// Name of the field - /// Default return - /// Type of field - /// Type of object being passed in - /// Type of return. - /// The value of a field on an object/type - [PublicAPI] - public static TCast GetAttr(TObject obj, string name, TCast @default = default(TCast)) - { - FieldInfo fi = GetField(typeof(TObject), name); - - return fi == null - ? @default - : (TCast)(object)((Func)GetGetter(fi))(obj); - } - - /// - /// Get a field on an object using a string. - /// - /// Object/Object of type which the field is on - /// Name of the field - /// Type of field - /// Type of object being passed in - /// The value of a field on an object/type - [PublicAPI] - public static TField GetAttr(TObject obj, string name) - { - FieldInfo fi = GetField(typeof(TObject), name) ?? throw new MissingFieldException(); - - return ((Func)GetGetter(fi))(obj); - } - - /// - /// Get a static field on an type using a string. - /// - /// Name of the field - /// Type which static field resides upon - /// Type of field - /// The value of a field on an object/type - [PublicAPI] - public static TField GetAttr(string name) - { - FieldInfo fi = GetField(typeof(TType), name, false); - - return fi == null ? default(TField) : ((Func)GetGetter(fi))(); - } - - /// - /// Set a field on an object using a string. - /// - /// Object/Object of type which the field is on - /// Name of the field - /// Value to set the field to - /// Type of field - /// Type of object being passed in - [PublicAPI] - public static void SetAttrSafe(TObject obj, string name, TField value) - { - FieldInfo fi = GetField(typeof(TObject), name); - - if (fi == null) - { - return; - } - - ((Action)GetSetter(fi))(obj, value); - } - - /// - /// Set a field on an object using a string. - /// - /// Object/Object of type which the field is on - /// Name of the field - /// Value to set the field to - /// Type of field - /// Type of object being passed in - [PublicAPI] - public static void SetAttr(TObject obj, string name, TField value) - { - FieldInfo fi = GetField(typeof(TObject), name) ?? - throw new MissingFieldException($"Field {name} does not exist!"); - - ((Action)GetSetter(fi))(obj, value); - } - - /// - /// Set a static field on an type using a string. - /// - /// Name of the field - /// Value to set the field to - /// Type which static field resides upon - /// Type of field - [PublicAPI] - public static void SetAttr(string name, TField value) - { - ((Action)GetGetter(GetField(typeof(TType), name, false)))(value); - } - - #region Obsolete - - /// - /// Set a field on an object using a string. - /// - /// Object/Object of type which the field is on - /// Name of the field - /// Value to set the field to to - /// Whether or not to get an instance field or a static field - /// Type of the object which the field holds. - [PublicAPI] - [Obsolete("Use SetAttr and SetAttr.")] - public static void SetAttr(object obj, string name, T val, bool instance = true) - { - if (obj == null || string.IsNullOrEmpty(name)) - { - return; - } - - GetField(obj.GetType(), name, instance)?.SetValue(obj, val); - } - - /// - /// Get a field on an object/type using a string. - /// - /// Object/Object of type which the field is on - /// Name of the field - /// Whether or not to get an instance field or a static field - /// Type of the object which the field holds. - /// The value of a field on an object/type - [PublicAPI] - [Obsolete("Use GetAttr.")] - public static T GetAttr(object obj, string name, bool instance = true) - { - if (obj == null || string.IsNullOrEmpty(name)) - { - return default(T); - } - - return (T)GetField(obj.GetType(), name, instance)?.GetValue(obj); - } - - #endregion - } -} \ No newline at end of file diff --git a/Source/RoomSpecific.cs b/Source/RoomSpecific.cs index 5eab1b3..7400072 100644 --- a/Source/RoomSpecific.cs +++ b/Source/RoomSpecific.cs @@ -12,46 +12,60 @@ public static class RoomSpecific { //This class is intended to recreate some scenarios, with more accuracy than that of the savestate class. //This should be eventually included to compatible with savestates, stored in the same location for easier access. - private static IEnumerator EnterSpiderTownTrap(int index) //Deepnest_Spider_Town + private static void EnterSpiderTownTrap(int index) //Deepnest_Spider_Town { - string supportedScene = "Deepnest_Spider_Town"; string goName = "RestBench Spider"; string websFsmName = "Fade"; string benchFsmName = "Bench Control Spider"; - if (DebugMod.GM.sceneName == supportedScene) + PlayMakerFSM websFSM = FindFsmGlobally(goName, websFsmName); + PlayMakerFSM benchFSM = FindFsmGlobally(goName, benchFsmName); + benchFSM.SetState("Start Rest"); + benchFSM.SendEvent("WAIT"); + benchFSM.SendEvent("FINISHED"); + benchFSM.SendEvent("STRUGGLE"); + websFSM.SendEvent("FIRST STRUGGLE"); + websFSM.SendEvent("FINISHED"); + websFSM.SendEvent("FINISHED"); + websFSM.SendEvent("FINISHED"); + websFSM.SendEvent("LAND"); + websFSM.SendEvent("FINISHED"); + if (index == 2) { - PlayMakerFSM websFSM = FindFsmGlobally(goName, websFsmName); - PlayMakerFSM benchFSM = FindFsmGlobally(goName, benchFsmName); - benchFSM.SetState("Start Rest"); - benchFSM.SendEvent("WAIT"); - benchFSM.SendEvent("FINISHED"); - benchFSM.SendEvent("STRUGGLE"); - websFSM.SendEvent("FIRST STRUGGLE"); websFSM.SendEvent("FINISHED"); - websFSM.SendEvent("FINISHED"); - websFSM.SendEvent("FINISHED"); - websFSM.SendEvent("LAND"); - websFSM.SendEvent("FINISHED"); - if(index == 2) - { - websFSM.SendEvent("FINISHED"); - } } - yield break; } - public static void DoRoomSpecific(string scene,int index)//index only used if multiple functionallities in one room, safe to ignore for now. + public static void BreakTHKChains(int index) + { + string fsmName = "Control"; + string goName1 = "hollow_knight_chain_base"; + string goName2 = "hollow_knight_chain_base 2"; + string goName3 = "hollow_knight_chain_base 3"; + string goName4 = "hollow_knight_chain_base 4"; + PlayMakerFSM fsm1 = FindFsmGlobally(goName1, fsmName); + PlayMakerFSM fsm2 = FindFsmGlobally(goName2, fsmName); + PlayMakerFSM fsm3 = FindFsmGlobally(goName3, fsmName); + PlayMakerFSM fsm4 = FindFsmGlobally(goName4, fsmName); + fsm1.SetState("Break"); + fsm2.SetState("Break"); + fsm3.SetState("Break"); + fsm4.SetState("Break"); + } + public static void DoRoomSpecific(string scene, int index)//index only used if multiple functionallities in one room, safe to ignore for now. { switch (scene) { case "Deepnest_Spider_Town": - DebugMod.GM.StartCoroutine(EnterSpiderTownTrap(index)); + EnterSpiderTownTrap(index); + break; + case "Final_Boss_Core": + BreakTHKChains(index); break; default: Console.AddLine("No Room Specific Function Found In: " + scene); break; } } - private static PlayMakerFSM FindFsmGlobally(string gameObjectName,string fsmName) + private static PlayMakerFSM FindFsmGlobally(string gameObjectName, string fsmName) { return GameObject.Find(gameObjectName).LocateMyFSM(fsmName); } diff --git a/Source/SaveState.cs b/Source/SaveState.cs index 73a0ab6..07e953c 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -261,10 +261,6 @@ private IEnumerator LoadStateCoro() //UnityEngine.Object.Destroy(GameCameras.instance.gameObject); //yield return null; //DebugMod.GM.SetupSceneRefs(); - if (BindableFunctions.breakChainsOnLoad) - { - DebugMod.GM.StartCoroutine(BossHandler.BreakTHKChains()); - } if(data.useRoomSpecific != 0) { RoomSpecific.DoRoomSpecific(data.saveScene,data.useRoomSpecific); From 29b060f7be87f935dd4b7a9078b1a5b0a8a06ee4 Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Thu, 24 Mar 2022 20:16:34 -0400 Subject: [PATCH 84/91] fixing very very small oopsie --- Source/DebugMod.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index 5f1f338..aedde2d 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -21,7 +21,7 @@ false full true - ..\..\..\..\HK 1221\Mods - Copy\hollow_knight_Data\Managed\Mods\ + bin\Debug\ obj\Windows\AnyCPU\Debug bin\Debug\DebugMod.xml DEBUG;PLATFORM_WINDOWS From 9a587c3e92ac2952a2b6101ae6acf38dff64bb9f Mon Sep 17 00:00:00 2001 From: cerpintext Date: Sun, 27 Mar 2022 22:50:00 +0200 Subject: [PATCH 85/91] honestly just notes lol --- Source/DebugMod.cs | 2 ++ Source/SaveState.cs | 6 +++++- Source/SaveStateManager.cs | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index fb4c2c9..a305427 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -15,6 +15,7 @@ public class DebugMod : Mod, IMod private static GameManager _gm; private static InputHandler _ih; private static HeroController _hc; + private static NailSlash _ns; private static GameObject _refKnight; private static PlayMakerFSM _refKnightSlash; private static CameraController _refCamera; @@ -24,6 +25,7 @@ public class DebugMod : Mod, IMod internal static InputHandler IH => _ih != null ? _ih : (_ih = GM.inputHandler); internal static HeroController HC => _hc != null ? _hc : (_hc = GM.hero_ctrl); internal static GameObject RefKnight => _refKnight != null ? _refKnight : (_refKnight = HC.gameObject); + //internal static NailSlash NailSlash => _ns != null ? _ns : (_ns = typeof(HC.normalSlash.GetType()); internal static PlayMakerFSM RefKnightSlash => _refKnightSlash != null ? _refKnightSlash : (_refKnightSlash = RefKnight.transform.Find("Attacks/Slash").GetComponent()); internal static CameraController RefCamera => _refCamera != null ? _refCamera : (_refCamera = GM.cameraCtrl); internal static PlayMakerFSM RefDreamNail => _refDreamNail != null ? _refDreamNail : (_refDreamNail = FSMUtility.LocateFSM(RefKnight, "Dream Nail")); diff --git a/Source/SaveState.cs b/Source/SaveState.cs index a796f40..3d5a53e 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -48,7 +48,11 @@ internal SaveState() { data = new SaveStateData(); } - + /* TODO: + handle fury/full-health fury + apply/deapply twister effects when charms changed + adjust nail dmg from one save to another + */ #region saving public void SaveTempState() diff --git a/Source/SaveStateManager.cs b/Source/SaveStateManager.cs index 1a920d5..d438eff 100644 --- a/Source/SaveStateManager.cs +++ b/Source/SaveStateManager.cs @@ -34,6 +34,7 @@ internal class SaveStateManager public static int currentStateSlot = -1; public static string path = Application.persistentDataPath + "/Savestates-1221/0/"; public static string currentStateOperation = null; + //public static bool hasFury = typeof(Modding.ReflectionHelper).GetField(, "fury"); private static string[] stateStrings = { From bd517474e2b1c575445896c39ca69245dcf5a06d Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Mon, 18 Apr 2022 15:55:38 -0400 Subject: [PATCH 86/91] Fix savestating Soul with cracked soul meter --- Source/SaveState.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Source/SaveState.cs b/Source/SaveState.cs index 07e953c..c0c4ba5 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -241,8 +241,17 @@ private IEnumerator LoadStateCoro() } else { - HeroController.instance.AddMPCharge(1); - HeroController.instance.TakeMP(1); + if(PlayerData.instance.MPCharge != 0) + { + HeroController.instance.TakeMP(1); + HeroController.instance.AddMPCharge(1); + } + else + { + HeroController.instance.AddMPCharge(1); + HeroController.instance.TakeMP(1); + } + } HeroController.instance.proxyFSM.SendEvent("HeroCtrl-HeroLanded"); From 1cfd1a0a4c73b28e08a4483bea7a81a29715f69b Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Mon, 18 Apr 2022 15:58:08 -0400 Subject: [PATCH 87/91] Add Reloading Radiance Fight from arena, Fix small bug, version bump --- Source/BindableFunctions.cs | 29 ++++++++++++++++++++++++++++- Source/DebugMod.cs | 2 +- Source/RoomSpecific.cs | 8 +++++--- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/Source/BindableFunctions.cs b/Source/BindableFunctions.cs index 7a64ff1..fba5a04 100644 --- a/Source/BindableFunctions.cs +++ b/Source/BindableFunctions.cs @@ -8,6 +8,7 @@ using HutongGames.PlayMaker; using UnityEngine.SceneManagement; using HutongGames.PlayMaker.Actions; +using System.Collections; namespace DebugMod { @@ -1188,6 +1189,32 @@ public static void IncreaseQuakeLevel() #endregion #region Bosses + [BindableMethod(name = "Reload Radiance Fight", category = "Bosses")] + public static void LoadRadiance() + { + GameManager.instance.StartCoroutine(LoadRadianceRoom()); + } + private static IEnumerator LoadRadianceRoom() + { + //makes sure the initial platform and challage prompt appears + HeroController.instance.gameObject.LocateMyFSM("ProxyFSM").FsmVariables.FindFsmBool("Faced Radiance").Value = false; + + HeroController.instance.RelinquishControl(); + HeroController.instance.StopAnimationControl(); + PlayMakerFSM.BroadcastEvent("START DREAM ENTRY"); + PlayMakerFSM.BroadcastEvent("DREAM ENTER"); + if (DebugMod.GM.IsGamePaused()) + { + PlayerData.instance.disablePause = false; + UIManager.instance.TogglePauseGame(); + } + HeroController.instance.enterWithoutInput = true; // stop early control on scene load + GameManager.instance.ChangeToScene("Dream_Final_Boss", "door1", 0f); + yield return new WaitUntil(() => HeroController.instance.acceptingInput); + yield return null; + //cuz people mostly have full soul from thk fight + HeroController.instance.AddMPCharge(198); + } [BindableMethod(name = "Force Shade Fireball", category = "Bosses")] public static void ShadeFireball() { @@ -1622,7 +1649,7 @@ public static void FaceRight() HeroController.instance.FaceRight(); Console.AddLine("Made player face right"); } - + #endregion } } diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index a992084..36b69e0 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -174,7 +174,7 @@ public override void Initialize() public override string GetVersion() { - string version = "1.5.1"; + string version = "1.5.2"; #if DEBUG version = string.Concat(version, "-dev"); #endif diff --git a/Source/RoomSpecific.cs b/Source/RoomSpecific.cs index 7400072..0391166 100644 --- a/Source/RoomSpecific.cs +++ b/Source/RoomSpecific.cs @@ -12,6 +12,7 @@ public static class RoomSpecific { //This class is intended to recreate some scenarios, with more accuracy than that of the savestate class. //This should be eventually included to compatible with savestates, stored in the same location for easier access. + #region Functions private static void EnterSpiderTownTrap(int index) //Deepnest_Spider_Town { string goName = "RestBench Spider"; @@ -34,7 +35,7 @@ private static void EnterSpiderTownTrap(int index) //Deepnest_Spider_Town websFSM.SendEvent("FINISHED"); } } - public static void BreakTHKChains(int index) + private static void BreakTHKChains(int index) { string fsmName = "Control"; string goName1 = "hollow_knight_chain_base"; @@ -49,7 +50,8 @@ public static void BreakTHKChains(int index) fsm2.SetState("Break"); fsm3.SetState("Break"); fsm4.SetState("Break"); - } + } //Room_Final_Boss + #endregion public static void DoRoomSpecific(string scene, int index)//index only used if multiple functionallities in one room, safe to ignore for now. { switch (scene) @@ -57,7 +59,7 @@ public static void BreakTHKChains(int index) case "Deepnest_Spider_Town": EnterSpiderTownTrap(index); break; - case "Final_Boss_Core": + case "Room_Final_Boss_Core": BreakTHKChains(index); break; default: From a8de66aa79b46b6261039befbf5b29b45d28dc0a Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Mon, 18 Apr 2022 16:01:04 -0400 Subject: [PATCH 88/91] fix version --- Source/DebugMod.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index 36b69e0..c1ce367 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -174,7 +174,7 @@ public override void Initialize() public override string GetVersion() { - string version = "1.5.2"; + string version = "1.5.3"; #if DEBUG version = string.Concat(version, "-dev"); #endif From 484a8dabee3c4f7a9db2716359d37b029854c93f Mon Sep 17 00:00:00 2001 From: SkeppysFlipFlops <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Sat, 30 Apr 2022 16:53:45 -0400 Subject: [PATCH 89/91] Save facing direction in savestates --- Source/DebugMod.csproj | 1 + Source/SaveState.cs | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Source/DebugMod.csproj b/Source/DebugMod.csproj index aedde2d..594d55c 100644 --- a/Source/DebugMod.csproj +++ b/Source/DebugMod.csproj @@ -44,6 +44,7 @@ default 4 false + CS1591 true diff --git a/Source/SaveState.cs b/Source/SaveState.cs index c0c4ba5..cbbb3b0 100644 --- a/Source/SaveState.cs +++ b/Source/SaveState.cs @@ -20,25 +20,27 @@ public class SaveStateData { public string saveStateIdentifier; public string saveScene; + public int useRoomSpecific = 0; + public int facingRight = -1; // -1 for unknown, so that older savestate files behave the same. public PlayerData savedPd; public object lockArea; public SceneData savedSd; public Vector3 savePos; public FieldInfo cameraLockArea; public string filePath; - public int useRoomSpecific; internal SaveStateData() { } internal SaveStateData(SaveStateData _data) { saveStateIdentifier = _data.saveStateIdentifier; saveScene = _data.saveScene; + useRoomSpecific = _data.useRoomSpecific; + facingRight = _data.facingRight; cameraLockArea = _data.cameraLockArea; savedPd = _data.savedPd; savedSd = _data.savedSd; savePos = _data.savePos; lockArea = _data.lockArea; - useRoomSpecific = _data.useRoomSpecific; } } @@ -63,6 +65,7 @@ public void SaveTempState() data.cameraLockArea = (data.cameraLockArea ?? typeof(CameraController).GetField("currentLockArea", BindingFlags.Instance | BindingFlags.NonPublic)); data.lockArea = data.cameraLockArea.GetValue(GameManager.instance.cameraCtrl); data.useRoomSpecific = 0; + data.facingRight = (HeroController.instance.cState.facingRight) ? 1:0; } public void NewSaveStateToFile(int paramSlot) @@ -166,6 +169,7 @@ public void LoadStateFromFile(int paramSlot) data.saveScene = tmpData.saveScene; data.lockArea = tmpData.lockArea; data.useRoomSpecific = tmpData.useRoomSpecific; + data.facingRight = tmpData.facingRight; DebugMod.instance.LogFine("Load SaveState ready: " + data.saveStateIdentifier); } catch (Exception ex) @@ -266,6 +270,15 @@ private IEnumerator LoadStateCoro() GameManager.instance.inputHandler.RefreshPlayerData(); + if (data.facingRight == 1) + { + HeroController.instance.FaceRight(); + } + else if (data.facingRight == 0) + { + HeroController.instance.FaceLeft(); + } + if (DebugMod.settings.EnemiesPanelVisible) EnemiesPanel.RefreshEnemyList(); //UnityEngine.Object.Destroy(GameCameras.instance.gameObject); //yield return null; From 2023fe416654ee75395742f80ef50e0c5ba26b91 Mon Sep 17 00:00:00 2001 From: MagneticPizza <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Sat, 30 Apr 2022 16:55:07 -0400 Subject: [PATCH 90/91] version bump --- Source/DebugMod.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/DebugMod.cs b/Source/DebugMod.cs index c1ce367..e41e39a 100644 --- a/Source/DebugMod.cs +++ b/Source/DebugMod.cs @@ -174,7 +174,7 @@ public override void Initialize() public override string GetVersion() { - string version = "1.5.3"; + string version = "1.5.5"; #if DEBUG version = string.Concat(version, "-dev"); #endif From 56955791c6bd0a3881af90f2c462d1e6ac6463f1 Mon Sep 17 00:00:00 2001 From: MagneticPizza <57578841+SkeppysFlipFlops@users.noreply.github.com> Date: Sat, 30 Apr 2022 17:48:53 -0400 Subject: [PATCH 91/91] Update README.md Added explanation of room-specific savestates --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 46f6878..8aafc2e 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,18 @@ Specifies slot number, then makes a new savestate and saves to a json-file with ## Load new state from file Specifies slot number, then loads savestate from that file directly. +## How to use room specific Savestates +1. Make sure you are in one of the following rooms, as these are the only ones supported + Room_Final_Boss_Core + Deepnest_Spider_Town + (you can check what room you are in by pressing f2 and reading 'scene name') +2. Create a savestate in the said room. +3. Open your hollow knight saveStates folder (%APPDATA%\..\LocalLow\Team Cherry\Hollow Knight\Savestates-1221\) +4. Subtract 1 from the page of savestates you saved in, and open that folder. (example, saved in page 4, open folder named 3) +5. Open the savestate.json, whatever number you pressed being the number it will be (example, pressed 4, open file named savestate4 with a text editor such as notepad) +6. Change the value labeled useRoomSpecific to 1 to enable room specific savestates.(if you can't find it, search for 'useRoomSpecific' with Ctrl+f) +7. Load the savestate. + ---------------------------------------------------------------------------------------- Known Issues ---------------------------------------------------------------------------------------- @@ -108,4 +120,4 @@ KeinZantezuken MyEyes/Firzen Cerpintext Mulhima -DemoJameson \ No newline at end of file +DemoJameson