using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GlobalEnums; using HarmonyLib; using HutongGames.PlayMaker; using InControl; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using SilksongManager.Currency; using SilksongManager.Damage; using SilksongManager.DebugMenu; using SilksongManager.DebugMenu.Windows; using SilksongManager.Enemies; using SilksongManager.Hitbox; using SilksongManager.Inventory; using SilksongManager.Menu; using SilksongManager.Menu.Keybinds; using SilksongManager.Patches; using SilksongManager.Player; using SilksongManager.SaveState; using SilksongManager.SpeedControl; using SilksongManager.Tools; using SilksongManager.UI; using SilksongManager.World; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Catalyst")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Debug and utility mod for Hollow Knight: Silksong")] [assembly: AssemblyFileVersion("1.0.0.2")] [assembly: AssemblyInformationalVersion("1.0.0.2+022e1c75a2848601392bf2bdbce105a3328b5d21")] [assembly: AssemblyProduct("SilksongManager")] [assembly: AssemblyTitle("SilksongManager")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.2")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SilksongManager { [BepInPlugin("ru.catalyst.silksongmanager", "Silksong Manager", "1.0.0.2")] public class Plugin : BaseUnityPlugin { private DebugMenuController _debugMenu; private bool _menuHookInitialized; private bool _enemiesFrozen; public static ManualLogSource Log { get; private set; } public static Plugin Instance { get; private set; } public static PluginConfig ModConfig { get; private set; } public static PlayerData PD => PlayerData.instance; public static HeroController Hero => HeroController.instance; public static GameManager GM => GameManager.instance; public static UIManager UI => UIManager.instance; private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"Silksong Manager v1.0.0.2 loading..."); InitializeConfiguration(); InitializeSystems(); InitializePatches(); SceneManager.sceneLoaded += OnSceneLoaded; Log.LogInfo((object)"Silksong Manager initialized successfully!"); } private void Update() { if (ModKeybindManager.WasActionPressed(ModAction.ToggleDebugMenu)) { _debugMenu?.ToggleMenu(); } HandleHotkeys(); } private void LateUpdate() { CheatSystem.Update(); } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; Log.LogInfo((object)"Silksong Manager unloaded."); } private void InitializeConfiguration() { ModConfig = new PluginConfig(((BaseUnityPlugin)this).Config); ModKeybindManager.Initialize(((BaseUnityPlugin)this).Config); } private void InitializeSystems() { CheatSystem.Initialize(((BaseUnityPlugin)this).Config); DamageSystem.Initialize(((BaseUnityPlugin)this).Config); _debugMenu = ((Component)this).gameObject.AddComponent(); ((Component)this).gameObject.AddComponent(); HitboxManager.Initialize(((Component)this).gameObject); SaveStateManager.Initialize(); SpeedControlManager.Initialize(); } private void InitializePatches() { DamagePatches.Apply(); } private void HandleHotkeys() { if (ModConfig.EnableHotkeys) { HandleMovementHotkeys(); HandleCombatHotkeys(); HandleResourceHotkeys(); HandleGameSpeedHotkeys(); HandleDebugHotkeys(); HandleSaveStateHotkeys(); HandleSceneHotkeys(); } } private void HandleMovementHotkeys() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (ModKeybindManager.WasActionPressed(ModAction.ToggleNoclip)) { CheatSystem.ToggleNoclip(); bool noclipEnabled = CheatSystem.NoclipEnabled; NotificationManager.Show("Noclip", noclipEnabled ? "ON" : "OFF"); } if (ModKeybindManager.WasActionPressed(ModAction.SavePosition)) { WorldActions.SavePosition(); HeroController hero = Hero; Vector3 val = ((hero != null) ? ((Component)hero).transform.position : Vector3.zero); NotificationManager.Show("Position Saved", $"X: {val.x:F1}, Y: {val.y:F1}"); } if (ModKeybindManager.WasActionPressed(ModAction.LoadPosition)) { WorldActions.LoadPosition(); NotificationManager.Show("Position Loaded"); } } private void HandleCombatHotkeys() { if (ModKeybindManager.WasActionPressed(ModAction.ToggleInvincibility)) { PlayerActions.ToggleInvincibility(); bool flag = PD?.isInvincible ?? false; NotificationManager.Show("Invincibility", flag ? "ON" : "OFF"); } if (ModKeybindManager.WasActionPressed(ModAction.ToggleInfiniteJumps)) { CheatSystem.ToggleInfiniteJumps(); bool infiniteJumps = CheatSystem.InfiniteJumps; NotificationManager.Show("Infinite Jumps", infiniteJumps ? "ON" : "OFF"); } if (ModKeybindManager.WasActionPressed(ModAction.ToggleInfiniteHealth)) { CheatSystem.ToggleInfiniteHealth(); bool infiniteHealth = CheatSystem.InfiniteHealth; NotificationManager.Show("Infinite Health", infiniteHealth ? "ON" : "OFF"); } if (ModKeybindManager.WasActionPressed(ModAction.ToggleInfiniteSilk)) { CheatSystem.ToggleInfiniteSilk(); bool infiniteSilk = CheatSystem.InfiniteSilk; NotificationManager.Show("Infinite Silk", infiniteSilk ? "ON" : "OFF"); } if (ModKeybindManager.WasActionPressed(ModAction.KillAllEnemies)) { int enemyCount = EnemyActions.GetEnemyCount(); EnemyActions.KillAllEnemies(); NotificationManager.Show("Kill All Enemies", $"{enemyCount} enemies killed"); } if (ModKeybindManager.WasActionPressed(ModAction.FreezeEnemies)) { _enemiesFrozen = !_enemiesFrozen; if (_enemiesFrozen) { EnemyActions.FreezeAllEnemies(); } else { EnemyActions.UnfreezeAllEnemies(); } NotificationManager.Show("Freeze Enemies", _enemiesFrozen ? "ON" : "OFF"); } } private void HandleResourceHotkeys() { if (ModKeybindManager.WasActionPressed(ModAction.AddGeo)) { CurrencyActions.AddGeo(1000); NotificationManager.Show("+1000 Geo", $"Total: {PD?.geo ?? 0}"); } if (ModKeybindManager.WasActionPressed(ModAction.AddShellShards)) { CurrencyActions.AddShards(5); NotificationManager.Show("+5 Shell Shards"); } if (ModKeybindManager.WasActionPressed(ModAction.MaxSilk)) { PlayerActions.QuickSilk(); NotificationManager.Show("Max Silk"); } if (ModKeybindManager.WasActionPressed(ModAction.HealToFull)) { PlayerActions.QuickHeal(); NotificationManager.Show("Full Health"); } } private void HandleGameSpeedHotkeys() { if (ModKeybindManager.WasActionPressed(ModAction.IncreaseGameSpeed)) { SpeedControlManager.SetGlobalSpeed(SpeedControlConfig.GlobalSpeed + 0.25f); NotificationManager.Show("Game Speed", $"{SpeedControlConfig.GlobalSpeed:F2}x"); } if (ModKeybindManager.WasActionPressed(ModAction.DecreaseGameSpeed)) { SpeedControlManager.SetGlobalSpeed(Mathf.Max(0.1f, SpeedControlConfig.GlobalSpeed - 0.25f)); NotificationManager.Show("Game Speed", $"{SpeedControlConfig.GlobalSpeed:F2}x"); } if (ModKeybindManager.WasActionPressed(ModAction.ResetGameSpeed)) { SpeedControlManager.ResetAll(); NotificationManager.Show("Game Speed", "1.0x (Reset)"); } } private void HandleDebugHotkeys() { if (ModKeybindManager.WasActionPressed(ModAction.ToggleHitboxes)) { HitboxManager.ToggleHitboxes(); bool showHitboxes = HitboxConfig.ShowHitboxes; NotificationManager.Show("Hitboxes", showHitboxes ? "ON" : "OFF"); } } private void HandleSaveStateHotkeys() { if (ModKeybindManager.WasActionPressed(ModAction.SaveState)) { string text = SaveStateManager.QuickSave(); NotificationManager.Show("State Saved", "\"" + text + "\""); } if (ModKeybindManager.WasActionPressed(ModAction.LoadLastState)) { string text2 = SaveStateManager.LoadLastState(); if (text2 != null) { NotificationManager.Show("Loading State", "\"" + text2 + "\""); } else { NotificationManager.Show("No States", "Save a state first"); } } } private void HandleSceneHotkeys() { if (ModKeybindManager.WasActionPressed(ModAction.ReloadScene)) { string text = WorldActions.ReloadCurrentScene(); if (text != null) { NotificationManager.Show("Reload Scene", text); } } if (ModKeybindManager.WasActionPressed(ModAction.Respawn)) { WorldActions.Respawn(); NotificationManager.Show("Respawn"); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { Log.LogInfo((object)("Scene loaded: " + ((Scene)(ref scene)).name)); if (((Scene)(ref scene)).name == "Menu_Title") { ((MonoBehaviour)this).StartCoroutine(WaitForMainMenuAndInitialize()); return; } _menuHookInitialized = false; MainMenuHook.Reset(); } private IEnumerator WaitForMainMenuAndInitialize() { float timeout = 10f; float elapsed = 0f; Log.LogInfo((object)"Waiting for MainMenuOptions to appear..."); for (; elapsed < timeout; elapsed += 0.1f) { if ((Object)(object)Object.FindAnyObjectByType() != (Object)null) { Log.LogInfo((object)$"MainMenuOptions found after {elapsed:F2}s"); if (!_menuHookInitialized) { MainMenuHook.Initialize(); _menuHookInitialized = true; } yield break; } yield return (object)new WaitForSeconds(0.1f); } Log.LogWarning((object)$"MainMenuOptions not found after {timeout}s timeout!"); } } public class PluginConfig { private readonly ConfigFile _config; private ConfigEntry _enableHotkeys; private ConfigEntry _showDebugInfo; private ConfigEntry _enableLogging; public ConfigFile ConfigFile => _config; public bool EnableHotkeys { get { return _enableHotkeys?.Value ?? true; } set { if (_enableHotkeys != null) { _enableHotkeys.Value = value; } } } public bool ShowDebugInfo { get { return _showDebugInfo?.Value ?? false; } set { if (_showDebugInfo != null) { _showDebugInfo.Value = value; } } } public bool EnableLogging { get { return _enableLogging?.Value ?? true; } set { if (_enableLogging != null) { _enableLogging.Value = value; } } } public float MenuWidth { get; private set; } public float MenuHeight { get; private set; } public int FontSize { get; private set; } public PluginConfig(ConfigFile config) { _config = config; LoadConfig(); } private void LoadConfig() { LoadGeneralSettings(); LoadDebugMenuSettings(); } private void LoadGeneralSettings() { _enableHotkeys = _config.Bind("General", "EnableHotkeys", true, "Enable keyboard hotkeys for quick actions"); _showDebugInfo = _config.Bind("General", "ShowDebugInfo", false, "Show debug information on screen"); _enableLogging = _config.Bind("General", "EnableLogging", true, "Enable logging to BepInEx console"); } private void LoadDebugMenuSettings() { MenuWidth = _config.Bind("DebugMenu", "MenuWidth", 400f, "Width of the debug menu window").Value; MenuHeight = _config.Bind("DebugMenu", "MenuHeight", 600f, "Height of the debug menu window").Value; FontSize = _config.Bind("DebugMenu", "FontSize", 14, "Font size for debug menu text").Value; } } public static class PluginInfo { public const string GUID = "ru.catalyst.silksongmanager"; public const string NAME = "Silksong Manager"; public const string VERSION = "1.0.0.2"; public const string AUTHOR = "Catalyst"; public const string EMAIL = "catalyst@kyokai.ru"; public const string TELEGRAM = "@Catalyst_Kyokai"; } } namespace SilksongManager.World { public static class WorldActions { private static Vector3 _savedPosition = Vector3.zero; private static string _savedScene = ""; private static List _visitedScenes = new List(); public static void SavePosition() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) HeroController hero = Plugin.Hero; if (!((Object)(object)hero == (Object)null)) { _savedPosition = ((Component)hero).transform.position; _savedScene = Plugin.GM?.sceneName ?? ""; Plugin.Log.LogInfo((object)$"Saved position: {_savedPosition} in scene {_savedScene}"); } } public static void LoadPosition() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (_savedPosition == Vector3.zero) { Plugin.Log.LogWarning((object)"No position saved."); return; } string text = Plugin.GM?.sceneName ?? ""; if (text != _savedScene) { Plugin.Log.LogWarning((object)("Cannot teleport: different scene. Saved: " + _savedScene + ", Current: " + text)); } else { PlayerActions.TeleportTo(_savedPosition); } } public static string GetCurrentSceneName() { return Plugin.GM?.sceneName ?? "Unknown"; } public static void TransitionToScene(string sceneName, string gateName = "") { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown GameManager gM = Plugin.GM; if ((Object)(object)gM == (Object)null) { Plugin.Log.LogWarning((object)"Cannot transition: GameManager not available."); return; } SceneLoadInfo val = new SceneLoadInfo { SceneName = sceneName, EntryGateName = gateName, PreventCameraFadeOut = false, WaitForSceneTransitionCameraFade = true, EntryDelay = 0f, Visualization = (SceneLoadVisualizations)0 }; gM.BeginSceneTransition(val); Plugin.Log.LogInfo((object)("Transitioning to scene: " + sceneName)); } public static string ReloadCurrentScene() { string currentSceneName = GetCurrentSceneName(); if (currentSceneName == "Unknown") { return null; } TransitionToScene(currentSceneName); return currentSceneName; } public static void Respawn() { if ((Object)(object)Plugin.GM == (Object)null) { Plugin.Log.LogWarning((object)"Cannot respawn: GameManager not available."); } else if ((Object)(object)Plugin.Hero != (Object)null) { ((MonoBehaviour)Plugin.Hero).StartCoroutine(Plugin.Hero.HazardRespawn()); Plugin.Log.LogInfo((object)"Player respawned."); } } public static WorldInfo GetWorldInfo() { GameManager gM = Plugin.GM; if ((Object)(object)gM == (Object)null) { return default(WorldInfo); } return new WorldInfo { CurrentScene = gM.sceneName, EntryGate = gM.GetEntryGateName(), IsGamePaused = gM.IsGamePaused() }; } public static void PauseGame() { Time.timeScale = 0f; Plugin.Log.LogInfo((object)"Game paused."); } public static void ResumeGame() { SpeedControlManager.ApplyGlobalSpeed(); Plugin.Log.LogInfo((object)"Game resumed."); } [Obsolete("Use SpeedControl.SpeedControlManager.SetGlobalSpeed instead")] public static void SetGameSpeed(float speed) { SpeedControlManager.SetGlobalSpeed(speed); } } public struct WorldInfo { public string CurrentScene; public string EntryGate; public bool IsGamePaused; } } namespace SilksongManager.UI { public class NotificationManager : MonoBehaviour { private class Notification { public string Title; public string Message; public float Duration; public float TimeRemaining; public float Alpha; public NotificationState State; } private enum NotificationState { FadingIn, Visible, FadingOut } private static NotificationManager _instance; private readonly List _notifications = new List(); private const float FADE_DURATION = 0.25f; private const float DEFAULT_DURATION = 2f; private const float NOTIFICATION_HEIGHT = 50f; private const float NOTIFICATION_WIDTH = 280f; private const float PADDING = 15f; private const float SPACING = 8f; private const int MAX_NOTIFICATIONS = 5; private GUIStyle _titleStyle; private GUIStyle _messageStyle; private GUIStyle _boxStyle; private Texture2D _backgroundTexture; private bool _stylesInitialized; public static NotificationManager Instance => _instance; private void Awake() { if ((Object)(object)_instance != (Object)null && (Object)(object)_instance != (Object)(object)this) { Object.Destroy((Object)(object)this); } else { _instance = this; } } private void Update() { UpdateNotifications(); } private void OnGUI() { if (_notifications.Count != 0) { InitializeStyles(); DrawNotifications(); } } private void OnDestroy() { if ((Object)(object)_backgroundTexture != (Object)null) { Object.Destroy((Object)(object)_backgroundTexture); } } public static void Show(string title, string message = null, float duration = 2f) { if ((Object)(object)_instance == (Object)null) { Plugin.Log.LogWarning((object)"NotificationManager not initialized"); } else { _instance.AddNotification(title, message, duration); } } private void AddNotification(string title, string message, float duration) { while (_notifications.Count >= 5) { _notifications.RemoveAt(0); } Notification item = new Notification { Title = title, Message = message, Duration = duration, TimeRemaining = duration, Alpha = 0f, State = NotificationState.FadingIn }; _notifications.Add(item); Plugin.Log.LogInfo((object)("[Notification] " + title + ": " + message)); } private void UpdateNotifications() { for (int num = _notifications.Count - 1; num >= 0; num--) { Notification notification = _notifications[num]; switch (notification.State) { case NotificationState.FadingIn: notification.Alpha += Time.unscaledDeltaTime / 0.25f; if (notification.Alpha >= 1f) { notification.Alpha = 1f; notification.State = NotificationState.Visible; } break; case NotificationState.Visible: notification.TimeRemaining -= Time.unscaledDeltaTime; if (notification.TimeRemaining <= 0f) { notification.State = NotificationState.FadingOut; } break; case NotificationState.FadingOut: notification.Alpha -= Time.unscaledDeltaTime / 0.25f; if (notification.Alpha <= 0f) { _notifications.RemoveAt(num); } break; } } } private void InitializeStyles() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_008d: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown if (!_stylesInitialized) { _backgroundTexture = new Texture2D(1, 1); _backgroundTexture.SetPixel(0, 0, new Color(0.1f, 0.1f, 0.12f, 0.95f)); _backgroundTexture.Apply(); GUIStyle val = new GUIStyle(GUI.skin.box); val.normal.background = _backgroundTexture; val.border = new RectOffset(4, 4, 4, 4); val.padding = new RectOffset(12, 12, 8, 8); _boxStyle = val; GUIStyle val2 = new GUIStyle(GUI.skin.label) { fontSize = 14, fontStyle = (FontStyle)1 }; val2.normal.textColor = new Color(0.95f, 0.75f, 0.3f); val2.alignment = (TextAnchor)3; _titleStyle = val2; GUIStyle val3 = new GUIStyle(GUI.skin.label) { fontSize = 12 }; val3.normal.textColor = new Color(0.85f, 0.85f, 0.9f); val3.alignment = (TextAnchor)3; _messageStyle = val3; _stylesInitialized = true; } } private void DrawNotifications() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) float num = 15f; Rect val = default(Rect); for (int num2 = _notifications.Count - 1; num2 >= 0; num2--) { Notification notification = _notifications[num2]; float num3 = (string.IsNullOrEmpty(notification.Message) ? 35f : 50f); ((Rect)(ref val))..ctor((float)Screen.width - 280f - 15f, num, 280f, num3); Color color = GUI.color; GUI.color = new Color(1f, 1f, 1f, notification.Alpha); GUI.Box(val, GUIContent.none, _boxStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 12f, ((Rect)(ref val)).y + 6f, ((Rect)(ref val)).width - 24f, 20f), notification.Title, _titleStyle); if (!string.IsNullOrEmpty(notification.Message)) { GUI.Label(new Rect(((Rect)(ref val)).x + 12f, ((Rect)(ref val)).y + 26f, ((Rect)(ref val)).width - 24f, 18f), notification.Message, _messageStyle); } GUI.color = color; num += num3 + 8f; } } } } namespace SilksongManager.Tools { public static class ToolActions { public static void UnlockAllTools() { ToolItemManager.UnlockAllTools(); Plugin.Log.LogInfo((object)"Unlocked all tools."); } public static void UnlockAllCrests() { ToolItemManager.UnlockAllCrests(); Plugin.Log.LogInfo((object)"Unlocked all crests."); } public static List GetAllTools() { List list = new List(); foreach (ToolItem allTool in ToolItemManager.GetAllTools()) { if ((Object)(object)allTool != (Object)null) { list.Add(new ToolInfo { Name = allTool.name, IsUnlocked = allTool.IsUnlocked }); } } return list; } public static List GetUnlockedTools() { List list = new List(); foreach (ToolItem unlockedTool in ToolItemManager.GetUnlockedTools()) { if ((Object)(object)unlockedTool != (Object)null) { list.Add(new ToolInfo { Name = unlockedTool.name, IsUnlocked = true }); } } return list; } public static List GetAllCrests() { List list = new List(); foreach (ToolCrest allCrest in ToolItemManager.GetAllCrests()) { if ((Object)(object)allCrest != (Object)null) { list.Add(new CrestInfo { Name = allCrest.name, IsUnlocked = allCrest.IsUnlocked }); } } return list; } public static void ReplenishAllTools() { ToolItemManager.TryReplenishTools(true, (ReplenishMethod)0); Plugin.Log.LogInfo((object)"Replenished all tools."); } public static bool UnlockTool(string toolName) { ToolItem toolByName = ToolItemManager.GetToolByName(toolName); if ((Object)(object)toolByName == (Object)null) { Plugin.Log.LogWarning((object)("Tool not found: " + toolName)); return false; } ((SavedItem)toolByName).Get(true); Plugin.Log.LogInfo((object)("Unlocked tool: " + toolName)); return true; } public static bool LockTool(string toolName) { ToolItem toolByName = ToolItemManager.GetToolByName(toolName); if ((Object)(object)toolByName == (Object)null) { Plugin.Log.LogWarning((object)("Tool not found: " + toolName)); return false; } toolByName.Lock(); Plugin.Log.LogInfo((object)("Locked tool: " + toolName)); return true; } public static void LockAllTools() { foreach (ToolItem allTool in ToolItemManager.GetAllTools()) { if ((Object)(object)allTool != (Object)null && allTool.IsUnlocked) { allTool.Lock(); } } Plugin.Log.LogInfo((object)"Locked all tools."); } public static List GetNonCrestTools() { List list = new List(); foreach (ToolItem allTool in ToolItemManager.GetAllTools()) { if (!((Object)(object)allTool == (Object)null)) { list.Add(new ToolInfo { Name = allTool.name, IsUnlocked = allTool.IsUnlocked }); } } return list; } } public struct ToolInfo { public string Name; public bool IsUnlocked; } public struct CrestInfo { public string Name; public bool IsUnlocked; } } namespace SilksongManager.SpeedControl { public class EnemySpeedScaler : MonoBehaviour { private Rigidbody2D _rb; private HealthManager _hm; private const float WALK_SPEED_MAX = 25f; private const float MIN_SPEED = 0.5f; private void Awake() { _rb = ((Component)this).GetComponent(); _hm = ((Component)this).GetComponent(); if ((Object)(object)_hm == (Object)null) { _hm = ((Component)this).GetComponentInParent(); } } private void FixedUpdate() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_rb == (Object)null || (Object)(object)_hm == (Object)null || !SpeedControlConfig.IsEnabled) { return; } float effectiveEnemyMovement = SpeedControlConfig.EffectiveEnemyMovement; if (!Mathf.Approximately(effectiveEnemyMovement, 1f)) { Vector2 linearVelocity = _rb.linearVelocity; float magnitude = ((Vector2)(ref linearVelocity)).magnitude; if (!(magnitude < 0.5f) && !(magnitude > 25f)) { Vector2 normalized = ((Vector2)(ref linearVelocity)).normalized; float num = magnitude * effectiveEnemyMovement; num = Mathf.Min(num, 25f); _rb.linearVelocity = normalized * num; } } } } public class ProjectileSpeedScaler : MonoBehaviour { private Rigidbody2D _rb; private bool _hasScaled; private float _appliedMult = 1f; private void Awake() { _rb = ((Component)this).GetComponent(); } private void OnEnable() { _hasScaled = false; _appliedMult = 1f; if ((Object)(object)_rb == (Object)null) { _rb = ((Component)this).GetComponent(); } } private void Start() { TryScale(); } private void FixedUpdate() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (!_hasScaled) { TryScale(); return; } float effectiveEnemyAttack = SpeedControlConfig.EffectiveEnemyAttack; if (Mathf.Abs(effectiveEnemyAttack - _appliedMult) > 0.01f && (Object)(object)_rb != (Object)null) { Vector2 linearVelocity = _rb.linearVelocity; if (((Vector2)(ref linearVelocity)).sqrMagnitude > 0.1f) { _rb.linearVelocity = _rb.linearVelocity / _appliedMult * effectiveEnemyAttack; _appliedMult = effectiveEnemyAttack; } } } private void TryScale() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_rb == (Object)null || !SpeedControlConfig.IsEnabled) { return; } float effectiveEnemyAttack = SpeedControlConfig.EffectiveEnemyAttack; if (Mathf.Approximately(effectiveEnemyAttack, 1f)) { _hasScaled = true; _appliedMult = 1f; return; } Vector2 linearVelocity = _rb.linearVelocity; if (!(((Vector2)(ref linearVelocity)).sqrMagnitude < 0.1f)) { _rb.linearVelocity = linearVelocity * effectiveEnemyAttack; _hasScaled = true; _appliedMult = effectiveEnemyAttack; } } } public static class SpeedControlConfig { public static float GlobalSpeed { get; set; } = 1f; public static float PlayerMovementSpeed { get; set; } = 1f; public static float PlayerAttackSpeed { get; set; } = 1f; public static float PlayerAllSpeed { get; set; } = 1f; public static float EffectivePlayerMovement => PlayerMovementSpeed * PlayerAllSpeed; public static float EffectivePlayerAttack => PlayerAttackSpeed * PlayerAllSpeed; public static float EnemyMovementSpeed { get; set; } = 1f; public static float EnemyAttackSpeed { get; set; } = 1f; public static float EnemyAllSpeed { get; set; } = 1f; public static float EffectiveEnemyMovement => EnemyMovementSpeed * EnemyAllSpeed; public static float EffectiveEnemyAttack => EnemyAttackSpeed * EnemyAllSpeed; public static bool IsEnabled { get; set; } = true; internal static float OriginalRunSpeed { get; set; } = 0f; internal static float OriginalWalkSpeed { get; set; } = 0f; internal static bool OriginalsCaptured { get; set; } = false; public static void ResetAll() { GlobalSpeed = 1f; PlayerMovementSpeed = 1f; PlayerAttackSpeed = 1f; PlayerAllSpeed = 1f; EnemyMovementSpeed = 1f; EnemyAttackSpeed = 1f; EnemyAllSpeed = 1f; } public static bool IsAnyModified() { if (GlobalSpeed == 1f && PlayerMovementSpeed == 1f && PlayerAttackSpeed == 1f && PlayerAllSpeed == 1f && EnemyMovementSpeed == 1f && EnemyAttackSpeed == 1f) { return EnemyAllSpeed != 1f; } return true; } } public static class SpeedControlManager { private static bool _initialized; private static HeroController _cachedHero; public static void Initialize() { if (!_initialized) { SpeedControlPatches.Apply(); SceneManager.sceneLoaded += OnSceneLoaded; _initialized = true; Plugin.Log.LogInfo((object)"SpeedControl system initialized"); } } public static void Shutdown() { SceneManager.sceneLoaded -= OnSceneLoaded; SpeedControlPatches.Remove(); SpeedControlConfig.ResetAll(); _initialized = false; } public static void SetGlobalSpeed(float speed) { SpeedControlConfig.GlobalSpeed = Mathf.Clamp(speed, 0.1f, 10f); ApplyGlobalSpeed(); Plugin.Log.LogInfo((object)$"Global speed set to {SpeedControlConfig.GlobalSpeed:F2}x"); } public static void ApplyGlobalSpeed() { if (SpeedControlConfig.IsEnabled) { GameManager gM = Plugin.GM; if (!((Object)(object)gM != (Object)null) || !gM.IsGamePaused()) { Time.timeScale = SpeedControlConfig.GlobalSpeed; } } } public static void SetPlayerMovementSpeed(float speed) { SpeedControlConfig.PlayerMovementSpeed = Mathf.Clamp(speed, 0.1f, 10f); ApplyPlayerSpeed(); Plugin.Log.LogInfo((object)$"Player movement speed set to {speed:F2}x"); } public static void SetPlayerAttackSpeed(float speed) { SpeedControlConfig.PlayerAttackSpeed = Mathf.Clamp(speed, 0.1f, 10f); ApplyPlayerAttackSpeed(); Plugin.Log.LogInfo((object)$"Player attack speed set to {speed:F2}x"); } public static void SetPlayerAllSpeed(float speed) { SpeedControlConfig.PlayerAllSpeed = Mathf.Clamp(speed, 0.1f, 10f); ApplyPlayerSpeed(); ApplyPlayerAttackSpeed(); Plugin.Log.LogInfo((object)$"Player all speed set to {speed:F2}x"); } public static void ApplyPlayerSpeed() { if (!SpeedControlConfig.IsEnabled) { return; } HeroController hero = Plugin.Hero; if (!((Object)(object)hero == (Object)null)) { if (!SpeedControlConfig.OriginalsCaptured || SpeedControlConfig.OriginalRunSpeed <= 0f) { SpeedControlConfig.OriginalRunSpeed = 8.3f; SpeedControlConfig.OriginalWalkSpeed = 3.3f; SpeedControlConfig.OriginalsCaptured = true; Plugin.Log.LogInfo((object)$"Speed originals set: Run={SpeedControlConfig.OriginalRunSpeed}, Walk={SpeedControlConfig.OriginalWalkSpeed}"); } float effectivePlayerMovement = SpeedControlConfig.EffectivePlayerMovement; hero.RUN_SPEED = SpeedControlConfig.OriginalRunSpeed * effectivePlayerMovement; hero.WALK_SPEED = SpeedControlConfig.OriginalWalkSpeed * effectivePlayerMovement; } } public static void ApplyPlayerAttackSpeed() { } public static void SetEnemyMovementSpeed(float speed) { SpeedControlConfig.EnemyMovementSpeed = Mathf.Clamp(speed, 0.1f, 10f); ApplyEnemySpeed(); Plugin.Log.LogInfo((object)$"Enemy movement speed set to {speed:F2}x"); } public static void SetEnemyAttackSpeed(float speed) { SpeedControlConfig.EnemyAttackSpeed = Mathf.Clamp(speed, 0.1f, 10f); ApplyEnemyAnimatorSpeed(); Plugin.Log.LogInfo((object)$"Enemy attack speed set to {speed:F2}x"); } public static void SetEnemyAllSpeed(float speed) { SpeedControlConfig.EnemyAllSpeed = Mathf.Clamp(speed, 0.1f, 10f); ApplyEnemySpeed(); ApplyEnemyAnimatorSpeed(); Plugin.Log.LogInfo((object)$"Enemy all speed set to {speed:F2}x"); } public static void ApplyEnemySpeed() { } public static void ApplyEnemyAnimatorSpeed() { if (!SpeedControlConfig.IsEnabled) { return; } float effectiveEnemyAttack = SpeedControlConfig.EffectiveEnemyAttack; foreach (HealthManager item in HealthManager.EnumerateActiveEnemies()) { if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).gameObject == (Object)null) { continue; } Animator[] componentsInChildren = ((Component)item).GetComponentsInChildren(); foreach (Animator val in componentsInChildren) { if ((Object)(object)val != (Object)null) { val.speed = effectiveEnemyAttack; } } } } public static void ResetAll() { SpeedControlConfig.ResetAll(); HeroController hero = Plugin.Hero; if ((Object)(object)hero != (Object)null && SpeedControlConfig.OriginalsCaptured) { hero.RUN_SPEED = SpeedControlConfig.OriginalRunSpeed; hero.WALK_SPEED = SpeedControlConfig.OriginalWalkSpeed; } Time.timeScale = 1f; SpeedControlPatches.ResetWalkerSpeeds(); Plugin.Log.LogInfo((object)"All speeds reset to 1.0x"); } public static void ApplyAllSpeeds() { if (SpeedControlConfig.IsEnabled) { ApplyGlobalSpeed(); ApplyPlayerSpeed(); ApplyEnemyAnimatorSpeed(); } } private static bool IsHeroOrEnemy(GameObject go) { if ((Object)(object)go == (Object)null) { return false; } HeroController hero = Plugin.Hero; if ((Object)(object)hero != (Object)null && ((Object)(object)go == (Object)(object)((Component)hero).gameObject || go.transform.IsChildOf(((Component)hero).transform))) { return true; } if ((Object)(object)go.GetComponentInParent() != (Object)null) { return true; } return false; } private static void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(ApplySpeedsDelayed()); } } private static IEnumerator ApplySpeedsDelayed() { yield return (object)new WaitForSeconds(0.5f); ApplyAllSpeeds(); } public static void Update() { if (SpeedControlConfig.IsEnabled && SpeedControlConfig.IsAnyModified()) { Mathf.Approximately(SpeedControlConfig.EffectiveEnemyMovement, 1f); } } } public static class SpeedControlPatches { private static Harmony _harmony; private static Type _tk2dAnimatorType; private static Type _tk2dClipType; private static PropertyInfo _clipFpsProperty; private static PropertyInfo _currentClipProperty; private static FieldInfo _clipNameField; private static bool _reflectionInitialized = false; private static HashSet _enemiesWithScaler = new HashSet(); private static readonly HashSet _movementAnimNames = new HashSet { "Walk", "Run", "Fly", "Idle", "Turn", "Move", "walk", "run", "fly", "idle", "turn", "move", "Walking", "Running", "Flying", "Turning", "Moving", "walking", "running", "flying", "turning", "moving", "Crawl", "crawl", "Crawling", "crawling" }; private static int _tk2dCallCount = 0; private static HashSet _spawnedWithScaler = new HashSet(); public static void Apply() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown try { InitializeReflection(); _harmony = new Harmony("com.catalyst.silksongmanager.speedcontrol"); int count = 0; TryPatch(typeof(GameManager), "UnpauseGame", "GameManager_UnpauseGame_Postfix", ref count); TryPatch(typeof(TimeManager), "UpdateTimeScale", "TimeManager_UpdateTimeScale_Postfix", ref count); TryPatch(typeof(HeroController), "Start", "HeroController_Start_Postfix", ref count); TryPatch(typeof(HeroController), "TakeDamage", "HeroController_TakeDamage_Postfix", ref count); TryPatch(typeof(HeroController), "Respawn", "HeroController_Respawn_Postfix", ref count); TryPatch(typeof(NailSlash), "PlaySlash", "NailSlash_PlaySlash_Postfix", ref count); TryPatch(typeof(Downspike), "StartSlash", "Downspike_StartSlash_Postfix", ref count); PatchAttackCooldowns(ref count); PatchObjectPoolSpawn(ref count); TryPatch(typeof(HealthManager), "OnEnable", "HealthManager_OnEnable_Postfix", ref count); PatchTk2dAnimator(ref count); Plugin.Log.LogInfo((object)$"SpeedControlPatches: {count} patches applied"); } catch (Exception ex) { Plugin.Log.LogError((object)("SpeedControlPatches failed: " + ex.Message + "\n" + ex.StackTrace)); } } private static void PatchTk2dAnimator(ref int count) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Expected O, but got Unknown if (_tk2dAnimatorType == null) { return; } try { MethodInfo methodInfo = AccessTools.Method(_tk2dAnimatorType, "Play", Type.EmptyTypes, (Type[])null); if (methodInfo != null) { MethodInfo method = typeof(SpeedControlPatches).GetMethod("Tk2d_PlayNoArgs_Postfix", BindingFlags.Static | BindingFlags.Public); _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); count++; Plugin.Log.LogInfo((object)"SpeedControl: Patched tk2d.Play()"); } MethodInfo methodInfo2 = AccessTools.Method(_tk2dAnimatorType, "Play", new Type[1] { typeof(string) }, (Type[])null); if (methodInfo2 != null) { MethodInfo method2 = typeof(SpeedControlPatches).GetMethod("Tk2d_Play_Postfix", BindingFlags.Static | BindingFlags.Public); _harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); count++; Plugin.Log.LogInfo((object)"SpeedControl: Patched tk2d.Play(string)"); } if (_tk2dClipType != null) { MethodInfo methodInfo3 = AccessTools.Method(_tk2dAnimatorType, "Play", new Type[1] { _tk2dClipType }, (Type[])null); if (methodInfo3 != null) { MethodInfo method3 = typeof(SpeedControlPatches).GetMethod("Tk2d_PlayClip_Postfix", BindingFlags.Static | BindingFlags.Public); _harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(method3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); count++; Plugin.Log.LogInfo((object)"SpeedControl: Patched tk2d.Play(clip)"); } MethodInfo methodInfo4 = AccessTools.Method(_tk2dAnimatorType, "Play", new Type[3] { _tk2dClipType, typeof(float), typeof(float) }, (Type[])null); if (methodInfo4 != null) { MethodInfo method4 = typeof(SpeedControlPatches).GetMethod("Tk2d_PlayClipFps_Postfix", BindingFlags.Static | BindingFlags.Public); _harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, new HarmonyMethod(method4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); count++; Plugin.Log.LogInfo((object)"SpeedControl: Patched tk2d.Play(clip,float,float)"); } } MethodInfo methodInfo5 = AccessTools.Method(_tk2dAnimatorType, "PlayFromFrame", new Type[2] { typeof(string), typeof(int) }, (Type[])null); if (methodInfo5 != null) { MethodInfo method5 = typeof(SpeedControlPatches).GetMethod("Tk2d_PlayFromFrame_Postfix", BindingFlags.Static | BindingFlags.Public); _harmony.Patch((MethodBase)methodInfo5, (HarmonyMethod)null, new HarmonyMethod(method5), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); count++; Plugin.Log.LogInfo((object)"SpeedControl: Patched tk2d.PlayFromFrame"); } } catch (Exception ex) { Plugin.Log.LogError((object)("SpeedControl: tk2d patch failed: " + ex.Message)); } } private static void PatchObjectPoolSpawn(ref int count) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown try { MethodInfo methodInfo = AccessTools.Method(typeof(ObjectPool), "Spawn", new Type[5] { typeof(GameObject), typeof(Transform), typeof(Vector3), typeof(Quaternion), typeof(bool) }, (Type[])null); if (methodInfo != null) { MethodInfo method = typeof(SpeedControlPatches).GetMethod("ObjectPool_Spawn_Postfix", BindingFlags.Static | BindingFlags.Public); _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); count++; Plugin.Log.LogInfo((object)"SpeedControl: Patched ObjectPool.Spawn"); } else { Plugin.Log.LogWarning((object)"SpeedControl: ObjectPool.Spawn method not found"); } } catch (Exception ex) { Plugin.Log.LogError((object)("SpeedControl: ObjectPool.Spawn patch failed: " + ex.Message)); } } private static void PatchAttackCooldowns(ref int count) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown try { MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(HeroControllerConfig), "AttackCooldownTime"); if (methodInfo != null) { MethodInfo method = typeof(SpeedControlPatches).GetMethod("AttackCooldownTime_Postfix", BindingFlags.Static | BindingFlags.Public); _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); count++; Plugin.Log.LogInfo((object)"SpeedControl: Patched AttackCooldownTime"); } MethodInfo methodInfo2 = AccessTools.PropertyGetter(typeof(HeroControllerConfig), "QuickAttackCooldownTime"); if (methodInfo2 != null) { MethodInfo method2 = typeof(SpeedControlPatches).GetMethod("AttackCooldownTime_Postfix", BindingFlags.Static | BindingFlags.Public); _harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); count++; Plugin.Log.LogInfo((object)"SpeedControl: Patched QuickAttackCooldownTime"); } MethodInfo methodInfo3 = AccessTools.PropertyGetter(typeof(HeroControllerConfig), "AttackRecoveryTime"); if (methodInfo3 != null) { MethodInfo method3 = typeof(SpeedControlPatches).GetMethod("AttackCooldownTime_Postfix", BindingFlags.Static | BindingFlags.Public); _harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(method3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); count++; Plugin.Log.LogInfo((object)"SpeedControl: Patched AttackRecoveryTime"); } } catch (Exception ex) { Plugin.Log.LogError((object)("SpeedControl: Attack cooldown patches failed: " + ex.Message)); } } private static void TryPatch(Type targetType, string methodName, string patchName, ref int count) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown try { MethodInfo methodInfo = AccessTools.Method(targetType, methodName, (Type[])null, (Type[])null); if (!(methodInfo == null)) { MethodInfo method = typeof(SpeedControlPatches).GetMethod(patchName, BindingFlags.Static | BindingFlags.Public); if (!(method == null)) { _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); count++; } } } catch (Exception ex) { Plugin.Log.LogError((object)("SpeedControl: " + targetType.Name + "." + methodName + " failed: " + ex.Message)); } } private static void InitializeReflection() { if (_reflectionInitialized) { return; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { _tk2dAnimatorType = assembly.GetType("tk2dSpriteAnimator"); if (!(_tk2dAnimatorType != null)) { continue; } _tk2dClipType = assembly.GetType("tk2dSpriteAnimationClip"); Plugin.Log.LogInfo((object)("SpeedControl: Found tk2d type in " + assembly.GetName().Name)); MethodInfo[] methods = _tk2dAnimatorType.GetMethods(); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == "Play") { ParameterInfo[] parameters = methodInfo.GetParameters(); string text = string.Join(", ", Array.ConvertAll(parameters, (ParameterInfo p) => p.ParameterType.Name)); Plugin.Log.LogInfo((object)("SpeedControl: Found Play(" + text + ")")); } } break; } if (_tk2dAnimatorType != null) { _clipFpsProperty = _tk2dAnimatorType.GetProperty("ClipFps"); _currentClipProperty = _tk2dAnimatorType.GetProperty("CurrentClip"); } if (_tk2dClipType != null) { _clipNameField = _tk2dClipType.GetField("name"); } } catch { } _reflectionInitialized = true; } public static void Remove() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } public static void Tk2d_PlayNoArgs_Postfix(object __instance) { ApplyAnimationSpeedToCurrentClip(__instance); } public static void Tk2d_Play_Postfix(object __instance, string name) { _tk2dCallCount++; if (_tk2dCallCount <= 10) { Component val = (Component)((__instance is Component) ? __instance : null); ManualLogSource log = Plugin.Log; object arg = _tk2dCallCount; object obj; if (val == null) { obj = null; } else { GameObject gameObject = val.gameObject; obj = ((gameObject != null) ? ((Object)gameObject).name : null); } if (obj == null) { obj = "null"; } log.LogInfo((object)$"SpeedControl: tk2d.Play called #{arg}: '{name}' on {obj}"); } ApplyAnimationSpeed(__instance, name); } public static void Tk2d_PlayClip_Postfix(object __instance, object clip) { string clipName = GetClipName(clip); _tk2dCallCount++; if (_tk2dCallCount <= 10) { Component val = (Component)((__instance is Component) ? __instance : null); ManualLogSource log = Plugin.Log; object arg = _tk2dCallCount; object obj; if (val == null) { obj = null; } else { GameObject gameObject = val.gameObject; obj = ((gameObject != null) ? ((Object)gameObject).name : null); } if (obj == null) { obj = "null"; } log.LogInfo((object)$"SpeedControl: tk2d.Play(clip) called #{arg}: '{clipName}' on {obj}"); } ApplyAnimationSpeed(__instance, clipName); } public static void Tk2d_PlayClipFps_Postfix(object __instance, object clip) { string clipName = GetClipName(clip); _tk2dCallCount++; if (_tk2dCallCount <= 10) { Component val = (Component)((__instance is Component) ? __instance : null); ManualLogSource log = Plugin.Log; object arg = _tk2dCallCount; object obj; if (val == null) { obj = null; } else { GameObject gameObject = val.gameObject; obj = ((gameObject != null) ? ((Object)gameObject).name : null); } if (obj == null) { obj = "null"; } log.LogInfo((object)$"SpeedControl: tk2d.Play(clip,fps) called #{arg}: '{clipName}' on {obj}"); } ApplyAnimationSpeed(__instance, clipName); } public static void Tk2d_PlayFromFrame_Postfix(object __instance, string name) { _tk2dCallCount++; if (_tk2dCallCount <= 10) { Component val = (Component)((__instance is Component) ? __instance : null); ManualLogSource log = Plugin.Log; object arg = _tk2dCallCount; object obj; if (val == null) { obj = null; } else { GameObject gameObject = val.gameObject; obj = ((gameObject != null) ? ((Object)gameObject).name : null); } if (obj == null) { obj = "null"; } log.LogInfo((object)$"SpeedControl: tk2d.PlayFromFrame called #{arg}: '{name}' on {obj}"); } ApplyAnimationSpeed(__instance, name); } private static void ApplyAnimationSpeed(object animator, string animName) { if (!SpeedControlConfig.IsEnabled || _clipFpsProperty == null) { return; } try { Component val = (Component)((animator is Component) ? animator : null); if ((Object)(object)val == (Object)null) { return; } GameObject gameObject = val.gameObject; if (IsHeroObject(gameObject) || !IsEnemyObject(gameObject)) { return; } bool num = IsMovementAnimation(animName); float num2 = 1f; if (num) { num2 = SpeedControlConfig.EffectiveEnemyMovement; } else { num2 = SpeedControlConfig.EffectiveEnemyAttack; if (!Mathf.Approximately(num2, 1f)) { Plugin.Log.LogInfo((object)$"SpeedControl: Attack anim '{animName}' on {((Object)gameObject).name}, mult={num2}"); } } if (!Mathf.Approximately(num2, 1f)) { ApplyFpsMult(animator, num2); } } catch { } } private static void ApplyFpsMult(object animator, float mult) { try { float num = (float)_clipFpsProperty.GetValue(animator); if (num > 0f) { _clipFpsProperty.SetValue(animator, num * mult); } } catch { } } private static bool IsMovementAnimation(string animName) { if (string.IsNullOrEmpty(animName)) { return false; } foreach (string movementAnimName in _movementAnimNames) { if (animName.Contains(movementAnimName)) { return true; } } return false; } public static void GameManager_UnpauseGame_Postfix() { if (SpeedControlConfig.IsEnabled && SpeedControlConfig.GlobalSpeed != 1f) { Time.timeScale = SpeedControlConfig.GlobalSpeed; } } public static void TimeManager_UpdateTimeScale_Postfix() { if (SpeedControlConfig.IsEnabled && !Mathf.Approximately(SpeedControlConfig.GlobalSpeed, 1f)) { Time.timeScale *= SpeedControlConfig.GlobalSpeed; } } public static void HeroController_Start_Postfix(HeroController __instance) { if (!SpeedControlConfig.OriginalsCaptured) { SpeedControlConfig.OriginalRunSpeed = __instance.RUN_SPEED; SpeedControlConfig.OriginalWalkSpeed = __instance.WALK_SPEED; SpeedControlConfig.OriginalsCaptured = true; } SpeedControlManager.ApplyPlayerSpeed(); } public static void HeroController_TakeDamage_Postfix(HeroController __instance) { if (SpeedControlConfig.IsEnabled) { SpeedControlManager.ApplyPlayerSpeed(); } } public static void HeroController_Respawn_Postfix() { if (SpeedControlConfig.IsEnabled && (Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(ApplySpeedsNextFrame()); } } public static void HealthManager_OnEnable_Postfix(HealthManager __instance) { if ((Object)(object)__instance == (Object)null) { return; } int instanceID = ((Object)((Component)__instance).gameObject).GetInstanceID(); if (!_enemiesWithScaler.Contains(instanceID)) { if ((Object)(object)((Component)__instance).GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } _enemiesWithScaler.Add(instanceID); } } public static void NailSlash_PlaySlash_Postfix(NailSlash __instance) { if (SpeedControlConfig.IsEnabled) { float effectivePlayerAttack = SpeedControlConfig.EffectivePlayerAttack; if (!Mathf.Approximately(effectivePlayerAttack, 1f)) { ApplyTk2dSpeedMultiplier(((Component)__instance).gameObject, effectivePlayerAttack); } } } public static void Downspike_StartSlash_Postfix(Downspike __instance) { if (SpeedControlConfig.IsEnabled) { float effectivePlayerAttack = SpeedControlConfig.EffectivePlayerAttack; if (!Mathf.Approximately(effectivePlayerAttack, 1f)) { ApplyTk2dSpeedMultiplier(((Component)__instance).gameObject, effectivePlayerAttack); } } } public static void AttackCooldownTime_Postfix(ref float __result) { if (SpeedControlConfig.IsEnabled) { float effectivePlayerAttack = SpeedControlConfig.EffectivePlayerAttack; if (!Mathf.Approximately(effectivePlayerAttack, 1f)) { __result /= effectivePlayerAttack; } } } public static void ObjectPool_Spawn_Postfix(GameObject __result) { if ((Object)(object)__result == (Object)null || !SpeedControlConfig.IsEnabled) { return; } int instanceID = ((Object)__result).GetInstanceID(); if (!_spawnedWithScaler.Contains(instanceID)) { _spawnedWithScaler.Add(instanceID); if ((Object)(object)__result.GetComponent() != (Object)null && !IsHeroObject(__result) && (Object)(object)__result.GetComponent() == (Object)null) { __result.AddComponent(); } } } private static bool IsHeroObject(GameObject go) { if ((Object)(object)go == (Object)null) { return false; } HeroController instance = HeroController.instance; if ((Object)(object)instance == (Object)null) { return false; } if (!((Object)(object)go == (Object)(object)((Component)instance).gameObject)) { return go.transform.IsChildOf(((Component)instance).transform); } return true; } private static bool IsEnemyObject(GameObject go) { if ((Object)(object)go == (Object)null) { return false; } return (Object)(object)go.GetComponentInParent() != (Object)null; } private static void ApplyTk2dSpeedMultiplier(GameObject go, float mult) { if (_tk2dAnimatorType == null || _clipFpsProperty == null) { return; } try { Component component = go.GetComponent(_tk2dAnimatorType); if (!((Object)(object)component == (Object)null)) { float num = (float)_clipFpsProperty.GetValue(component); _clipFpsProperty.SetValue(component, num * mult); } } catch { } } private static string GetClipName(object clip) { if (clip == null || _clipNameField == null) { return ""; } try { return (_clipNameField.GetValue(clip) as string) ?? ""; } catch { return ""; } } private static void ApplyAnimationSpeedToCurrentClip(object animator) { if (_currentClipProperty == null) { return; } try { string clipName = GetClipName(_currentClipProperty.GetValue(animator)); ApplyAnimationSpeed(animator, clipName); } catch { } } private static IEnumerator ApplySpeedsNextFrame() { yield return null; SpeedControlManager.ApplyAllSpeeds(); } public static void ResetWalkerSpeeds() { } } } namespace SilksongManager.SaveState { [Serializable] public class BattleSceneStateData { public string GameObjectPath; public int CurrentWave; public int CurrentEnemies; public int EnemiesToNext; public bool Started; public bool Completed; public FsmStateData LogicFsmState; } [Serializable] public class BossSceneStateData { public bool IsActive; public int BossLevel; public bool HasTransitionedIn; public int BossesLeft; public FsmStateData ControllerFsmState; } [Serializable] public class SpriteRendererData { public bool Enabled; public Color Color; public int SortingOrder; public string SortingLayerName; public string SpriteName; } [Serializable] public class AnimatorData { public bool Enabled; public int StateHash; public float NormalizedTime; public float Speed; } [Serializable] public class ColliderData { public bool Enabled; public bool IsTrigger; } [Serializable] public class TransformData { public Vector3 LocalPosition; public Quaternion LocalRotation; public Vector3 LocalScale; } [Serializable] public class MeshRendererData { public bool Enabled; public string SortingLayerName; public int SortingOrder; } [Serializable] public class SkinnedMeshRendererData { public bool Enabled; public string SortingLayerName; public int SortingOrder; } [Serializable] public class ObjectComponentData { public bool IsActive; public SpriteRendererData SpriteRenderer; public MeshRendererData MeshRenderer; public SkinnedMeshRendererData SkinnedMeshRenderer; public AnimatorData Animator; public ColliderData Collider2D; public TransformData Transform; } [Serializable] public class EnemyStateData { public string GameObjectName; public string GameObjectPath; public bool IsActive = true; public int HP; public bool IsDead; public bool IsInvincible; public int InvincibleFromDirection; public bool HasHit; public Vector3 Position; public Quaternion Rotation; public Vector3 Scale; public Vector2 Velocity; public float AngularVelocity; public bool IsKinematic; public bool IsRecoiling; public float RecoilTimeRemaining; public int RecoilDirection; public List FsmStates = new List(); public ObjectComponentData MainObjectState; public Dictionary ChildStates = new Dictionary(); public Dictionary ChildObjectStates = new Dictionary(); } [Serializable] public class FsmStateData { public string FsmName; public string ActiveStateName; public Dictionary BoolVariables = new Dictionary(); public Dictionary IntVariables = new Dictionary(); public Dictionary FloatVariables = new Dictionary(); public Dictionary StringVariables = new Dictionary(); public Dictionary Vector3Variables = new Dictionary(); } [Serializable] public class SaveStateData { public string SaveName; public string Timestamp; public string SceneName; public string PlayerDataJson; public string SceneDataJson; public Vector3 Position; public Vector2 Velocity; public bool FacingRight; public bool IsGrounded; public int Health; public int MaxHealth; public int Silk; public int MaxSilk; public int Geo; public List EnemyStates; public BattleSceneStateData BattleSceneState; public BossSceneStateData BossSceneState; public string GetDisplayName() { if (string.IsNullOrEmpty(SaveName)) { return SceneName + " - " + Timestamp; } return SaveName; } } public static class SaveStateManager { private static List _saveStates = new List(); private static string _saveFilePath; private static SaveStateData _pendingLoadState; private static Harmony _harmony; public static event Action OnStatesChanged; public static void Initialize() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown _saveFilePath = Path.Combine(Paths.ConfigPath, "SilksongManager_SaveStates.json"); LoadStatesFromDisk(); _harmony = new Harmony("com.silksongmanager.savestate"); _harmony.Patch((MethodBase)AccessTools.Method(typeof(GameManager), "FindEntryPoint", (Type[])null, (Type[])null), new HarmonyMethod(typeof(SaveStateManager), "FindEntryPointPatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public static List GetStates() { return _saveStates; } public static SaveStateData GetLastState() { if (_saveStates.Count == 0) { return null; } return _saveStates[_saveStates.Count - 1]; } public static string QuickSave() { CaptureState(); return GetLastState()?.GetDisplayName() ?? "Unknown"; } public static string LoadLastState() { SaveStateData lastState = GetLastState(); if (lastState == null) { Plugin.Log.LogWarning((object)"No save states available to load."); return null; } LoadState(lastState); return lastState.GetDisplayName(); } public static void CaptureState(string name = null) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if (Plugin.PD == null || (Object)(object)Plugin.Hero == (Object)null) { Plugin.Log.LogError((object)"Cannot save state: PlayerData or Hero is null"); return; } try { SaveStateData saveStateData = new SaveStateData(); saveStateData.SaveName = name; saveStateData.Timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); Scene activeScene = SceneManager.GetActiveScene(); saveStateData.SceneName = ((Scene)(ref activeScene)).name; saveStateData.PlayerDataJson = JsonConvert.SerializeObject((object)Plugin.PD); ForceSavePersistentItems(); if (SceneData.instance != null) { saveStateData.SceneDataJson = JsonConvert.SerializeObject((object)SceneData.instance); Plugin.Log.LogInfo((object)$"[DEBUG] Captured SceneData, JSON length: {saveStateData.SceneDataJson?.Length ?? 0}"); } HeroController hero = Plugin.Hero; saveStateData.Position = ((Component)hero).transform.position; saveStateData.Velocity = ((Component)hero).GetComponent().linearVelocity; saveStateData.FacingRight = hero.cState.facingRight; saveStateData.IsGrounded = hero.cState.onGround; saveStateData.Health = Plugin.PD.health; saveStateData.MaxHealth = Plugin.PD.maxHealth; saveStateData.Silk = Plugin.PD.silk; saveStateData.MaxSilk = Plugin.PD.silkMax; saveStateData.Geo = Plugin.PD.geo; saveStateData.EnemyStates = CaptureEnemyStates(); saveStateData.BattleSceneState = CaptureBattleSceneState(); saveStateData.BossSceneState = CaptureBossSceneState(); _saveStates.Add(saveStateData); SaveStatesToDisk(); SaveStateManager.OnStatesChanged?.Invoke(); Plugin.Log.LogInfo((object)("Captured save state: " + saveStateData.GetDisplayName())); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to capture state: " + ex.Message)); } } public static void LoadState(SaveStateData state) { if (state != null && !((Object)(object)Plugin.Hero == (Object)null)) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(LoadStateCoro(state)); } } private static IEnumerator LoadStateCoro(SaveStateData state) { Plugin.Log.LogInfo((object)("Starting robust load for state: " + state.SceneName)); _pendingLoadState = state; Time.timeScale = 0f; if ((Object)(object)Plugin.Hero != (Object)null) { ((MonoBehaviour)Plugin.Hero).StopAllCoroutines(); ((MonoBehaviour)Plugin.Hero).StopAllCoroutines(); typeof(HeroController).GetField("hazardInvulnRoutine", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(Plugin.Hero, null); typeof(HeroController).GetMethod("CancelDamageRecoil", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(Plugin.Hero, null); Component component = ((Component)Plugin.Hero).GetComponent("InvulnerablePulse"); if ((Object)(object)component != (Object)null) { ((object)component).GetType().GetMethod("StopInvulnerablePulse")?.Invoke(component, null); } } EventRegister.SendEvent("INVENTORY CANCEL", (GameObject)null); DialogueBox.EndConversation(true, (Action)null); DialogueBox.HideInstant(); DialogueYesNoBox.ForceClose(); QuestYesNoBox.ForceClose(); SlideSurface[] array = Object.FindObjectsOfType(); foreach (SlideSurface obj in array) { if ((bool)(typeof(SlideSurface).GetField("isHeroAttached", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(obj) ?? ((object)false))) { typeof(SlideSurface).GetMethod("Detach", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(obj, new object[1] { false }); } } string dummySceneName = "Demo Start"; GameManager.instance.entryGateName = "dreamGate"; GameManager.instance.startedOnThisScene = true; AsyncOperationHandle val = Addressables.LoadSceneAsync((object)("Scenes/" + dummySceneName), (LoadSceneMode)0, true, 100, (SceneReleaseMode)0); yield return val; yield return (object)new WaitUntil((Func)delegate { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); return ((Scene)(ref activeScene)).name == dummySceneName; }); if (Plugin.PD != null && !string.IsNullOrEmpty(state.PlayerDataJson)) { JsonConvert.PopulateObject(state.PlayerDataJson, (object)Plugin.PD); } if (SceneData.instance != null && !string.IsNullOrEmpty(state.SceneDataJson)) { Plugin.Log.LogInfo((object)$"[DEBUG] Restoring SceneData, JSON length: {state.SceneDataJson.Length}"); JsonConvert.PopulateObject(state.SceneDataJson, (object)SceneData.instance); Plugin.Log.LogInfo((object)"[DEBUG] SceneData restored"); } else { Plugin.Log.LogWarning((object)$"[DEBUG] SceneData NOT restored: instance={SceneData.instance != null}, json={!string.IsNullOrEmpty(state.SceneDataJson)}"); } EventRegister.SendEvent(EventRegisterEvents.HealthUpdate, (GameObject)null); EventRegister.SendEvent(EventRegisterEvents.UpdateBlueHealth, (GameObject)null); EventRegister.SendEvent(EventRegisterEvents.RegeneratedSilkChunk, (GameObject)null); EventRegister.SendEvent(EventRegisterEvents.SilkCursedUpdate, (GameObject)null); Plugin.Log.LogInfo((object)$"[DEBUG] Sent HUD refresh events: Health={state.Health}, Silk={state.Silk}"); StaticVariableList.ClearSceneTransitions(); Plugin.GM.BeginSceneTransition(new SceneLoadInfo { SceneName = state.SceneName, EntryGateName = "dreamGate", HeroLeaveDirection = (GatePosition)5, EntryDelay = 0f, WaitForSceneTransitionCameraFade = false, Visualization = (SceneLoadVisualizations)0, PreventCameraFadeOut = false, AlwaysUnloadUnusedAssets = true }); yield return (object)new WaitUntil((Func)delegate { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); return ((Scene)(ref activeScene)).name == state.SceneName; }); yield return (object)new WaitUntil((Func)(() => !Plugin.GM.IsInSceneTransition)); GameManager.instance.cameraCtrl.PositionToHero(false); GameManager.instance.FadeSceneIn(); Plugin.Hero.CharmUpdate(); QuestManager.IncrementVersion(); CollectableItemManager.IncrementVersion(); PlayMakerFSM.BroadcastEvent("CHARM INDICATOR CHECK"); PlayMakerFSM.BroadcastEvent("TOOL EQUIPS CHANGED"); PlayMakerFSM.BroadcastEvent("UPDATE NAIL DAMAGE"); FieldInfo field = typeof(CameraController).GetField("isGameplayScene", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { field.SetValue(GameManager.instance.cameraCtrl, true); } yield return null; try { RestorePersistentBoolItems(); } catch (Exception ex) { Plugin.Log.LogError((object)("Error restoring persistent items: " + ex)); } yield return (object)new WaitForSecondsRealtime(0.2f); try { RestoreEnemyStates(state.EnemyStates); } catch (Exception ex2) { Plugin.Log.LogError((object)("Error restoring enemies: " + ex2)); } try { RestoreBattleSceneState(state.BattleSceneState); } catch (Exception ex3) { Plugin.Log.LogError((object)("Error restoring battle: " + ex3)); } try { RestoreBossSceneState(state.BossSceneState); } catch (Exception ex4) { Plugin.Log.LogError((object)("Error restoring boss: " + ex4)); } if (state.BattleSceneState != null || state.BossSceneState != null) { PlayMakerFSM.BroadcastEvent("BATTLE START"); } ApplyStateImmediate(state); Plugin.Log.LogInfo((object)"[DEBUG] Force Unpausing Game..."); try { GameManager.instance.isPaused = false; } catch (Exception ex5) { Plugin.Log.LogWarning((object)("Failed to unpause GM: " + ex5.Message)); } try { GameManager.instance.FadeSceneIn(); } catch (Exception ex6) { Plugin.Log.LogWarning((object)("Failed to fade scene in: " + ex6.Message)); } try { GameCameras.instance.ResumeCameraShake(); } catch (Exception ex7) { Plugin.Log.LogWarning((object)("Failed to resume camera shake: " + ex7.Message)); } try { if ((Object)(object)GameManager.instance.inputHandler != (Object)null) { GameManager.instance.inputHandler.StartAcceptingInput(); GameManager.instance.inputHandler.AllowPause(); } } catch (Exception ex8) { Plugin.Log.LogWarning((object)("Failed to unlock input: " + ex8.Message)); } try { Type type = Assembly.GetAssembly(typeof(GameManager)).GetType("MenuButtonList"); if (type != null) { type.GetMethod("ClearAllLastSelected", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null); } } catch (Exception ex9) { Plugin.Log.LogWarning((object)("Failed to clear menus: " + ex9.Message)); } try { Time.timeScale = 1f; Type type2 = Assembly.GetAssembly(typeof(GameManager)).GetType("TimeManager"); if (type2 != null) { type2.GetProperty("TimeScale", BindingFlags.Static | BindingFlags.Public)?.SetValue(null, 1f); } } catch (Exception ex10) { Plugin.Log.LogWarning((object)("Failed to set TimeScale: " + ex10.Message)); } Plugin.Log.LogInfo((object)"[DEBUG] Unpause sequence completed"); yield return (object)new WaitForFixedUpdate(); ((Component)Plugin.Hero).transform.position = state.Position; Physics2D.SyncTransforms(); yield return (object)new WaitForFixedUpdate(); ForceEnemyRedetection(); Vector3 savedPos = ((Component)Plugin.Hero).transform.position; ((Component)Plugin.Hero).transform.position = new Vector3(9999f, 9999f, savedPos.z); Physics2D.SyncTransforms(); yield return (object)new WaitForFixedUpdate(); ((Component)Plugin.Hero).transform.position = savedPos; Physics2D.SyncTransforms(); yield return (object)new WaitForFixedUpdate(); Plugin.Log.LogInfo((object)"[DEBUG] Forced hero position reset for Physics2D collision re-detection"); Plugin.Log.LogInfo((object)$"[DEBUG] Before restore: health={Plugin.PD.health}, silk={Plugin.PD.silk}"); Plugin.PD.health = state.Health; Plugin.PD.silk = state.Silk; Plugin.PD.geo = state.Geo; Plugin.Log.LogInfo((object)$"[DEBUG] After restore: health={Plugin.PD.health}, silk={Plugin.PD.silk}, geo={Plugin.PD.geo}"); yield return (object)new WaitUntil((Func)(() => (Object)(object)GameCameras.instance?.hudCanvasSlideOut != (Object)null)); yield return null; try { Plugin.Log.LogInfo((object)$"[DEBUG] Triggering health UI update via TakeHealth/AddHealth, health={Plugin.PD.health}"); Plugin.Hero.TakeHealth(1); Plugin.Hero.AddHealth(1); Plugin.Log.LogInfo((object)$"[DEBUG] After TakeHealth/AddHealth, health={Plugin.PD.health}"); Plugin.Hero.ClearEffects(); int healthBlue = Plugin.PD.healthBlue; for (int num = 0; num < healthBlue; num++) { EventRegister.SendEvent("ADD BLUE HEALTH", (GameObject)null); } Plugin.Log.LogInfo((object)$"[DEBUG] Health UI refresh completed, blueHealth={healthBlue}"); if ((Object)(object)GameCameras.instance.silkSpool != (Object)null) { GameCameras.instance.silkSpool.DrawSpool(); Plugin.Log.LogInfo((object)"[DEBUG] Called silkSpool.DrawSpool()"); } PlayMakerFSM.BroadcastEvent("CHARM INDICATOR CHECK"); PlayMakerFSM.BroadcastEvent("TOOL EQUIPS CHANGED"); Plugin.Log.LogInfo((object)"[DEBUG] HUD refresh completed"); } catch (Exception ex11) { Plugin.Log.LogWarning((object)("HUD refresh failed: " + ex11.Message)); } Time.timeScale = 1f; _pendingLoadState = null; Plugin.Log.LogInfo((object)"Load complete!"); } private static void ForceEnemyRedetection() { Plugin.Log.LogInfo((object)"[DEBUG] ForceEnemyRedetection: Starting..."); HealthManager[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); int num = 0; int num2 = 0; HealthManager[] array2 = array; foreach (HealthManager val in array2) { if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy) { continue; } Collider2D[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Collider2D val2 in componentsInChildren) { string text = ((Object)((Component)val2).gameObject).name.ToLower(); if ((text.Contains("alert") || text.Contains("wake") || text.Contains("range") || text.Contains("detect") || text.Contains("sense")) && val2.isTrigger) { bool enabled = ((Behaviour)val2).enabled; ((Behaviour)val2).enabled = false; ((Behaviour)val2).enabled = enabled; num++; } } Crawler component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled) { try { component.StopCrawling(); component.StartCrawling(); num2++; Plugin.Log.LogInfo((object)("[DEBUG] Restarted Crawler on " + ((Object)((Component)val).gameObject).name)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to restart Crawler on " + ((Object)((Component)val).gameObject).name + ": " + ex.Message)); } } PlayMakerFSM[] components = ((Component)val).GetComponents(); foreach (PlayMakerFSM val3 in components) { if (val3.FsmName == "Control" && ((Behaviour)val3).enabled) { val3.SendEvent("FINISHED"); } } DamageHero component2 = ((Component)val).GetComponent(); if ((Object)(object)component2 != (Object)null && ((Behaviour)component2).enabled) { ((Behaviour)component2).enabled = false; ((Behaviour)component2).enabled = true; Plugin.Log.LogInfo((object)("[DEBUG] Toggled DamageHero on " + ((Object)((Component)val).gameObject).name)); } Collider2D component3 = ((Component)val).GetComponent(); if ((Object)(object)component3 != (Object)null && ((Behaviour)component3).enabled) { ((Behaviour)component3).enabled = false; ((Behaviour)component3).enabled = true; } } Plugin.Log.LogInfo((object)$"[DEBUG] ForceEnemyRedetection: Toggled {num} alert triggers, restarted {num2} crawlers"); } public static void DeleteState(SaveStateData state) { if (_saveStates.Remove(state)) { SaveStatesToDisk(); SaveStateManager.OnStatesChanged?.Invoke(); } } private static void ApplyStateImmediate(SaveStateData state) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)Plugin.Hero == (Object)null) { return; } HeroController hero = Plugin.Hero; ((Component)hero).transform.position = state.Position; ((Component)hero).GetComponent().linearVelocity = Vector2.zero; ((Component)hero).GetComponent().bodyType = (RigidbodyType2D)0; hero.AffectedByGravity(true); ((Component)hero).GetComponent().gravityScale = 0.79f; if (state.FacingRight) { hero.FaceRight(); } else { hero.FaceLeft(); } hero.cState.transitioning = false; hero.cState.dead = false; hero.cState.hazardDeath = false; hero.cState.recoiling = false; hero.cState.shadowDashing = false; hero.transitionState = (HeroTransitionState)0; hero.SetDamageMode((DamageMode)0); HeroBox.Inactive = false; Plugin.Log.LogInfo((object)"[DEBUG] Reset HeroBox.Inactive = false"); hero.cState.invulnerable = false; hero.cState.ClearInvulnerabilitySources(); Plugin.Log.LogInfo((object)"[DEBUG] Cleared cState invulnerability sources"); HeroInvincibilitySource.Clear(); Plugin.Log.LogInfo((object)$"[DEBUG] HeroInvincibilitySource.Clear(), IsActive={HeroInvincibilitySource.IsActive}"); hero.parryInvulnTimer = 0f; hero.cState.downspikeInvulnerabilitySteps = 0; if (!CheatSystem.UserInvincible && !CheatSystem.NoclipEnabled) { Plugin.PD.isInvincible = false; } MethodInfo method = typeof(HeroController).GetMethod("FinishedEnteringScene", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { method.Invoke(hero, new object[2] { true, false }); } try { GameManager.instance.FinishedEnteringScene(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to call GM.FinishedEnteringScene: " + ex.Message)); } ((Renderer)((Component)hero).GetComponent()).enabled = true; Collider2D component = ((Component)hero).GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = true; } hero.StartAnimationControl(); HeroAnimationController component2 = ((Component)hero).GetComponent(); if (state.IsGrounded) { hero.cState.onGround = true; component2.PlayClip("Idle"); object? obj = typeof(HeroController).GetField("proxyFSM", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(hero); object? obj2 = ((obj is PlayMakerFSM) ? obj : null); if (obj2 != null) { ((PlayMakerFSM)obj2).SendEvent("HeroCtrl-Idle"); } } else { hero.cState.onGround = false; component2.PlayClip("Fall"); } hero.AcceptInput(); Plugin.Log.LogInfo((object)"========== HERO DEBUG LOG =========="); Plugin.Log.LogInfo((object)$"Hero Layer: {((Component)hero).gameObject.layer} (LayerMask.LayerToName: {LayerMask.LayerToName(((Component)hero).gameObject.layer)})"); Plugin.Log.LogInfo((object)("Hero Tag: " + ((Component)hero).gameObject.tag)); Plugin.Log.LogInfo((object)$"Hero Active: {((Component)hero).gameObject.activeInHierarchy}"); Plugin.Log.LogInfo((object)$"Hero Position: {((Component)hero).transform.position}"); Plugin.Log.LogInfo((object)$"cState.transitioning: {hero.cState.transitioning}"); Plugin.Log.LogInfo((object)$"cState.dead: {hero.cState.dead}"); Plugin.Log.LogInfo((object)$"cState.hazardDeath: {hero.cState.hazardDeath}"); Plugin.Log.LogInfo((object)$"cState.Invulnerable: {hero.cState.Invulnerable}"); Plugin.Log.LogInfo((object)$"transitionState: {hero.transitionState}"); Plugin.Log.LogInfo((object)$"damageMode: {hero.damageMode}"); Plugin.Log.LogInfo((object)$"isInvincible (PD): {Plugin.PD?.isInvincible}"); Collider2D[] components = ((Component)hero).GetComponents(); Plugin.Log.LogInfo((object)$"Hero Colliders ({components.Length}):"); Collider2D[] array = components; foreach (Collider2D val in array) { Plugin.Log.LogInfo((object)$" - {((object)val).GetType().Name}: enabled={((Behaviour)val).enabled}, isTrigger={val.isTrigger}"); } if ((Object)(object)hero.heroBox != (Object)null) { Plugin.Log.LogInfo((object)$"HeroBox: active={((Component)hero.heroBox).gameObject.activeInHierarchy}"); Collider2D component3 = ((Component)hero.heroBox).GetComponent(); if ((Object)(object)component3 != (Object)null) { Plugin.Log.LogInfo((object)$" HeroBox Collider: enabled={((Behaviour)component3).enabled}, isTrigger={component3.isTrigger}"); } } Plugin.Log.LogInfo((object)"Hero Child Colliders:"); array = ((Component)hero).GetComponentsInChildren(true); foreach (Collider2D val2 in array) { if ((Object)(object)((Component)val2).gameObject != (Object)(object)((Component)hero).gameObject) { Plugin.Log.LogInfo((object)$" - {((Object)((Component)val2).gameObject).name}: enabled={((Behaviour)val2).enabled}, active={((Component)val2).gameObject.activeInHierarchy}"); } } Plugin.Log.LogInfo((object)"========== END HERO DEBUG LOG =========="); Plugin.Log.LogInfo((object)"[DEBUG] ApplyStateImmediate: Reset damageMode=FULL_DAMAGE, transitioning=false"); } catch (Exception ex2) { Plugin.Log.LogError((object)("Failed to apply state: " + ex2.Message)); } } private static void SaveStatesToDisk() { try { string contents = JsonConvert.SerializeObject((object)_saveStates, (Formatting)1); File.WriteAllText(_saveFilePath, contents); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to save states to disk: " + ex.Message)); } } private static void LoadStatesFromDisk() { if (!File.Exists(_saveFilePath)) { return; } try { List list = JsonConvert.DeserializeObject>(File.ReadAllText(_saveFilePath)); if (list != null) { _saveStates = list; } } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to load states from disk: " + ex.Message)); } } private static void LogAllEnemiesDetailed(string context) { //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Expected O, but got Unknown Plugin.Log.LogInfo((object)("========== ENEMY DEBUG LOG: " + context + " ==========")); HealthManager[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); Plugin.Log.LogInfo((object)$"Total enemies found: {array.Length}"); HealthManager[] array2 = array; foreach (HealthManager val in array2) { if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null) { continue; } GameObject gameObject = ((Component)val).gameObject; Plugin.Log.LogInfo((object)("--- ENEMY: " + ((Object)gameObject).name + " ---")); Plugin.Log.LogInfo((object)(" Path: " + GetGameObjectPath(gameObject))); Plugin.Log.LogInfo((object)$" Active: {gameObject.activeInHierarchy} (self={gameObject.activeSelf})"); Plugin.Log.LogInfo((object)$" HP: {val.hp}, IsDead: {val.isDead}, IsInvincible: {val.IsInvincible}"); Plugin.Log.LogInfo((object)$" Position: {gameObject.transform.position}"); Component[] components = gameObject.GetComponents(); Plugin.Log.LogInfo((object)$" Components ({components.Length}):"); Component[] array3 = components; foreach (Component val2 in array3) { if ((Object)(object)val2 == (Object)null) { continue; } string text = ""; Behaviour val3 = (Behaviour)(object)((val2 is Behaviour) ? val2 : null); if (val3 != null) { text = $" [enabled={val3.enabled}]"; } else { Collider2D val4 = (Collider2D)(object)((val2 is Collider2D) ? val2 : null); if (val4 != null) { text = $" [enabled={((Behaviour)val4).enabled}]"; } else { Renderer val5 = (Renderer)(object)((val2 is Renderer) ? val2 : null); if (val5 != null) { text = $" [enabled={val5.enabled}]"; } } } Plugin.Log.LogInfo((object)(" - " + ((object)val2).GetType().Name + text)); } PlayMakerFSM[] components2 = gameObject.GetComponents(); if (components2.Length != 0) { Plugin.Log.LogInfo((object)$" FSMs ({components2.Length}):"); PlayMakerFSM[] array4 = components2; foreach (PlayMakerFSM val6 in array4) { Plugin.Log.LogInfo((object)$" - {val6.FsmName}: state='{val6.ActiveStateName}', enabled={((Behaviour)val6).enabled}"); if (val6.FsmVariables == null) { continue; } FsmBool[] boolVariables = val6.FsmVariables.BoolVariables; foreach (FsmBool val7 in boolVariables) { if (((NamedVariable)val7).Name.Contains("Spawn") || ((NamedVariable)val7).Name.Contains("Active") || ((NamedVariable)val7).Name.Contains("Dead") || ((NamedVariable)val7).Name.Contains("Alert") || ((NamedVariable)val7).Name.Contains("Hero") || ((NamedVariable)val7).Name.Contains("Seen")) { Plugin.Log.LogInfo((object)$" {((NamedVariable)val7).Name} = {val7.Value}"); } } } } Plugin.Log.LogInfo((object)$" Children ({gameObject.transform.childCount}):"); foreach (Transform item in gameObject.transform) { Transform val8 = item; string text2 = (((Component)val8).gameObject.activeInHierarchy ? "active" : "INACTIVE"); Plugin.Log.LogInfo((object)(" - " + ((Object)val8).name + " [" + text2 + "]")); } } Plugin.Log.LogInfo((object)"========== END ENEMY DEBUG LOG =========="); } private static List CaptureEnemyStates() { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Invalid comparison between Unknown and I4 LogAllEnemiesDetailed("BEFORE CAPTURE"); List list = new List(); HealthManager[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); Plugin.Log.LogInfo((object)$"[DEBUG] CaptureEnemyStates: Found {array.Length} enemies (including inactive)"); HealthManager[] array2 = array; foreach (HealthManager val in array2) { if ((Object)(object)((Component)val).gameObject == (Object)null) { continue; } EnemyStateData enemyStateData = new EnemyStateData(); enemyStateData.GameObjectName = ((Object)((Component)val).gameObject).name; enemyStateData.GameObjectPath = GetGameObjectPath(((Component)val).gameObject); enemyStateData.IsActive = ((Component)val).gameObject.activeInHierarchy; enemyStateData.HP = val.hp; enemyStateData.IsDead = val.isDead; enemyStateData.IsInvincible = val.IsInvincible; enemyStateData.InvincibleFromDirection = val.InvincibleFromDirection; enemyStateData.Position = ((Component)val).transform.position; enemyStateData.Rotation = ((Component)val).transform.rotation; enemyStateData.Scale = ((Component)val).transform.localScale; Rigidbody2D component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { enemyStateData.Velocity = component.linearVelocity; enemyStateData.AngularVelocity = component.angularVelocity; enemyStateData.IsKinematic = (int)component.bodyType == 1; } Recoil component2 = ((Component)val).GetComponent(); if ((Object)(object)component2 != (Object)null) { FieldInfo field = typeof(Recoil).GetField("state", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field2 = typeof(Recoil).GetField("recoilTimeRemaining", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { object value = field.GetValue(component2); enemyStateData.IsRecoiling = (int)value == 2; } if (field2 != null) { enemyStateData.RecoilTimeRemaining = (float)field2.GetValue(component2); } } PlayMakerFSM[] components = ((Component)val).GetComponents(); foreach (PlayMakerFSM fsm in components) { enemyStateData.FsmStates.Add(CaptureFsmState(fsm)); } enemyStateData.MainObjectState = CaptureObjectComponentData(((Component)val).gameObject); Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Transform val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)(object)((Component)val).transform)) { string relativePath = GetRelativePath(val2, ((Component)val).transform); enemyStateData.ChildStates[relativePath] = CaptureObjectComponentData(((Component)val2).gameObject); } } list.Add(enemyStateData); } return list; } private static FsmStateData CaptureFsmState(PlayMakerFSM fsm) { //IL_0135: Unknown result type (might be due to invalid IL or missing references) FsmStateData fsmStateData = new FsmStateData(); fsmStateData.FsmName = fsm.FsmName; fsmStateData.ActiveStateName = fsm.ActiveStateName; if (fsm.FsmVariables != null) { FsmBool[] boolVariables = fsm.FsmVariables.BoolVariables; foreach (FsmBool val in boolVariables) { fsmStateData.BoolVariables[((NamedVariable)val).Name] = val.Value; } FsmInt[] intVariables = fsm.FsmVariables.IntVariables; foreach (FsmInt val2 in intVariables) { fsmStateData.IntVariables[((NamedVariable)val2).Name] = val2.Value; } FsmFloat[] floatVariables = fsm.FsmVariables.FloatVariables; foreach (FsmFloat val3 in floatVariables) { fsmStateData.FloatVariables[((NamedVariable)val3).Name] = val3.Value; } FsmString[] stringVariables = fsm.FsmVariables.StringVariables; foreach (FsmString val4 in stringVariables) { fsmStateData.StringVariables[((NamedVariable)val4).Name] = val4.Value; } FsmVector3[] vector3Variables = fsm.FsmVariables.Vector3Variables; foreach (FsmVector3 val5 in vector3Variables) { fsmStateData.Vector3Variables[((NamedVariable)val5).Name] = val5.Value; } } return fsmStateData; } private static BattleSceneStateData CaptureBattleSceneState() { BattleScene val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null) { return null; } BattleSceneStateData battleSceneStateData = new BattleSceneStateData(); battleSceneStateData.GameObjectPath = GetGameObjectPath(((Component)val).gameObject); battleSceneStateData.CurrentWave = val.currentWave; battleSceneStateData.CurrentEnemies = val.currentEnemies; battleSceneStateData.EnemiesToNext = val.enemiesToNext; FieldInfo field = typeof(BattleScene).GetField("started", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { battleSceneStateData.Started = (bool)(field.GetValue(val) ?? ((object)false)); } Plugin.Log.LogInfo((object)$"[DEBUG] Captured BattleScene: wave={battleSceneStateData.CurrentWave}, enemies={battleSceneStateData.CurrentEnemies}, started={battleSceneStateData.Started}"); return battleSceneStateData; } private static BossSceneStateData CaptureBossSceneState() { BossSceneController val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null) { return null; } return new BossSceneStateData { IsActive = true, BossLevel = val.BossLevel, HasTransitionedIn = val.HasTransitionedIn }; } private static void RestoreEnemyStates(List enemyStates) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_045b: Unknown result type (might be due to invalid IL or missing references) //IL_0462: Expected O, but got Unknown if (enemyStates == null) { return; } LogAllEnemiesDetailed("BEFORE RESTORE"); HealthManager[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); Plugin.Log.LogInfo((object)$"[DEBUG] RestoreEnemyStates: Found {array.Length} enemies to restore from {enemyStates.Count} saved states"); foreach (EnemyStateData state in enemyStates) { HealthManager val = ((IEnumerable)array).FirstOrDefault((Func)((HealthManager e) => GetGameObjectPath(((Component)e).gameObject) == state.GameObjectPath)); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("Could not find enemy to restore: " + state.GameObjectPath)); continue; } ((Component)val).gameObject.SetActive(state.IsActive); Plugin.Log.LogInfo((object)$"[DEBUG] Restored enemy '{state.GameObjectName}' active={state.IsActive}"); val.hp = state.HP; val.isDead = state.IsDead; val.IsInvincible = state.IsInvincible; val.InvincibleFromDirection = state.InvincibleFromDirection; ((Component)val).transform.position = state.Position; ((Component)val).transform.rotation = state.Rotation; ((Component)val).transform.localScale = state.Scale; Rigidbody2D component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { component.linearVelocity = state.Velocity; component.angularVelocity = state.AngularVelocity; if (state.IsKinematic) { component.bodyType = (RigidbodyType2D)1; } } Recoil component2 = ((Component)val).GetComponent(); if ((Object)(object)component2 != (Object)null) { if (state.IsRecoiling) { typeof(Recoil).GetField("state", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(component2, 2); typeof(Recoil).GetField("recoilTimeRemaining", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(component2, state.RecoilTimeRemaining); } else { typeof(Recoil).GetField("state", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(component2, 0); component2.CancelRecoil(); } } PlayMakerFSM[] components = ((Component)val).GetComponents(); foreach (FsmStateData fsmData in state.FsmStates) { PlayMakerFSM val2 = ((IEnumerable)components).FirstOrDefault((Func)((PlayMakerFSM f) => f.FsmName == fsmData.FsmName)); if ((Object)(object)val2 != (Object)null) { RestoreFsmState(val2, fsmData); } } if (state.MainObjectState != null) { RestoreObjectComponentData(((Component)val).gameObject, state.MainObjectState); } if (state.ChildStates != null && state.ChildStates.Count > 0) { foreach (KeyValuePair childState in state.ChildStates) { string key = childState.Key; Transform val3 = ((Component)val).transform.Find(key); if ((Object)(object)val3 != (Object)null) { RestoreObjectComponentData(((Component)val3).gameObject, childState.Value); continue; } Plugin.Log.LogError((object)("[ERROR] Could not find child '" + key + "' on '" + state.GameObjectName + "' to restore state.")); } Plugin.Log.LogInfo((object)$"[DEBUG] Restored full state for {state.ChildStates.Count} child objects on {state.GameObjectName}"); } else if (state.ChildObjectStates != null && state.ChildObjectStates.Count > 0) { foreach (Transform item in ((Component)val).transform) { Transform val4 = item; if (state.ChildObjectStates.TryGetValue(((Object)val4).name, out var value)) { ((Component)val4).gameObject.SetActive(value); } } Plugin.Log.LogInfo((object)$"[DEBUG] Restored (legacy) active state for {state.ChildObjectStates.Count} child objects on {state.GameObjectName}"); } if (state.IsDead) { ((Component)val).gameObject.SetActive(false); } } HashSet hashSet = new HashSet(enemyStates.Select((EnemyStateData s) => s.GameObjectPath)); HealthManager[] array2 = array; foreach (HealthManager val5 in array2) { string gameObjectPath = GetGameObjectPath(((Component)val5).gameObject); if (!hashSet.Contains(gameObjectPath) && ((Component)val5).gameObject.activeInHierarchy) { Plugin.Log.LogInfo((object)("[DEBUG] Deactivating enemy not in save: " + ((Object)((Component)val5).gameObject).name)); ((Component)val5).gameObject.SetActive(false); } } LogAllEnemiesDetailed("AFTER RESTORE"); } private static void RestoreFsmState(PlayMakerFSM fsm, FsmStateData data) { //IL_01d7: Unknown result type (might be due to invalid IL or missing references) Plugin.Log.LogInfo((object)("[DEBUG] RestoreFsmState: " + ((Object)((Component)fsm).gameObject).name + "/" + fsm.FsmName + " -> target state '" + data.ActiveStateName + "'")); if (fsm.FsmVariables != null) { int num = 0; foreach (KeyValuePair boolVariable in data.BoolVariables) { fsm.FsmVariables.GetFsmBool(boolVariable.Key).Value = boolVariable.Value; num++; } foreach (KeyValuePair intVariable in data.IntVariables) { fsm.FsmVariables.GetFsmInt(intVariable.Key).Value = intVariable.Value; num++; } foreach (KeyValuePair floatVariable in data.FloatVariables) { fsm.FsmVariables.GetFsmFloat(floatVariable.Key).Value = floatVariable.Value; num++; } foreach (KeyValuePair stringVariable in data.StringVariables) { fsm.FsmVariables.GetFsmString(stringVariable.Key).Value = stringVariable.Value; num++; } foreach (KeyValuePair vector3Variable in data.Vector3Variables) { fsm.FsmVariables.GetFsmVector3(vector3Variable.Key).Value = vector3Variable.Value; num++; } Plugin.Log.LogInfo((object)$"[DEBUG] Restored {num} FSM variables"); if (fsm.FsmName == "Control") { FsmBool fsmBool = fsm.FsmVariables.GetFsmBool("Spawned"); if (fsmBool != null) { Plugin.Log.LogInfo((object)$"[DEBUG] Found 'Spawned' variable, current={fsmBool.Value}, forcing to true"); fsmBool.Value = true; } FsmBool fsmBool2 = fsm.FsmVariables.GetFsmBool("Done First Spawn"); if (fsmBool2 != null && !fsmBool2.Value) { Plugin.Log.LogInfo((object)$"[DEBUG] Found 'Done First Spawn' variable, current={fsmBool2.Value}, forcing to true"); fsmBool2.Value = true; } } } if (string.IsNullOrEmpty(data.ActiveStateName)) { return; } try { string activeStateName = fsm.ActiveStateName; Plugin.Log.LogInfo((object)("[DEBUG] FSM current state: '" + activeStateName + "', target: '" + data.ActiveStateName + "'")); if (fsm.FsmName == "Control") { if ((data.ActiveStateName.ToLower().Contains("walk") || data.ActiveStateName.ToLower().Contains("start") || data.ActiveStateName.ToLower().Contains("idle") || data.ActiveStateName.ToLower().Contains("attack") || data.ActiveStateName.ToLower().Contains("chase")) && (activeStateName.ToLower().Contains("hid") || activeStateName.ToLower().Contains("sleep") || activeStateName.ToLower().Contains("wait"))) { Plugin.Log.LogInfo((object)("[DEBUG] Enemy was awake (state=" + data.ActiveStateName + "), sending ALERT to wake up naturally")); fsm.SendEvent("ALERT"); fsm.SendEvent("WAKE"); fsm.SendEvent("ACTIVATE"); } else { fsm.Fsm.SetState(data.ActiveStateName); Plugin.Log.LogInfo((object)("[DEBUG] Set FSM state to '" + data.ActiveStateName + "', new active: '" + fsm.ActiveStateName + "'")); } try { FieldInfo field = ((object)fsm.Fsm).GetType().GetField("ActiveState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object value = field.GetValue(fsm.Fsm); if (value != null) { FieldInfo field2 = value.GetType().GetField("Actions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 != null && field2.GetValue(value) is Array array) { foreach (object item in array) { item?.GetType().GetMethod("OnEnter", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(item, null); } Plugin.Log.LogInfo((object)$"[DEBUG] Triggered OnEnter for {array.Length} actions in state '{data.ActiveStateName}'"); } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[DEBUG] Could not run state entry actions: " + ex.Message)); } Animator component = ((Component)fsm).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { component.Play(data.ActiveStateName, -1, 0f); Plugin.Log.LogInfo((object)("[DEBUG] Triggered Animator.Play('" + data.ActiveStateName + "')")); } } else { fsm.Fsm.SetState(data.ActiveStateName); Plugin.Log.LogInfo((object)("[DEBUG] Set FSM state to '" + data.ActiveStateName + "', new active: '" + fsm.ActiveStateName + "'")); } } catch (Exception ex2) { Plugin.Log.LogError((object)("Failed to set FSM state " + data.ActiveStateName + " on " + ((Object)fsm).name + ": " + ex2.Message)); } } private static void ForceSavePersistentItems() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) PersistentBoolItem[] array = Object.FindObjectsOfType(); Plugin.Log.LogInfo((object)$"[DEBUG] ForceSavePersistentItems: Found {array.Length} items"); int num = 0; PersistentBoolItem[] array2 = array; foreach (PersistentBoolItem val in array2) { try { ((PersistentItem)(object)val).SaveStateNoCondition(); num++; string text = ((PersistentItem)(object)val).GetId(); string text2 = ((PersistentItem)(object)val).GetSceneName(); if (string.IsNullOrEmpty(text)) { text = ((Object)val).name; } if (string.IsNullOrEmpty(text2)) { Scene scene = ((Component)val).gameObject.scene; text2 = GameManager.GetBaseSceneName(((Scene)(ref scene)).name); } bool valueOrDefault = SceneData.instance.PersistentBools.GetValueOrDefault(text2, text); Plugin.Log.LogInfo((object)$"[DEBUG] Saved '{((Object)val).name}' (scene={text2}, id={text}) = {valueOrDefault}"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to save persistent item " + ((Object)val).name + ": " + ex.Message)); } } Plugin.Log.LogInfo((object)$"[DEBUG] ForceSavePersistentItems: Saved {num} items"); } private static void RestorePersistentBoolItems() { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) PersistentBoolItem[] array = Object.FindObjectsOfType(); int num = 0; int num2 = 0; Type? baseType = typeof(PersistentBoolItem).BaseType; FieldInfo fieldInfo = baseType?.GetField("started", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo fieldInfo2 = baseType?.GetField("hasSetup", BindingFlags.Instance | BindingFlags.NonPublic); Plugin.Log.LogInfo((object)$"[DEBUG] Found {array.Length} PersistentBoolItems to process"); Plugin.Log.LogInfo((object)$"[DEBUG] startedField found: {fieldInfo != null}, hasSetupField found: {fieldInfo2 != null}"); PersistentBoolItem[] array2 = array; foreach (PersistentBoolItem val in array2) { try { string text = ((PersistentItem)(object)val).GetId(); string text2 = ((PersistentItem)(object)val).GetSceneName(); if (string.IsNullOrEmpty(text)) { text = ((Object)val).name; } if (string.IsNullOrEmpty(text2)) { Scene scene = ((Component)val).gameObject.scene; text2 = GameManager.GetBaseSceneName(((Scene)(ref scene)).name); } bool valueOrDefault = SceneData.instance.PersistentBools.GetValueOrDefault(text2, text); Plugin.Log.LogInfo((object)$"[DEBUG] PersistentBoolItem '{((Object)val).name}' (scene={text2}, id={text}): SceneData value = {valueOrDefault}"); if (valueOrDefault) { val.SetValueOverride(true); num2++; Plugin.Log.LogInfo((object)("[DEBUG] Applied SetValueOverride(true) to '" + ((Object)val).name + "'")); } num++; } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to restore persistent item " + ((Object)val).name + ": " + ex.Message)); } } Plugin.Log.LogInfo((object)$"[DEBUG] Restored {num} PersistentBoolItems, {num2} had true value in SceneData"); } private static void RestoreBattleSceneState(BattleSceneStateData data) { if (data == null) { return; } BattleScene val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null) { return; } Type typeFromHandle = typeof(BattleScene); val.currentWave = data.CurrentWave; val.currentEnemies = data.CurrentEnemies; val.enemiesToNext = data.EnemiesToNext; if (data.Started || data.CurrentWave > 0) { FieldInfo field = typeFromHandle.GetField("started", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { field.SetValue(val, true); Plugin.Log.LogInfo((object)"[DEBUG] Set BattleScene.started = true"); } BoxCollider2D component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } PolygonCollider2D component2 = ((Component)val).GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Behaviour)component2).enabled = false; } val.LockInBattle(); Plugin.Log.LogInfo((object)"[DEBUG] Called BattleScene.LockInBattle() to close gates"); } } private static void RestoreBossSceneState(BossSceneStateData data) { if (data != null && data.IsActive) { BossSceneController val = Object.FindObjectOfType(); if (!((Object)(object)val == (Object)null)) { val.BossLevel = data.BossLevel; } } } private static void RestoreObjectComponentData(GameObject obj, ObjectComponentData data) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (data == null) { return; } obj.SetActive(data.IsActive); if (data.Transform != null) { obj.transform.localPosition = data.Transform.LocalPosition; obj.transform.localRotation = data.Transform.LocalRotation; obj.transform.localScale = data.Transform.LocalScale; } if (data.SpriteRenderer != null) { SpriteRenderer component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).enabled = data.SpriteRenderer.Enabled; component.color = data.SpriteRenderer.Color; ((Renderer)component).sortingOrder = data.SpriteRenderer.SortingOrder; ((Renderer)component).sortingLayerName = data.SpriteRenderer.SortingLayerName; } } if (data.MeshRenderer != null) { MeshRenderer component2 = obj.GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Renderer)component2).enabled = data.MeshRenderer.Enabled; ((Renderer)component2).sortingOrder = data.MeshRenderer.SortingOrder; ((Renderer)component2).sortingLayerName = data.MeshRenderer.SortingLayerName; } } if (data.SkinnedMeshRenderer != null) { SkinnedMeshRenderer component3 = obj.GetComponent(); if ((Object)(object)component3 != (Object)null) { ((Renderer)component3).enabled = data.SkinnedMeshRenderer.Enabled; ((Renderer)component3).sortingOrder = data.SkinnedMeshRenderer.SortingOrder; ((Renderer)component3).sortingLayerName = data.SkinnedMeshRenderer.SortingLayerName; } } if (data.Animator != null) { Animator component4 = obj.GetComponent(); if ((Object)(object)component4 != (Object)null) { ((Behaviour)component4).enabled = data.Animator.Enabled; if (data.Animator.Enabled) { component4.Play(data.Animator.StateHash, 0, data.Animator.NormalizedTime); component4.speed = data.Animator.Speed; } } } if (data.Collider2D != null) { Collider2D component5 = obj.GetComponent(); if ((Object)(object)component5 != (Object)null) { ((Behaviour)component5).enabled = data.Collider2D.Enabled; component5.isTrigger = data.Collider2D.IsTrigger; } } } private static ObjectComponentData CaptureObjectComponentData(GameObject obj) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) ObjectComponentData objectComponentData = new ObjectComponentData(); objectComponentData.IsActive = obj.activeSelf; objectComponentData.Transform = new TransformData { LocalPosition = obj.transform.localPosition, LocalRotation = obj.transform.localRotation, LocalScale = obj.transform.localScale }; SpriteRenderer component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { objectComponentData.SpriteRenderer = new SpriteRendererData { Enabled = ((Renderer)component).enabled, Color = component.color, SortingOrder = ((Renderer)component).sortingOrder, SortingLayerName = ((Renderer)component).sortingLayerName, SpriteName = (((Object)(object)component.sprite != (Object)null) ? ((Object)component.sprite).name : "null") }; } MeshRenderer component2 = obj.GetComponent(); if ((Object)(object)component2 != (Object)null) { objectComponentData.MeshRenderer = new MeshRendererData { Enabled = ((Renderer)component2).enabled, SortingLayerName = ((Renderer)component2).sortingLayerName, SortingOrder = ((Renderer)component2).sortingOrder }; } SkinnedMeshRenderer component3 = obj.GetComponent(); if ((Object)(object)component3 != (Object)null) { objectComponentData.SkinnedMeshRenderer = new SkinnedMeshRendererData { Enabled = ((Renderer)component3).enabled, SortingLayerName = ((Renderer)component3).sortingLayerName, SortingOrder = ((Renderer)component3).sortingOrder }; } Animator component4 = obj.GetComponent(); if ((Object)(object)component4 != (Object)null && (Object)(object)component4.runtimeAnimatorController != (Object)null) { AnimatorStateInfo currentAnimatorStateInfo = component4.GetCurrentAnimatorStateInfo(0); objectComponentData.Animator = new AnimatorData { Enabled = ((Behaviour)component4).enabled, StateHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash, NormalizedTime = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime, Speed = component4.speed }; } Collider2D component5 = obj.GetComponent(); if ((Object)(object)component5 != (Object)null) { objectComponentData.Collider2D = new ColliderData { Enabled = ((Behaviour)component5).enabled, IsTrigger = component5.isTrigger }; } string text = $"[DEBUG] Captured '{((Object)obj).name}': active={objectComponentData.IsActive}"; if (objectComponentData.SpriteRenderer != null) { text += $", SR[en={objectComponentData.SpriteRenderer.Enabled}, sort={objectComponentData.SpriteRenderer.SortingOrder}, sprite={objectComponentData.SpriteRenderer.SpriteName}]"; } if (objectComponentData.MeshRenderer != null) { text += $", MR[en={objectComponentData.MeshRenderer.Enabled}, sort={objectComponentData.MeshRenderer.SortingOrder}]"; } if (objectComponentData.SkinnedMeshRenderer != null) { text += $", SMR[en={objectComponentData.SkinnedMeshRenderer.Enabled}, sort={objectComponentData.SkinnedMeshRenderer.SortingOrder}]"; } if (objectComponentData.Animator != null) { text += $", Anim[en={objectComponentData.Animator.Enabled}, hash={objectComponentData.Animator.StateHash}]"; } if (objectComponentData.Collider2D != null) { text += $", Col[en={objectComponentData.Collider2D.Enabled}]"; } Plugin.Log.LogInfo((object)text); return objectComponentData; } private static string GetRelativePath(Transform child, Transform root) { if ((Object)(object)child == (Object)(object)root) { return ""; } string text = ((Object)child).name; Transform parent = child.parent; while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private static string GetGameObjectPath(GameObject obj) { string text = "/" + ((Object)obj).name; while ((Object)(object)obj.transform.parent != (Object)null) { obj = ((Component)obj.transform.parent).gameObject; text = "/" + ((Object)obj).name + text; } return text; } public static bool FindEntryPointPatch(GameManager __instance, ref Vector2? __result, string entryPointName) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (_pendingLoadState != null && entryPointName == "dreamGate") { __result = Vector2.op_Implicit(_pendingLoadState.Position); return false; } return true; } } } namespace SilksongManager.Player { public static class CheatSystem { private static bool _infiniteJumps = false; private static bool _infiniteHealth = false; private static bool _infiniteSilk = false; private static bool _noclipEnabled = false; private static bool _userInvincible = false; private static Vector3 _noclipPos; private static float _originalGravityScale = 1f; private static int _lastHealth = 0; private static int _lastSilk = 0; private static FieldInfo _doubleJumpedField; private static bool _reflectionInitialized = false; private static ConfigEntry _infiniteJumpsConfig; private static ConfigEntry _infiniteHealthConfig; private static ConfigEntry _infiniteSilkConfig; private static ConfigEntry _userInvincibleConfig; private static ConfigEntry _noclipSpeedConfig; private static ConfigEntry _noclipBoostSpeedConfig; public static bool InfiniteJumps => _infiniteJumps; public static bool InfiniteHealth => _infiniteHealth; public static bool InfiniteSilk => _infiniteSilk; public static bool NoclipEnabled => _noclipEnabled; public static bool UserInvincible => _userInvincible; public static float NoclipSpeed { get { return _noclipSpeedConfig?.Value ?? 15f; } set { if (_noclipSpeedConfig != null) { _noclipSpeedConfig.Value = value; } } } public static float NoclipBoostSpeed { get { return _noclipBoostSpeedConfig?.Value ?? 30f; } set { if (_noclipBoostSpeedConfig != null) { _noclipBoostSpeedConfig.Value = value; } } } public static void Initialize(ConfigFile config) { _infiniteJumpsConfig = config.Bind("Cheats", "InfiniteJumps", false, "Enable infinite jumps"); _infiniteHealthConfig = config.Bind("Cheats", "InfiniteHealth", false, "Enable infinite health"); _infiniteSilkConfig = config.Bind("Cheats", "InfiniteSilk", false, "Enable infinite silk"); _userInvincibleConfig = config.Bind("Cheats", "UserInvincible", false, "User-enabled invincibility"); _noclipSpeedConfig = config.Bind("Cheats", "NoclipSpeed", 15f, "Noclip normal movement speed"); _noclipBoostSpeedConfig = config.Bind("Cheats", "NoclipBoostSpeed", 30f, "Noclip boost movement speed"); _infiniteJumps = _infiniteJumpsConfig.Value; _infiniteHealth = _infiniteHealthConfig.Value; _infiniteSilk = _infiniteSilkConfig.Value; _userInvincible = _userInvincibleConfig.Value; InitializeReflection(); } private static void InitializeReflection() { if (_reflectionInitialized) { return; } try { _doubleJumpedField = typeof(HeroController).GetField("doubleJumped", BindingFlags.Instance | BindingFlags.NonPublic); if (_doubleJumpedField != null) { Plugin.Log.LogInfo((object)"CheatSystem: Found HeroController.doubleJumped field"); } else { Plugin.Log.LogWarning((object)"CheatSystem: Could not find HeroController.doubleJumped field"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("CheatSystem reflection init failed: " + ex.Message)); } _reflectionInitialized = true; } public static void Update() { HeroController hero = Plugin.Hero; PlayerData pD = Plugin.PD; if (!((Object)(object)hero == (Object)null) && pD != null) { if (_infiniteJumps) { ProcessInfiniteJumps(hero); } if (_infiniteHealth) { ProcessInfiniteHealth(pD); } else { _lastHealth = pD.health; } if (_infiniteSilk) { ProcessInfiniteSilk(pD); } else { _lastSilk = pD.silk; } if (_userInvincible || _noclipEnabled) { pD.isInvincible = true; } if (_noclipEnabled) { ProcessNoclipMovement(hero); } } } private static void ProcessInfiniteJumps(HeroController hero) { hero.cState.onGround = true; if (_doubleJumpedField != null) { try { _doubleJumpedField.SetValue(hero, false); } catch { } } } private static void ProcessInfiniteHealth(PlayerData pd) { if (pd.health < _lastHealth && pd.health > 0) { pd.health = _lastHealth; } else { _lastHealth = pd.health; } } private static void ProcessInfiniteSilk(PlayerData pd) { if (pd.silk < pd.silkMax) { HeroController hero = Plugin.Hero; if ((Object)(object)hero != (Object)null) { int num = pd.silkMax - pd.silk; hero.AddSilk(num, false); } } _lastSilk = pd.silk; } private static void ProcessNoclipMovement(HeroController hero) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) Rigidbody2D component = ((Component)hero).GetComponent(); if ((Object)(object)component == (Object)null) { return; } InputHandler instance = ManagerSingleton.Instance; if (!((Object)(object)instance == (Object)null) && instance.inputActions != null) { float num = NoclipSpeed; if (ModKeybindManager.IsKeyHeld(ModAction.NoclipSpeedBoost)) { num = NoclipBoostSpeed; } float num2 = num * Time.deltaTime; Vector3 val = Vector3.zero; if (((OneAxisInputControl)instance.inputActions.Left).IsPressed) { val += Vector3.left * num2; } if (((OneAxisInputControl)instance.inputActions.Right).IsPressed) { val += Vector3.right * num2; } if (((OneAxisInputControl)instance.inputActions.Up).IsPressed) { val += Vector3.up * num2; } if (((OneAxisInputControl)instance.inputActions.Down).IsPressed) { val += Vector3.down * num2; } _noclipPos += val; if ((int)hero.transitionState == 0) { ((Component)hero).transform.position = _noclipPos; component.constraints = (RigidbodyConstraints2D)(component.constraints | 3); } else { _noclipPos = ((Component)hero).transform.position; component.constraints = (RigidbodyConstraints2D)(component.constraints & -4); } } } public static void ToggleInfiniteJumps() { _infiniteJumps = !_infiniteJumps; if (_infiniteJumpsConfig != null) { _infiniteJumpsConfig.Value = _infiniteJumps; } Plugin.Log.LogInfo((object)("Infinite Jumps: " + (_infiniteJumps ? "ON" : "OFF"))); } public static void SetInfiniteJumps(bool value) { _infiniteJumps = value; if (_infiniteJumpsConfig != null) { _infiniteJumpsConfig.Value = value; } } public static void ToggleInfiniteHealth() { _infiniteHealth = !_infiniteHealth; if (_infiniteHealthConfig != null) { _infiniteHealthConfig.Value = _infiniteHealth; } PlayerData pD = Plugin.PD; if (_infiniteHealth && pD != null) { _lastHealth = pD.health; } Plugin.Log.LogInfo((object)("Infinite Health: " + (_infiniteHealth ? "ON" : "OFF"))); } public static void SetInfiniteHealth(bool value) { _infiniteHealth = value; if (_infiniteHealthConfig != null) { _infiniteHealthConfig.Value = value; } if (value) { PlayerData pD = Plugin.PD; if (pD != null) { _lastHealth = pD.health; } } } public static void ToggleInfiniteSilk() { _infiniteSilk = !_infiniteSilk; if (_infiniteSilkConfig != null) { _infiniteSilkConfig.Value = _infiniteSilk; } PlayerData pD = Plugin.PD; if (_infiniteSilk && pD != null) { _lastSilk = pD.silk; } Plugin.Log.LogInfo((object)("Infinite Silk: " + (_infiniteSilk ? "ON" : "OFF"))); } public static void SetInfiniteSilk(bool value) { _infiniteSilk = value; if (_infiniteSilkConfig != null) { _infiniteSilkConfig.Value = value; } if (value) { PlayerData pD = Plugin.PD; if (pD != null) { _lastSilk = pD.silk; } } } public static void ToggleUserInvincible() { _userInvincible = !_userInvincible; if (_userInvincibleConfig != null) { _userInvincibleConfig.Value = _userInvincible; } PlayerData pD = Plugin.PD; if (pD != null) { pD.isInvincible = _userInvincible; } Plugin.Log.LogInfo((object)("User Invincible: " + (_userInvincible ? "ON" : "OFF"))); } public static void SetUserInvincible(bool value) { _userInvincible = value; if (_userInvincibleConfig != null) { _userInvincibleConfig.Value = value; } PlayerData pD = Plugin.PD; if (pD != null) { pD.isInvincible = value; } } public static void ToggleNoclip() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) HeroController hero = Plugin.Hero; if ((Object)(object)hero == (Object)null) { return; } _noclipEnabled = !_noclipEnabled; Rigidbody2D component = ((Component)hero).GetComponent(); ((Component)hero).GetComponentsInChildren(); PlayerData pD = Plugin.PD; if (_noclipEnabled) { _noclipPos = ((Component)hero).transform.position; if ((Object)(object)component != (Object)null) { _originalGravityScale = component.gravityScale; } if (pD != null) { pD.isInvincible = true; } } else { if ((Object)(object)component != (Object)null) { component.gravityScale = _originalGravityScale; component.constraints = (RigidbodyConstraints2D)(component.constraints & -4); } if (pD != null && !_userInvincible) { pD.isInvincible = false; } } Plugin.Log.LogInfo((object)("Noclip: " + (_noclipEnabled ? "ON" : "OFF"))); } public static void SetNoclip(bool value) { if (_noclipEnabled != value) { ToggleNoclip(); } } } public static class PlayerActions { private static bool _infiniteJumpsEnabled = false; private static bool _noclipEnabled = false; private static Vector3 _savedPosition = Vector3.zero; public static bool IsInfiniteJumpsEnabled => _infiniteJumpsEnabled; public static bool IsNoclipEnabled => _noclipEnabled; public static void QuickHeal() { PlayerData pD = Plugin.PD; HeroController hero = Plugin.Hero; if (pD == null || (Object)(object)hero == (Object)null) { Plugin.Log.LogWarning((object)"Cannot heal: not in game."); return; } int num = pD.maxHealth - pD.health; if (num > 0) { hero.AddHealth(num); Plugin.Log.LogInfo((object)$"Healed for {num} HP. Current: {pD.health}/{pD.maxHealth}"); } } public static void QuickSilk() { PlayerData pD = Plugin.PD; HeroController hero = Plugin.Hero; if (pD == null || (Object)(object)hero == (Object)null) { Plugin.Log.LogWarning((object)"Cannot refill silk: not in game."); return; } int num = pD.silkMax - pD.silk; if (num > 0) { hero.AddSilk(num, false); Plugin.Log.LogInfo((object)$"Refilled {num} silk. Current: {pD.silk}/{pD.silkMax}"); } } public static void ToggleInvincibility() { CheatSystem.ToggleUserInvincible(); } public static void SetHealth(int health) { PlayerData pD = Plugin.PD; if (pD == null) { return; } int num = health - pD.health; if (num > 0) { HeroController hero = Plugin.Hero; if (hero != null) { hero.AddHealth(num); } } else if (num < 0) { pD.health = Mathf.Max(1, health); } Plugin.Log.LogInfo((object)$"Set health to {pD.health}"); } public static void SetMaxHealth(int maxHealth) { PlayerData pD = Plugin.PD; if (pD != null) { pD.maxHealth = maxHealth; Plugin.Log.LogInfo((object)$"Set max health to {pD.maxHealth}"); } } public static void SetSilk(int silk) { PlayerData pD = Plugin.PD; if (pD != null) { pD.silk = Mathf.Clamp(silk, 0, pD.silkMax); Plugin.Log.LogInfo((object)$"Set silk to {pD.silk}"); } } public static void ToggleInfiniteJumps() { _infiniteJumpsEnabled = !_infiniteJumpsEnabled; Plugin.Log.LogInfo((object)("Infinite Jumps: " + (_infiniteJumpsEnabled ? "ON" : "OFF"))); } public static void ToggleNoclip() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) HeroController hero = Plugin.Hero; if ((Object)(object)hero == (Object)null) { return; } _noclipEnabled = !_noclipEnabled; Rigidbody2D component = ((Component)hero).GetComponent(); Collider2D[] componentsInChildren = ((Component)hero).GetComponentsInChildren(); if (_noclipEnabled) { if ((Object)(object)component != (Object)null) { component.gravityScale = 0f; component.linearVelocity = Vector2.zero; } Collider2D[] array = componentsInChildren; for (int i = 0; i < array.Length; i++) { ((Behaviour)array[i]).enabled = false; } } else { if ((Object)(object)component != (Object)null) { component.gravityScale = 1f; } Collider2D[] array = componentsInChildren; for (int i = 0; i < array.Length; i++) { ((Behaviour)array[i]).enabled = true; } } Plugin.Log.LogInfo((object)("Noclip: " + (_noclipEnabled ? "ON" : "OFF"))); } public static void ProcessNoclipMovement(float speed = 15f) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (!_noclipEnabled) { return; } HeroController hero = Plugin.Hero; if (!((Object)(object)hero == (Object)null)) { Rigidbody2D component = ((Component)hero).GetComponent(); if (!((Object)(object)component == (Object)null)) { float axis = Input.GetAxis("Horizontal"); float axis2 = Input.GetAxis("Vertical"); component.linearVelocity = new Vector2(axis * speed, axis2 * speed); } } } public static void TeleportTo(Vector3 position) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) HeroController hero = Plugin.Hero; if ((Object)(object)hero == (Object)null) { Plugin.Log.LogWarning((object)"Cannot teleport: not in game."); return; } ((Component)hero).transform.position = position; Plugin.Log.LogInfo((object)$"Teleported to {position}"); } public static void KillPlayer() { if (!((Object)(object)Plugin.Hero == (Object)null)) { PlayerData pD = Plugin.PD; if (pD != null) { pD.health = 0; } Plugin.Log.LogInfo((object)"Killed player."); } } public static void RespawnPlayer() { GameManager gM = Plugin.GM; if (!((Object)(object)gM == (Object)null)) { gM.ReadyForRespawn(false); Plugin.Log.LogInfo((object)"Respawning player."); } } public static PlayerStateInfo GetStateInfo() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) HeroController hero = Plugin.Hero; PlayerData pD = Plugin.PD; if ((Object)(object)hero == (Object)null || pD == null) { return default(PlayerStateInfo); } return new PlayerStateInfo { Position = ((Component)hero).transform.position, Health = pD.health, MaxHealth = pD.maxHealth, Silk = pD.silk, MaxSilk = pD.silkMax, IsInvincible = pD.isInvincible, FacingRight = hero.cState.facingRight, OnGround = hero.cState.onGround, Jumping = hero.cState.jumping, Dashing = hero.cState.dashing, Attacking = hero.cState.attacking, Dead = hero.cState.dead, SceneName = (Plugin.GM?.sceneName ?? "Unknown") }; } public static void UnlockAllAbilities() { ToolItemManager.UnlockAllTools(); ToolItemManager.UnlockAllCrests(); Plugin.Log.LogInfo((object)"Unlocked all tools and crests."); } } public struct PlayerStateInfo { public Vector3 Position; public int Health; public int MaxHealth; public int Silk; public int MaxSilk; public bool IsInvincible; public bool FacingRight; public bool OnGround; public bool Jumping; public bool Dashing; public bool Attacking; public bool Dead; public string SceneName; } } namespace SilksongManager.Patches { public static class DamagePatches { private static Harmony _harmony; public static void Apply() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown try { _harmony = new Harmony("com.catalyst.silksongmanager.damage"); _harmony.PatchAll(typeof(DamagePatches)); Plugin.Log.LogInfo((object)"DamagePatches applied successfully"); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to apply DamagePatches: " + ex.Message)); } } public static void Remove() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } [HarmonyPatch(typeof(HealthManager), "TakeDamage")] [HarmonyPrefix] public static void TakeDamage_Prefix(ref HitInstance hitInstance, HealthManager __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) try { DamageType? damageType = GetDamageType(hitInstance.AttackType); if (damageType.HasValue && (DamageSystem.IsCustomEnabled(damageType.Value) || !Mathf.Approximately(DamageSystem.GetMultiplier(damageType.Value), 1f) || !Mathf.Approximately(DamageSystem.GlobalMultiplier, 1f))) { float baseDamage = hitInstance.DamageDealt; float num = DamageSystem.CalculateFinalDamage(damageType.Value, baseDamage); if (num < 0f) { int num2 = Mathf.RoundToInt(0f - num); __instance.hp += num2; hitInstance.DamageDealt = 0; } else { hitInstance.DamageDealt = Mathf.RoundToInt(num); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("DamagePatches error: " + ex.Message)); } } private static DamageType? GetDamageType(AttackTypes attackType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected I4, but got Unknown switch ((int)attackType) { case 0: case 1: case 6: case 7: return DamageType.Nail; case 3: case 9: case 10: case 11: case 16: case 19: return DamageType.Tool; case 2: return DamageType.Spell; case 12: case 13: return DamageType.Summon; default: return null; } } } } namespace SilksongManager.Menu { public static class MainMenuHook { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnSSManagerButtonPressed; public static UnityAction <1>__OnBackButtonPressed; public static UnityAction <2>__OnKeybindsButtonPressed; public static UnityAction <3>__OnSettingsButtonPressed; public static UnityAction <4>__OnAboutButtonPressed; } private static bool _initialized; private static GameObject _ssManagerButton; private static MenuScreen _modMenuScreen; private static ModMenuController _menuController; private static bool _isInModMenu; public static bool IsInModMenu => _isInModMenu; public static void Initialize() { if (_initialized) { return; } try { MainMenuOptions val = Object.FindAnyObjectByType(); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"MainMenuOptions not found - not in menu scene?"); return; } CreateModMenuScreen(); CreateSSManagerButton(val); AddCustomCredits(); _initialized = true; Plugin.Log.LogInfo((object)"Main menu hook initialized successfully!"); } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to initialize main menu hook: {arg}"); } } public static void Reset() { _initialized = false; _ssManagerButton = null; _modMenuScreen = null; _menuController = null; _isInModMenu = false; } private static void CreateSSManagerButton(MainMenuOptions mainMenuOptions) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown MenuButton val = mainMenuOptions.extrasButton; if ((Object)(object)val == (Object)null) { val = mainMenuOptions.optionsButton; } if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"Could not find template button to clone!"); return; } _ssManagerButton = Object.Instantiate(((Component)val).gameObject, ((Component)val).transform.parent); ((Object)_ssManagerButton).name = "SSManagerButton"; MenuButton component = _ssManagerButton.GetComponent(); if ((Object)(object)component == (Object)null) { Plugin.Log.LogError((object)"Cloned button doesn't have MenuButton component!"); Object.Destroy((Object)(object)_ssManagerButton); return; } EventTrigger component2 = _ssManagerButton.GetComponent(); if ((Object)(object)component2 != (Object)null) { Object.DestroyImmediate((Object)(object)component2); Plugin.Log.LogInfo((object)"Removed EventTrigger from cloned button"); } component.OnSubmitPressed = new UnityEvent(); UnityEvent onSubmitPressed = component.OnSubmitPressed; object obj = <>O.<0>__OnSSManagerButtonPressed; if (obj == null) { UnityAction val2 = OnSSManagerButtonPressed; <>O.<0>__OnSSManagerButtonPressed = val2; obj = (object)val2; } onSubmitPressed.AddListener((UnityAction)obj); SetButtonText(_ssManagerButton, "SS Manager"); PositionButtonCorrectly(mainMenuOptions, component); Plugin.Log.LogInfo((object)"SS Manager button created successfully!"); } private static void SetButtonText(GameObject buttonObj, string text) { MonoBehaviour[] componentsInChildren = buttonObj.GetComponentsInChildren(); foreach (MonoBehaviour val in componentsInChildren) { string name = ((object)val).GetType().Name; if (name.Contains("Locali") || name.Contains("Translat")) { ((Behaviour)val).enabled = false; Plugin.Log.LogInfo((object)("Disabled localization component: " + name)); } } Text componentInChildren = buttonObj.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = text; return; } TextMeshProUGUI componentInChildren2 = buttonObj.GetComponentInChildren(); if ((Object)(object)componentInChildren2 != (Object)null) { ((TMP_Text)componentInChildren2).text = text; } else { Plugin.Log.LogWarning((object)"Could not find text component on button!"); } } private static void PositionButtonCorrectly(MainMenuOptions mainMenuOptions, MenuButton ssManagerButton) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) MenuButton extrasButton = mainMenuOptions.extrasButton; MenuButton quitButton = mainMenuOptions.quitButton; if ((Object)(object)extrasButton == (Object)null || (Object)(object)quitButton == (Object)null) { Plugin.Log.LogWarning((object)"Could not find extras or quit button for positioning"); return; } RectTransform component = ((Component)ssManagerButton).GetComponent(); RectTransform component2 = ((Component)extrasButton).GetComponent(); RectTransform component3 = ((Component)quitButton).GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null) { Plugin.Log.LogWarning((object)"Could not get RectTransforms for positioning"); return; } float num = component2.anchoredPosition.y - component3.anchoredPosition.y; float num2 = component2.anchoredPosition.y - num; component.anchoredPosition = new Vector2(component2.anchoredPosition.x, num2); component3.anchoredPosition = new Vector2(component3.anchoredPosition.x, component3.anchoredPosition.y - num); int siblingIndex = ((Component)quitButton).transform.GetSiblingIndex(); ((Component)ssManagerButton).transform.SetSiblingIndex(siblingIndex); SetupNavigation(extrasButton, ssManagerButton, quitButton); Plugin.Log.LogInfo((object)$"Button positioned at Y={component.anchoredPosition.y}, Quit moved to Y={component3.anchoredPosition.y}, Sibling index={siblingIndex}"); } private static void SetupNavigation(MenuButton extrasButton, MenuButton ssManagerButton, MenuButton quitButton) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) Navigation navigation = ((Selectable)extrasButton).navigation; ((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)ssManagerButton; ((Selectable)extrasButton).navigation = navigation; Navigation navigation2 = ((Selectable)ssManagerButton).navigation; ((Navigation)(ref navigation2)).mode = (Mode)4; ((Navigation)(ref navigation2)).selectOnUp = (Selectable)(object)extrasButton; ((Navigation)(ref navigation2)).selectOnDown = (Selectable)(object)quitButton; ((Selectable)ssManagerButton).navigation = navigation2; Navigation navigation3 = ((Selectable)quitButton).navigation; ((Navigation)(ref navigation3)).selectOnUp = (Selectable)(object)ssManagerButton; ((Selectable)quitButton).navigation = navigation3; } private static void OnSSManagerButtonPressed() { Plugin.Log.LogInfo((object)"SS Manager button pressed!"); UIManager instance = UIManager.instance; if ((Object)(object)instance != (Object)null && (Object)(object)_modMenuScreen != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(GoToModMenu(instance)); } else { Plugin.Log.LogWarning((object)"UIManager or ModMenuScreen not available!"); } } private static IEnumerator GoToModMenu(UIManager ui) { Plugin.Log.LogInfo((object)"GoToModMenu started"); _isInModMenu = true; GameManager instance = GameManager.instance; InputHandler ih = ((instance != null) ? instance.inputHandler : null); if (ih != null) { ih.StopUIInput(); } if ((Object)(object)ui.extrasMenuScreen != (Object)null) { CanvasGroup component = ((Component)ui.extrasMenuScreen).GetComponent(); if ((Object)(object)component != (Object)null) { component.alpha = 0f; component.interactable = false; component.blocksRaycasts = false; } ((Component)ui.extrasMenuScreen).gameObject.SetActive(false); Plugin.Log.LogInfo((object)"Explicitly hid original ExtrasMenuScreen"); } ((MonoBehaviour)ui).StartCoroutine(FadeOutSprite(ui.gameTitle)); try { object obj = ((object)ui).GetType().GetField("subtitleFSM")?.GetValue(ui); obj?.GetType().GetMethod("SendEvent", new Type[1] { typeof(string) })?.Invoke(obj, new object[1] { "FADE OUT" }); } catch { } yield return ((MonoBehaviour)ui).StartCoroutine(FadeOutCanvasGroup(ui.mainMenuScreen, ui)); Plugin.Log.LogInfo((object)"Showing mod menu screen"); yield return ((MonoBehaviour)ui).StartCoroutine(ShowMenu(_modMenuScreen, ui)); if ((Object)(object)_menuController != (Object)null) { _menuController.SetActive(active: true); } if (ih != null) { ih.StartUIInput(); } Plugin.Log.LogInfo((object)"GoToModMenu completed"); } public static void HandleBackPressed() { if (_isInModMenu) { Plugin.Log.LogInfo((object)"HandleBackPressed called"); if ((Object)(object)_menuController != (Object)null) { _menuController.SetActive(active: false); } UIManager instance = UIManager.instance; if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(ReturnToMainMenu(instance)); } } } public static IEnumerator ReturnToMainMenu(UIManager ui) { _isInModMenu = false; GameManager instance = GameManager.instance; InputHandler ih = ((instance != null) ? instance.inputHandler : null); if (ih != null) { ih.StopUIInput(); } yield return ((MonoBehaviour)ui).StartCoroutine(HideMenu(_modMenuScreen, ui)); yield return ((MonoBehaviour)ui).StartCoroutine(FadeInCanvasGroup(ui.mainMenuScreen, ui)); ((MonoBehaviour)ui).StartCoroutine(FadeInSprite(ui.gameTitle)); try { object obj = ((object)ui).GetType().GetField("subtitleFSM")?.GetValue(ui); obj?.GetType().GetMethod("SendEvent", new Type[1] { typeof(string) })?.Invoke(obj, new object[1] { "FADE IN" }); } catch { } if (ih != null) { ih.StartUIInput(); } } private static void OnBackButtonPressed() { Plugin.Log.LogInfo((object)"Back button pressed"); HandleBackPressed(); } public static void HideMainMenu(UIManager ui) { ((MonoBehaviour)ui).StartCoroutine(FadeOutSprite(ui.gameTitle)); try { object obj = ((object)ui).GetType().GetField("subtitleFSM")?.GetValue(ui); obj?.GetType().GetMethod("SendEvent", new Type[1] { typeof(string) })?.Invoke(obj, new object[1] { "FADE OUT" }); } catch { } ((MonoBehaviour)ui).StartCoroutine(FadeOutCanvasGroup(ui.mainMenuScreen, ui)); } public static void ShowMainMenu(UIManager ui) { ((MonoBehaviour)ui).StartCoroutine(FadeInSprite(ui.gameTitle)); try { object obj = ((object)ui).GetType().GetField("subtitleFSM")?.GetValue(ui); obj?.GetType().GetMethod("SendEvent", new Type[1] { typeof(string) })?.Invoke(obj, new object[1] { "FADE IN" }); } catch { } ((MonoBehaviour)ui).StartCoroutine(FadeInCanvasGroup(ui.mainMenuScreen, ui)); } private static IEnumerator FadeOutSprite(SpriteRenderer sprite) { if (!((Object)(object)sprite == (Object)null)) { float alpha = sprite.color.a; while (alpha > 0.05f) { alpha -= Time.unscaledDeltaTime * 3.2f; sprite.color = new Color(sprite.color.r, sprite.color.g, sprite.color.b, alpha); yield return null; } sprite.color = new Color(sprite.color.r, sprite.color.g, sprite.color.b, 0f); ((Renderer)sprite).enabled = false; } } private static IEnumerator FadeInSprite(SpriteRenderer sprite) { if (!((Object)(object)sprite == (Object)null)) { ((Renderer)sprite).enabled = true; float alpha = sprite.color.a; while (alpha < 0.95f) { alpha += Time.unscaledDeltaTime * 3.2f; sprite.color = new Color(sprite.color.r, sprite.color.g, sprite.color.b, alpha); yield return null; } sprite.color = new Color(sprite.color.r, sprite.color.g, sprite.color.b, 1f); } } private static IEnumerator FadeOutCanvasGroup(CanvasGroup cg, UIManager ui) { if ((Object)(object)cg == (Object)null) { yield break; } float loopFailsafe = 0f; while (cg.alpha > 0.05f) { cg.alpha -= Time.unscaledDeltaTime * ui.MENU_FADE_SPEED; loopFailsafe += Time.unscaledDeltaTime; if (loopFailsafe >= 2f) { break; } yield return null; } cg.alpha = 0f; cg.interactable = false; ((Component)cg).gameObject.SetActive(false); } private static IEnumerator FadeInCanvasGroup(CanvasGroup cg, UIManager ui) { if ((Object)(object)cg == (Object)null) { yield break; } ((Component)cg).gameObject.SetActive(true); cg.alpha = 0f; float loopFailsafe = 0f; while (cg.alpha < 0.95f) { cg.alpha += Time.unscaledDeltaTime * ui.MENU_FADE_SPEED; loopFailsafe += Time.unscaledDeltaTime; if (loopFailsafe >= 2f) { break; } yield return null; } cg.alpha = 1f; cg.interactable = true; } private static IEnumerator ShowMenu(MenuScreen menu, UIManager ui) { if (!((Object)(object)menu == (Object)null)) { CanvasGroup component = ((Component)menu).GetComponent(); if ((Object)(object)component != (Object)null) { yield return ((MonoBehaviour)ui).StartCoroutine(FadeInCanvasGroup(component, ui)); } else { ((Component)menu).gameObject.SetActive(true); } if ((int)menu.HighlightBehaviour == 0) { menu.HighlightDefault(); } } } private static IEnumerator HideMenu(MenuScreen menu, UIManager ui) { if (!((Object)(object)menu == (Object)null)) { CanvasGroup component = ((Component)menu).GetComponent(); if ((Object)(object)component != (Object)null) { yield return ((MonoBehaviour)ui).StartCoroutine(FadeOutCanvasGroup(component, ui)); } else { ((Component)menu).gameObject.SetActive(false); } } } private static void AddCustomCredits() { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) Text[] array = Object.FindObjectsOfType(); foreach (Text val in array) { if (!val.text.Contains("1.0.") || val.text.Length >= 20) { continue; } Plugin.Log.LogInfo((object)("Found version text: " + val.text)); GameObject val2 = Object.Instantiate(((Component)val).gameObject, ((Component)val).transform.parent); ((Object)val2).name = "SSManagerCredits"; MonoBehaviour[] components = val2.GetComponents(); foreach (MonoBehaviour val3 in components) { if (!(val3 is Text)) { Object.Destroy((Object)(object)val3); } } Text component = val2.GetComponent(); component.text = "Silksong Manager Edition\nwith ❤ by Catalyst"; component.lineSpacing = 0.8f; component.supportRichText = true; if ((Object)(object)((Component)((Component)val).transform.parent).GetComponent() != (Object)null) { val2.transform.SetSiblingIndex(((Component)val).transform.GetSiblingIndex() + 1); Plugin.Log.LogInfo((object)"Added credits via LayoutGroup"); return; } RectTransform component2 = val2.GetComponent(); RectTransform component3 = ((Component)val).GetComponent(); component2.anchoredPosition = component3.anchoredPosition - new Vector2(0f, 45f); Plugin.Log.LogInfo((object)"Added credits via manual positioning"); return; } Plugin.Log.LogInfo((object)"Could not find version text to attach credits to."); } private static void CreateModMenuScreen() { UIManager instance = UIManager.instance; if ((Object)(object)instance == (Object)null) { Plugin.Log.LogError((object)"UIManager not found!"); return; } MenuScreen val = instance.extrasMenuScreen ?? instance.optionsMenuScreen; if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"Could not find template MenuScreen to clone!"); return; } Plugin.Log.LogInfo((object)"=== Template MenuScreen hierarchy ==="); LogHierarchy(((Component)val).transform, 0); Plugin.Log.LogInfo((object)"=== End hierarchy ==="); GameObject val2 = Object.Instantiate(((Component)val).gameObject, ((Component)val).transform.parent); ((Object)val2).name = "SSManagerMenuScreen"; _modMenuScreen = val2.GetComponent(); if ((Object)(object)_modMenuScreen == (Object)null) { Plugin.Log.LogError((object)"Cloned screen doesn't have MenuScreen component!"); Object.Destroy((Object)(object)val2); return; } _menuController = val2.AddComponent(); Plugin.Log.LogInfo((object)"Added ModMenuController to menu screen"); val2.SetActive(false); CanvasGroup component = val2.GetComponent(); if ((Object)(object)component != (Object)null) { component.alpha = 0f; component.interactable = false; } ModifyMenuScreenContent(val2); Plugin.Log.LogInfo((object)"Mod menu screen created successfully!"); } private static void LogHierarchy(Transform t, int depth) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown string text = new string(' ', depth * 2); Component[] components = ((Component)t).GetComponents(); string text2 = string.Join(",", Array.ConvertAll(components, (Component c) => ((object)c)?.GetType().Name ?? "null")); Plugin.Log.LogInfo((object)$"{text}{((Object)t).name} [active={((Component)t).gameObject.activeSelf}] ({text2})"); foreach (Transform item in t) { LogHierarchy(item, depth + 1); } } private static void ModifyMenuScreenContent(GameObject screenObj) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Expected O, but got Unknown //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Expected O, but got Unknown //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Expected O, but got Unknown //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Expected O, but got Unknown //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Expected O, but got Unknown //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Unknown result type (might be due to invalid IL or missing references) Plugin.Log.LogInfo((object)"Modifying cloned menu screen content - DESTROYING unwanted elements..."); MenuButton val = null; if ((Object)(object)_modMenuScreen.backButton != (Object)null) { val = _modMenuScreen.backButton; ((Component)val).transform.SetParent(screenObj.transform, false); ((Component)val).gameObject.SetActive(false); Plugin.Log.LogInfo((object)("Saved backButton from destruction: " + ((Object)val).name)); } List list = new List(); Transform val2 = null; Transform val3 = null; foreach (Transform item in screenObj.transform) { Transform val4 = item; if ((Object)(object)val != (Object)null && (Object)(object)val4 == (Object)(object)((Component)val).transform) { Plugin.Log.LogInfo((object)("Skipping (saved): " + ((Object)val4).name)); continue; } string text = ((Object)val4).name.ToLower(); if (text.Contains("title")) { val2 = val4; Plugin.Log.LogInfo((object)("Keeping: " + ((Object)val4).name)); } else if (text.Contains("fleur")) { val3 = val4; Plugin.Log.LogInfo((object)("Keeping: " + ((Object)val4).name)); } else { list.Add(((Component)val4).gameObject); Plugin.Log.LogInfo((object)("Will DESTROY: " + ((Object)val4).name)); } } foreach (GameObject item2 in list) { Plugin.Log.LogInfo((object)("Destroying: " + ((Object)item2).name)); Object.DestroyImmediate((Object)(object)item2); } if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(true); Text component = ((Component)val2).GetComponent(); if ((Object)(object)component != (Object)null) { DestroyLocalization(((Component)val2).gameObject); component.text = "Silksong Manager"; Plugin.Log.LogInfo((object)"Set title UI.Text to 'Silksong Manager'"); } } else { Plugin.Log.LogWarning((object)"Title element not found!"); } if ((Object)(object)val3 != (Object)null) { ((Component)val3).gameObject.SetActive(true); Plugin.Log.LogInfo((object)"Enabled TopFleur"); } if ((Object)(object)val != (Object)null) { val.OnSubmitPressed = new UnityEvent(); UnityEvent onSubmitPressed = val.OnSubmitPressed; object obj = <>O.<1>__OnBackButtonPressed; if (obj == null) { UnityAction val5 = OnBackButtonPressed; <>O.<1>__OnBackButtonPressed = val5; obj = (object)val5; } onSubmitPressed.AddListener((UnityAction)obj); ((Component)val).gameObject.SetActive(true); RectTransform component2 = ((Component)val).GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.anchorMin = new Vector2(0.5f, 0f); component2.anchorMax = new Vector2(0.5f, 0f); component2.pivot = new Vector2(0.5f, 0.5f); component2.anchoredPosition = new Vector2(0f, 80f); } DestroyLocalization(((Component)val).gameObject); Plugin.Log.LogInfo((object)"Configured back button at bottom of screen"); } if ((Object)(object)_modMenuScreen.backButton != (Object)null) { object obj2 = <>O.<2>__OnKeybindsButtonPressed; if (obj2 == null) { UnityAction val6 = OnKeybindsButtonPressed; <>O.<2>__OnKeybindsButtonPressed = val6; obj2 = (object)val6; } GameObject val7 = CreateMenuButton(screenObj, "KeybindsButton", "Keybinds", 60f, (UnityAction)obj2); object obj3 = <>O.<3>__OnSettingsButtonPressed; if (obj3 == null) { UnityAction val8 = OnSettingsButtonPressed; <>O.<3>__OnSettingsButtonPressed = val8; obj3 = (object)val8; } GameObject val9 = CreateMenuButton(screenObj, "SettingsButton", "Settings", 0f, (UnityAction)obj3); object obj4 = <>O.<4>__OnAboutButtonPressed; if (obj4 == null) { UnityAction val10 = OnAboutButtonPressed; <>O.<4>__OnAboutButtonPressed = val10; obj4 = (object)val10; } GameObject obj5 = CreateMenuButton(screenObj, "AboutButton", "About", -60f, (UnityAction)obj4); MenuButton val11 = ((val7 != null) ? val7.GetComponent() : null); MenuButton val12 = ((val9 != null) ? val9.GetComponent() : null); MenuButton val13 = ((obj5 != null) ? obj5.GetComponent() : null); MenuButton backButton = _modMenuScreen.backButton; if ((Object)(object)val11 != (Object)null && (Object)(object)val12 != (Object)null && (Object)(object)val13 != (Object)null && (Object)(object)backButton != (Object)null) { SetupButtonNavigation(val11, null, val12); SetupButtonNavigation(val12, val11, val13); SetupButtonNavigation(val13, val12, backButton); Navigation navigation = ((Selectable)backButton).navigation; ((Navigation)(ref navigation)).mode = (Mode)4; ((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)val13; ((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)val11; ((Selectable)backButton).navigation = navigation; Navigation navigation2 = ((Selectable)val11).navigation; ((Navigation)(ref navigation2)).selectOnUp = (Selectable)(object)backButton; ((Selectable)val11).navigation = navigation2; _modMenuScreen.defaultHighlight = (Selectable)(object)val11; Plugin.Log.LogInfo((object)"Created 3 menu buttons with navigation"); } } else { Plugin.Log.LogWarning((object)"Back button not found, cannot create menu buttons!"); } Plugin.Log.LogInfo((object)"Menu screen content modification complete!"); } private static GameObject CreateMenuButton(GameObject parent, string name, string text, float yOffset, UnityAction onClick) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown if ((Object)(object)_modMenuScreen?.backButton == (Object)null) { return null; } GameObject val = Object.Instantiate(((Component)_modMenuScreen.backButton).gameObject, parent.transform); ((Object)val).name = name; RectTransform component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(0f, yOffset); } MenuButton component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.OnSubmitPressed = new UnityEvent(); component2.OnSubmitPressed.AddListener(onClick); DestroyLocalization(val); SetButtonTextDirect(val, text); } Plugin.Log.LogInfo((object)$"Created button '{text}' at Y={yOffset}"); return val; } private static void SetupButtonNavigation(MenuButton button, MenuButton up, MenuButton down) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)button == (Object)null)) { Navigation navigation = ((Selectable)button).navigation; ((Navigation)(ref navigation)).mode = (Mode)4; ((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)up; ((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)down; ((Selectable)button).navigation = navigation; } } private static void DestroyLocalization(GameObject obj) { if ((Object)(object)obj == (Object)null) { return; } MonoBehaviour[] componentsInChildren = obj.GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { string name = ((object)val).GetType().Name; if (name.Contains("Locali") || name.Contains("Translat") || name.Contains("LocalizedText") || name.Contains("LocalisedText")) { Plugin.Log.LogInfo((object)("Destroying localization component: " + name)); Object.DestroyImmediate((Object)(object)val); } } } } private static void DisableLocalization(GameObject obj) { MonoBehaviour[] componentsInChildren = obj.GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { string name = ((object)val).GetType().Name; if (name.Contains("Locali") || name.Contains("Translat") || name.Contains("LocalisedText")) { ((Behaviour)val).enabled = false; } } } private static void SetButtonTextDirect(GameObject buttonObj, string text) { Text componentInChildren = buttonObj.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = text; } TextMeshProUGUI componentInChildren2 = buttonObj.GetComponentInChildren(true); if ((Object)(object)componentInChildren2 != (Object)null) { ((TMP_Text)componentInChildren2).text = text; } } private static void OnKeybindsButtonPressed() { Plugin.Log.LogInfo((object)"Keybinds button pressed!"); UIManager instance = UIManager.instance; if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(GoToKeybindsScreen(instance)); } } private static IEnumerator GoToKeybindsScreen(UIManager ui) { GameManager instance = GameManager.instance; InputHandler ih = ((instance != null) ? instance.inputHandler : null); if (ih != null) { ih.StopUIInput(); } if ((Object)(object)_menuController != (Object)null) { Plugin.Log.LogInfo((object)"Deactivating ModMenuController in GoToKeybindsScreen"); _menuController.SetActive(active: false); } else { Plugin.Log.LogError((object)"_menuController is NULL in GoToKeybindsScreen!"); } MenuScreen modMenuScreen = _modMenuScreen; CanvasGroup cg = ((modMenuScreen != null) ? ((Component)modMenuScreen).GetComponent() : null); yield return ((MonoBehaviour)ui).StartCoroutine(FadeOutCanvasGroup(cg, ui)); ModKeybindsScreen.Initialize(); yield return ((MonoBehaviour)ui).StartCoroutine(ModKeybindsScreen.Show(ui)); if (ih != null) { ih.StartUIInput(); } } public static void ReturnFromKeybindsScreen() { UIManager instance = UIManager.instance; if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(ReturnFromKeybindsScreenCoroutine(instance)); } } private static IEnumerator ReturnFromKeybindsScreenCoroutine(UIManager ui) { GameManager instance = GameManager.instance; InputHandler ih = ((instance != null) ? instance.inputHandler : null); if (ih != null) { ih.StopUIInput(); } yield return ((MonoBehaviour)ui).StartCoroutine(ModKeybindsScreen.Hide(ui)); MenuScreen modMenuScreen = _modMenuScreen; CanvasGroup cg = ((modMenuScreen != null) ? ((Component)modMenuScreen).GetComponent() : null); yield return ((MonoBehaviour)ui).StartCoroutine(FadeInCanvasGroup(cg, ui)); if ((Object)(object)_menuController != (Object)null) { _menuController.SetActive(active: true); } if ((Object)(object)_modMenuScreen?.defaultHighlight != (Object)null) { EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject(((Component)_modMenuScreen.defaultHighlight).gameObject); } } if (ih != null) { ih.StartUIInput(); } } private static void OnSettingsButtonPressed() { Plugin.Log.LogInfo((object)"Settings button pressed!"); UIManager instance = UIManager.instance; if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(GoToSettingsScreen(instance)); } } private static IEnumerator GoToSettingsScreen(UIManager ui) { GameManager instance = GameManager.instance; InputHandler ih = ((instance != null) ? instance.inputHandler : null); if (ih != null) { ih.StopUIInput(); } if ((Object)(object)_menuController != (Object)null) { _menuController.SetActive(active: false); } if ((Object)(object)ui.mainMenuScreen != (Object)null) { ((Component)ui.mainMenuScreen).gameObject.SetActive(false); } MenuScreen modMenuScreen = _modMenuScreen; CanvasGroup cg = ((modMenuScreen != null) ? ((Component)modMenuScreen).GetComponent() : null); yield return ((MonoBehaviour)ui).StartCoroutine(FadeOutCanvasGroup(cg, ui)); ModSettingsScreen.Initialize(); yield return ((MonoBehaviour)ui).StartCoroutine(ModSettingsScreen.Show(ui)); if (ih != null) { ih.StartUIInput(); } } public static void ReturnFromSettingsScreen() { UIManager instance = UIManager.instance; if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(ReturnFromSettingsScreenCoroutine(instance)); } } private static IEnumerator ReturnFromSettingsScreenCoroutine(UIManager ui) { GameManager instance = GameManager.instance; InputHandler ih = ((instance != null) ? instance.inputHandler : null); if (ih != null) { ih.StopUIInput(); } yield return ((MonoBehaviour)ui).StartCoroutine(ModSettingsScreen.Hide(ui)); MenuScreen modMenuScreen = _modMenuScreen; CanvasGroup cg = ((modMenuScreen != null) ? ((Component)modMenuScreen).GetComponent() : null); yield return ((MonoBehaviour)ui).StartCoroutine(FadeInCanvasGroup(cg, ui)); if ((Object)(object)_menuController != (Object)null) { _menuController.SetActive(active: true); } if ((Object)(object)_modMenuScreen?.defaultHighlight != (Object)null) { EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject(((Component)_modMenuScreen.defaultHighlight).gameObject); } } if (ih != null) { ih.StartUIInput(); } } private static void OnAboutButtonPressed() { Plugin.Log.LogInfo((object)"About button pressed!"); UIManager instance = UIManager.instance; if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(GoToAboutScreen(instance)); } } private static IEnumerator GoToAboutScreen(UIManager ui) { GameManager instance = GameManager.instance; InputHandler ih = ((instance != null) ? instance.inputHandler : null); if (ih != null) { ih.StopUIInput(); } if ((Object)(object)_menuController != (Object)null) { _menuController.SetActive(active: false); } if ((Object)(object)ui.mainMenuScreen != (Object)null) { ((Component)ui.mainMenuScreen).gameObject.SetActive(false); } MenuScreen modMenuScreen = _modMenuScreen; CanvasGroup cg = ((modMenuScreen != null) ? ((Component)modMenuScreen).GetComponent() : null); yield return ((MonoBehaviour)ui).StartCoroutine(FadeOutCanvasGroup(cg, ui)); ModAboutScreen.Initialize(); yield return ((MonoBehaviour)ui).StartCoroutine(ModAboutScreen.Show(ui)); if (ih != null) { ih.StartUIInput(); } } public static void ReturnFromAboutScreen() { UIManager instance = UIManager.instance; if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(ReturnFromAboutScreenCoroutine(instance)); } } private static IEnumerator ReturnFromAboutScreenCoroutine(UIManager ui) { GameManager instance = GameManager.instance; InputHandler ih = ((instance != null) ? instance.inputHandler : null); if (ih != null) { ih.StopUIInput(); } yield return ((MonoBehaviour)ui).StartCoroutine(ModAboutScreen.Hide(ui)); MenuScreen modMenuScreen = _modMenuScreen; CanvasGroup cg = ((modMenuScreen != null) ? ((Component)modMenuScreen).GetComponent() : null); yield return ((MonoBehaviour)ui).StartCoroutine(FadeInCanvasGroup(cg, ui)); if ((Object)(object)_menuController != (Object)null) { _menuController.SetActive(active: true); } if ((Object)(object)_modMenuScreen?.defaultHighlight != (Object)null) { EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject(((Component)_modMenuScreen.defaultHighlight).gameObject); } } if (ih != null) { ih.StartUIInput(); } } } public static class ModAboutScreen { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnBackPressed; } private static MenuScreen _aboutScreen; private static bool _initialized; private static bool _isActive; private static bool _isExiting; public static bool IsActive => _isActive; public static bool IsExiting => _isExiting; public static void Initialize() { if (_initialized) { return; } try { CreateAboutScreen(); _initialized = true; Plugin.Log.LogInfo((object)"ModAboutScreen initialized"); } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to initialize ModAboutScreen: {arg}"); } } public static void Reset() { _initialized = false; _aboutScreen = null; _isActive = false; } private static void CreateAboutScreen() { UIManager instance = UIManager.instance; if ((Object)(object)instance == (Object)null) { Plugin.Log.LogError((object)"UIManager not found!"); return; } MenuScreen extrasMenuScreen = instance.extrasMenuScreen; if ((Object)(object)extrasMenuScreen == (Object)null) { Plugin.Log.LogError((object)"ExtrasMenuScreen not found!"); return; } GameObject val = Object.Instantiate(((Component)extrasMenuScreen).gameObject, ((Component)extrasMenuScreen).transform.parent); ((Object)val).name = "ModAboutScreen"; _aboutScreen = val.GetComponent(); if ((Object)(object)_aboutScreen == (Object)null) { Object.Destroy((Object)(object)val); return; } val.SetActive(false); CanvasGroup component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.alpha = 0f; component.interactable = false; component.blocksRaycasts = false; } ModifyScreenContent(val); } private static void ModifyScreenContent(GameObject screenObj) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) MenuButton val = null; if ((Object)(object)_aboutScreen.backButton != (Object)null) { val = _aboutScreen.backButton; ((Component)val).transform.SetParent(screenObj.transform, false); ((Component)val).gameObject.SetActive(false); } List list = new List(); Transform val2 = null; foreach (Transform item in screenObj.transform) { Transform val3 = item; if (!((Object)(object)val != (Object)null) || !((Object)(object)val3 == (Object)(object)((Component)val).transform)) { string text = ((Object)val3).name.ToLower(); if (text.Contains("title")) { val2 = val3; } else if (!text.Contains("fleur")) { list.Add(((Component)val3).gameObject); } } } foreach (GameObject item2 in list) { Object.DestroyImmediate((Object)(object)item2); } if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(true); DestroyLocalization(((Component)val2).gameObject); Text component = ((Component)val2).GetComponent(); if ((Object)(object)component != (Object)null) { component.text = "About"; } } if ((Object)(object)val != (Object)null) { val.OnSubmitPressed = new UnityEvent(); UnityEvent onSubmitPressed = val.OnSubmitPressed; object obj = <>O.<0>__OnBackPressed; if (obj == null) { UnityAction val4 = OnBackPressed; <>O.<0>__OnBackPressed = val4; obj = (object)val4; } onSubmitPressed.AddListener((UnityAction)obj); ((Component)val).gameObject.SetActive(true); RectTransform component2 = ((Component)val).GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.anchorMin = new Vector2(0.5f, 0f); component2.anchorMax = new Vector2(0.5f, 0f); component2.pivot = new Vector2(0.5f, 0.5f); component2.anchoredPosition = new Vector2(0f, 80f); } DestroyLocalization(((Component)val).gameObject); _aboutScreen.defaultHighlight = (Selectable)(object)val; } CreateAboutContent(screenObj); } private static void CreateAboutContent(GameObject screenObj) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)screenObj.GetComponentInParent() == (Object)null)) { GameObject val = new GameObject("DescriptionText"); val.transform.SetParent(screenObj.transform, false); Text val2 = val.AddComponent(); val2.font = Resources.GetBuiltinResource("Arial.ttf"); val2.fontSize = 24; val2.alignment = (TextAnchor)4; ((Graphic)val2).color = Color.white; val2.supportRichText = true; val2.text = "Silksong Manager\r\nVersion 1.0.0.2\r\n\r\nA comprehensive mod manager and debug toolkit\r\nfor Hollow Knight: Silksong\r\n\r\nFeatures:\r\n• Debug Menu with player/enemy/world controls\r\n• Custom Keybinds System\r\n• Infinite Jumps, Noclip, Invincibility\r\n• Custom Damage System\r\n• And much more!\r\n\r\n❤ Created by Catalyst\r\ncatalyst@kyokai.ru | Telegram: @Catalyst_Kyokai"; RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(0f, 30f); component.sizeDelta = new Vector2(600f, 400f); Text componentInChildren = screenObj.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.font != (Object)null) { val2.font = componentInChildren.font; } } } private static void DestroyLocalization(GameObject obj) { if ((Object)(object)obj == (Object)null) { return; } MonoBehaviour[] componentsInChildren = obj.GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { string name = ((object)val).GetType().Name; if (name.Contains("Locali") || name.Contains("Translat")) { Object.DestroyImmediate((Object)(object)val); } } } } private static void OnBackPressed() { if (!_isExiting) { Plugin.Log.LogInfo((object)"About back button pressed"); MainMenuHook.ReturnFromAboutScreen(); } } public static IEnumerator Show(UIManager ui) { if ((Object)(object)_aboutScreen == (Object)null) { yield break; } _isActive = true; _isExiting = false; MainMenuHook.HideMainMenu(ui); CanvasGroup cg = ((Component)_aboutScreen).GetComponent(); ((Component)_aboutScreen).gameObject.SetActive(true); AboutInputController aboutInputController = ((Component)_aboutScreen).gameObject.GetComponent(); if ((Object)(object)aboutInputController == (Object)null) { aboutInputController = ((Component)_aboutScreen).gameObject.AddComponent(); } ((Behaviour)aboutInputController).enabled = true; if ((Object)(object)cg != (Object)null) { cg.interactable = true; cg.blocksRaycasts = true; cg.alpha = 0f; float fade = 0f; while (fade < 1f) { fade = (cg.alpha = fade + Time.unscaledDeltaTime * 4f); yield return null; } cg.alpha = 1f; } _aboutScreen.HighlightDefault(); Plugin.Log.LogInfo((object)"About screen shown"); } public static IEnumerator Hide(UIManager ui) { if ((Object)(object)_aboutScreen == (Object)null) { yield break; } _isExiting = true; CanvasGroup cg = ((Component)_aboutScreen).GetComponent(); if ((Object)(object)cg != (Object)null) { float fade = 1f; while (fade > 0f) { fade = (cg.alpha = fade - Time.unscaledDeltaTime * 4f); yield return null; } cg.alpha = 0f; cg.interactable = false; cg.blocksRaycasts = false; } ((Component)_aboutScreen).gameObject.SetActive(false); _isActive = false; _isExiting = false; } } public class AboutInputController : MonoBehaviour { private void Update() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) if (!ModAboutScreen.IsActive) { return; } UIManager instance = UIManager.instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.mainMenuScreen != (Object)null && ((Component)instance.mainMenuScreen).gameObject.activeSelf) { ((Component)instance.mainMenuScreen).gameObject.SetActive(false); if ((Object)(object)instance.gameTitle != (Object)null && (instance.gameTitle.color.a > 0.1f || ((Renderer)instance.gameTitle).enabled)) { instance.gameTitle.color = new Color(instance.gameTitle.color.r, instance.gameTitle.color.g, instance.gameTitle.color.b, 0f); ((Renderer)instance.gameTitle).enabled = false; } } if (Input.GetKeyDown((KeyCode)27) && !ModAboutScreen.IsExiting) { Plugin.Log.LogInfo((object)"Escape pressed in About, returning to SS Manager"); MainMenuHook.ReturnFromAboutScreen(); } } } public class ModMenuController : MonoBehaviour { private bool _isActive; public void SetActive(bool active) { Plugin.Log.LogInfo((object)$"ModMenuController SetActive({active}) called on instance {((object)this).GetHashCode()}"); _isActive = active; } private void Update() { if (_isActive && !ModKeybindsScreen.IsActive && Input.GetKeyDown((KeyCode)27)) { Plugin.Log.LogInfo((object)$"Escape pressed in mod menu (instance {((object)this).GetHashCode()}), returning to main menu"); MainMenuHook.HandleBackPressed(); } } } public static class ModSettingsScreen { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnBackPressed; } private static MenuScreen _settingsScreen; private static bool _initialized; private static bool _isActive; private static bool _isExiting; public static bool IsActive => _isActive; public static bool IsExiting => _isExiting; public static void Initialize() { if (_initialized) { return; } try { CreateSettingsScreen(); _initialized = true; Plugin.Log.LogInfo((object)"ModSettingsScreen initialized"); } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to initialize ModSettingsScreen: {arg}"); } } public static void Reset() { _initialized = false; _settingsScreen = null; _isActive = false; } private static void CreateSettingsScreen() { UIManager instance = UIManager.instance; if ((Object)(object)instance == (Object)null) { Plugin.Log.LogError((object)"UIManager not found!"); return; } MenuScreen extrasMenuScreen = instance.extrasMenuScreen; if ((Object)(object)extrasMenuScreen == (Object)null) { Plugin.Log.LogError((object)"ExtrasMenuScreen not found!"); return; } GameObject val = Object.Instantiate(((Component)extrasMenuScreen).gameObject, ((Component)extrasMenuScreen).transform.parent); ((Object)val).name = "ModSettingsScreen"; _settingsScreen = val.GetComponent(); if ((Object)(object)_settingsScreen == (Object)null) { Object.Destroy((Object)(object)val); return; } val.SetActive(false); CanvasGroup component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.alpha = 0f; component.interactable = false; } ModifyScreenContent(val); } private static void ModifyScreenContent(GameObject screenObj) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) MenuButton val = null; if ((Object)(object)_settingsScreen.backButton != (Object)null) { val = _settingsScreen.backButton; ((Component)val).transform.SetParent(screenObj.transform, false); ((Component)val).gameObject.SetActive(false); } List list = new List(); Transform val2 = null; foreach (Transform item in screenObj.transform) { Transform val3 = item; if (!((Object)(object)val != (Object)null) || !((Object)(object)val3 == (Object)(object)((Component)val).transform)) { string text = ((Object)val3).name.ToLower(); if (text.Contains("title")) { val2 = val3; } else if (!text.Contains("fleur")) { list.Add(((Component)val3).gameObject); } } } foreach (GameObject item2 in list) { Object.DestroyImmediate((Object)(object)item2); } if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(true); DestroyLocalization(((Component)val2).gameObject); Text component = ((Component)val2).GetComponent(); if ((Object)(object)component != (Object)null) { component.text = "Settings"; } } if ((Object)(object)val != (Object)null) { val.OnSubmitPressed = new UnityEvent(); UnityEvent onSubmitPressed = val.OnSubmitPressed; object obj = <>O.<0>__OnBackPressed; if (obj == null) { UnityAction val4 = OnBackPressed; <>O.<0>__OnBackPressed = val4; obj = (object)val4; } onSubmitPressed.AddListener((UnityAction)obj); ((Component)val).gameObject.SetActive(true); RectTransform component2 = ((Component)val).GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.anchorMin = new Vector2(0.5f, 0f); component2.anchorMax = new Vector2(0.5f, 0f); component2.pivot = new Vector2(0.5f, 0.5f); component2.anchoredPosition = new Vector2(0f, 80f); } DestroyLocalization(((Component)val).gameObject); } CreateSettingsContent(screenObj, val); } private static void CreateSettingsContent(GameObject screenObj, MenuButton backButton) { //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) float num = 80f; float num2 = -50f; int num3 = 0; GameObject val = CreateToggleButton(screenObj, "PauseGameToggle", "Pause Game on Menu Open", num + (float)num3++ * num2, () => DebugMenuConfig.PauseGameOnMenu, delegate(bool pauseGameOnMenu) { DebugMenuConfig.PauseGameOnMenu = pauseGameOnMenu; }); GameObject obj = CreateToggleButton(screenObj, "HotkeysToggle", "Enable Hotkeys", num + (float)num3++ * num2, () => Plugin.ModConfig.EnableHotkeys, delegate(bool enableHotkeys) { Plugin.ModConfig.EnableHotkeys = enableHotkeys; }); MenuButton val2 = ((val != null) ? val.GetComponent() : null); MenuButton val3 = ((obj != null) ? obj.GetComponent() : null); if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null && (Object)(object)backButton != (Object)null) { SetupNavigation(val2, backButton, val3); SetupNavigation(val3, val2, backButton); Navigation navigation = ((Selectable)backButton).navigation; ((Navigation)(ref navigation)).mode = (Mode)4; ((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)val3; ((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)val2; ((Selectable)backButton).navigation = navigation; _settingsScreen.defaultHighlight = (Selectable)(object)val2; } } private static GameObject CreateToggleButton(GameObject parent, string name, string label, float yOffset, Func getter, Action setter) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown if ((Object)(object)_settingsScreen?.backButton == (Object)null) { return null; } GameObject buttonObj = Object.Instantiate(((Component)_settingsScreen.backButton).gameObject, parent.transform); ((Object)buttonObj).name = name; RectTransform component = buttonObj.GetComponent(); if ((Object)(object)component != (Object)null) { component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(0f, yOffset); } MenuButton component2 = buttonObj.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.OnSubmitPressed = new UnityEvent(); component2.OnSubmitPressed.AddListener((UnityAction)delegate { bool flag = !getter(); setter(flag); UpdateToggleText(buttonObj, label, flag); }); DestroyLocalization(buttonObj); UpdateToggleText(buttonObj, label, getter()); } return buttonObj; } private static void UpdateToggleText(GameObject buttonObj, string label, bool isOn) { Text componentInChildren = buttonObj.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = label + ": " + (isOn ? "ON" : "OFF"); } TextMeshProUGUI componentInChildren2 = buttonObj.GetComponentInChildren(true); if ((Object)(object)componentInChildren2 != (Object)null) { ((TMP_Text)componentInChildren2).text = label + ": " + (isOn ? "ON" : "OFF"); } } private static void SetupNavigation(MenuButton button, MenuButton up, MenuButton down) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)button == (Object)null)) { Navigation navigation = ((Selectable)button).navigation; ((Navigation)(ref navigation)).mode = (Mode)4; ((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)up; ((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)down; ((Selectable)button).navigation = navigation; } } private static void DestroyLocalization(GameObject obj) { if ((Object)(object)obj == (Object)null) { return; } MonoBehaviour[] componentsInChildren = obj.GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { string name = ((object)val).GetType().Name; if (name.Contains("Locali") || name.Contains("Translat")) { Object.DestroyImmediate((Object)(object)val); } } } } private static void OnBackPressed() { if (!_isExiting) { Plugin.Log.LogInfo((object)"Settings back button pressed"); MainMenuHook.ReturnFromSettingsScreen(); } } public static IEnumerator Show(UIManager ui) { if ((Object)(object)_settingsScreen == (Object)null) { yield break; } _isActive = true; _isExiting = false; MainMenuHook.HideMainMenu(ui); CanvasGroup cg = ((Component)_settingsScreen).GetComponent(); ((Component)_settingsScreen).gameObject.SetActive(true); SettingsInputController settingsInputController = ((Component)_settingsScreen).gameObject.GetComponent(); if ((Object)(object)settingsInputController == (Object)null) { settingsInputController = ((Component)_settingsScreen).gameObject.AddComponent(); } ((Behaviour)settingsInputController).enabled = true; if ((Object)(object)cg != (Object)null) { cg.interactable = true; cg.blocksRaycasts = true; cg.alpha = 0f; float fade = 0f; while (fade < 1f) { fade = (cg.alpha = fade + Time.unscaledDeltaTime * 4f); yield return null; } cg.alpha = 1f; } _settingsScreen.HighlightDefault(); Plugin.Log.LogInfo((object)"Settings screen shown"); } public static IEnumerator Hide(UIManager ui) { if ((Object)(object)_settingsScreen == (Object)null) { yield break; } _isExiting = true; CanvasGroup cg = ((Component)_settingsScreen).GetComponent(); if ((Object)(object)cg != (Object)null) { float fade = 1f; while (fade > 0f) { fade = (cg.alpha = fade - Time.unscaledDeltaTime * 4f); yield return null; } cg.alpha = 0f; cg.interactable = false; cg.blocksRaycasts = false; } ((Component)_settingsScreen).gameObject.SetActive(false); _isActive = false; _isExiting = false; } } public class SettingsInputController : MonoBehaviour { private void Update() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) if (!ModSettingsScreen.IsActive) { return; } UIManager instance = UIManager.instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.mainMenuScreen != (Object)null && ((Component)instance.mainMenuScreen).gameObject.activeSelf) { ((Component)instance.mainMenuScreen).gameObject.SetActive(false); if ((Object)(object)instance.gameTitle != (Object)null && (instance.gameTitle.color.a > 0.1f || ((Renderer)instance.gameTitle).enabled)) { instance.gameTitle.color = new Color(instance.gameTitle.color.r, instance.gameTitle.color.g, instance.gameTitle.color.b, 0f); ((Renderer)instance.gameTitle).enabled = false; } } if (Input.GetKeyDown((KeyCode)27) && !ModSettingsScreen.IsExiting) { Plugin.Log.LogInfo((object)"Escape pressed in Settings, returning to SS Manager"); MainMenuHook.ReturnFromSettingsScreen(); } } } } namespace SilksongManager.Menu.Keybinds { public enum ModAction { ToggleDebugMenu, ToggleNoclip, NoclipSpeedBoost, ToggleInvincibility, ToggleInfiniteJumps, ToggleInfiniteHealth, ToggleInfiniteSilk, SavePosition, LoadPosition, KillAllEnemies, FreezeEnemies, AddGeo, AddShellShards, MaxSilk, HealToFull, IncreaseGameSpeed, DecreaseGameSpeed, ResetGameSpeed, ToggleHitboxes, SaveState, LoadLastState, ReloadScene, Respawn } public static class ModKeybindManager { private static Dictionary> _keybindConfigs; private static bool _initialized = false; public static readonly Dictionary DefaultKeybinds = new Dictionary { { ModAction.ToggleDebugMenu, (KeyCode)261 }, { ModAction.ToggleNoclip, (KeyCode)110 }, { ModAction.NoclipSpeedBoost, (KeyCode)304 }, { ModAction.ToggleInvincibility, (KeyCode)105 }, { ModAction.ToggleInfiniteJumps, (KeyCode)106 }, { ModAction.ToggleInfiniteHealth, (KeyCode)0 }, { ModAction.ToggleInfiniteSilk, (KeyCode)0 }, { ModAction.SavePosition, (KeyCode)286 }, { ModAction.LoadPosition, (KeyCode)290 }, { ModAction.KillAllEnemies, (KeyCode)107 }, { ModAction.FreezeEnemies, (KeyCode)102 }, { ModAction.AddGeo, (KeyCode)103 }, { ModAction.AddShellShards, (KeyCode)104 }, { ModAction.MaxSilk, (KeyCode)0 }, { ModAction.HealToFull, (KeyCode)0 }, { ModAction.IncreaseGameSpeed, (KeyCode)61 }, { ModAction.DecreaseGameSpeed, (KeyCode)45 }, { ModAction.ResetGameSpeed, (KeyCode)48 }, { ModAction.ToggleHitboxes, (KeyCode)285 }, { ModAction.SaveState, (KeyCode)287 }, { ModAction.LoadLastState, (KeyCode)288 }, { ModAction.ReloadScene, (KeyCode)289 }, { ModAction.Respawn, (KeyCode)114 } }; public static readonly Dictionary ActionNames = new Dictionary { { ModAction.ToggleDebugMenu, "Debug Menu" }, { ModAction.ToggleNoclip, "Noclip" }, { ModAction.NoclipSpeedBoost, "Noclip Speed Boost" }, { ModAction.ToggleInvincibility, "Invincibility" }, { ModAction.ToggleInfiniteJumps, "Infinite Jumps" }, { ModAction.ToggleInfiniteHealth, "Infinite Health" }, { ModAction.ToggleInfiniteSilk, "Infinite Silk" }, { ModAction.SavePosition, "Save Position" }, { ModAction.LoadPosition, "Load Position" }, { ModAction.KillAllEnemies, "Kill All Enemies" }, { ModAction.FreezeEnemies, "Freeze Enemies" }, { ModAction.AddGeo, "Add Geo" }, { ModAction.AddShellShards, "Add Shell Shards" }, { ModAction.MaxSilk, "Max Silk" }, { ModAction.HealToFull, "Heal to Full" }, { ModAction.IncreaseGameSpeed, "Speed Up" }, { ModAction.DecreaseGameSpeed, "Speed Down" }, { ModAction.ResetGameSpeed, "Reset Speed" }, { ModAction.ToggleHitboxes, "Show Hitboxes" }, { ModAction.SaveState, "Quick Save" }, { ModAction.LoadLastState, "Quick Load" }, { ModAction.ReloadScene, "Reload Scene" }, { ModAction.Respawn, "Respawn" } }; public static void Initialize(ConfigFile config) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (_initialized) { return; } _keybindConfigs = new Dictionary>(); foreach (ModAction value2 in Enum.GetValues(typeof(ModAction))) { KeyCode val = (KeyCode)(DefaultKeybinds.ContainsKey(value2) ? ((int)DefaultKeybinds[value2]) : 0); ConfigEntry value = config.Bind("Keybinds", value2.ToString(), val, "Keybind for " + GetActionName(value2)); _keybindConfigs[value2] = value; } _initialized = true; Plugin.Log.LogInfo((object)$"ModKeybindManager initialized with {_keybindConfigs.Count} keybinds"); } public static KeyCode GetKeybind(ModAction action) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!_initialized || !_keybindConfigs.ContainsKey(action)) { if (!DefaultKeybinds.ContainsKey(action)) { return (KeyCode)0; } return DefaultKeybinds[action]; } return _keybindConfigs[action].Value; } public static void SetKeybind(ModAction action, KeyCode key) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (_initialized && _keybindConfigs.ContainsKey(action)) { _keybindConfigs[action].Value = key; Plugin.Log.LogInfo((object)$"Set keybind for {action} to {key}"); } } public static string GetActionName(ModAction action) { if (!ActionNames.ContainsKey(action)) { return action.ToString(); } return ActionNames[action]; } public static bool IsModKeybindConflicting(KeyCode key, ModAction excludeAction, out ModAction conflictingAction) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) conflictingAction = ModAction.ToggleDebugMenu; if ((int)key == 0) { return false; } foreach (ModAction value in Enum.GetValues(typeof(ModAction))) { if (value != excludeAction && GetKeybind(value) == key) { conflictingAction = value; return true; } } return false; } public static bool IsGameKeybindConflicting(KeyCode key, out string gameActionName) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) gameActionName = null; if ((int)key == 0) { return false; } try { GameManager instance = GameManager.instance; InputHandler val = ((instance != null) ? instance.inputHandler : null); if ((Object)(object)val == (Object)null) { return false; } Key val2 = KeyCodeToInControlKey(key); if ((int)val2 == 0) { return false; } foreach (PlayerAction mappableKeyboardAction in val.MappableKeyboardActions) { KeyOrMouseBinding keyBindingForAction = val.GetKeyBindingForAction(mappableKeyboardAction); if (!KeyOrMouseBinding.IsNone(keyBindingForAction) && keyBindingForAction.Key == val2) { gameActionName = mappableKeyboardAction.Name; return true; } } } catch { } return false; } public static void ResetToDefaults() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) foreach (ModAction value in Enum.GetValues(typeof(ModAction))) { KeyCode key = (KeyCode)(DefaultKeybinds.ContainsKey(value) ? ((int)DefaultKeybinds[value]) : 0); SetKeybind(value, key); } Plugin.Log.LogInfo((object)"All keybinds reset to defaults"); } public static bool WasActionPressed(ModAction action) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) KeyCode keybind = GetKeybind(action); if ((int)keybind != 0) { return Input.GetKeyDown(keybind); } return false; } public static bool IsKeyHeld(ModAction action) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) KeyCode keybind = GetKeybind(action); if ((int)keybind != 0) { return Input.GetKey(keybind); } return false; } private static Key KeyCodeToInControlKey(KeyCode keyCode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected I4, but got Unknown //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected I4, but got Unknown //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected I4, but got Unknown //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) if ((int)keyCode <= 32) { if ((int)keyCode == 9) { return (Key)66; } if ((int)keyCode == 32) { return (Key)76; } } else { switch (keyCode - 48) { case 0: return (Key)26; case 1: return (Key)27; case 2: return (Key)28; case 3: return (Key)29; case 4: return (Key)30; case 5: return (Key)31; case 6: return (Key)32; case 7: return (Key)33; case 8: return (Key)34; case 9: return (Key)35; } switch (keyCode - 97) { case 0: return (Key)36; case 1: return (Key)37; case 2: return (Key)38; case 3: return (Key)39; case 4: return (Key)40; case 5: return (Key)41; case 6: return (Key)42; case 7: return (Key)43; case 8: return (Key)44; case 9: return (Key)45; case 10: return (Key)46; case 11: return (Key)47; case 12: return (Key)48; case 13: return (Key)49; case 14: return (Key)50; case 15: return (Key)51; case 16: return (Key)52; case 17: return (Key)53; case 18: return (Key)54; case 19: return (Key)55; case 20: return (Key)56; case 21: return (Key)57; case 22: return (Key)58; case 23: return (Key)59; case 24: return (Key)60; case 25: return (Key)61; } switch (keyCode - 282) { case 22: return (Key)5; case 21: return (Key)9; case 24: return (Key)8; case 23: return (Key)12; case 26: return (Key)6; case 25: return (Key)10; case 0: return (Key)14; case 1: return (Key)15; case 2: return (Key)16; case 3: return (Key)17; case 4: return (Key)18; case 5: return (Key)19; case 6: return (Key)20; case 7: return (Key)21; case 8: return (Key)22; case 9: return (Key)23; case 10: return (Key)24; case 11: return (Key)25; } } return (Key)0; } } public static class ModKeybindsScreen { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnBackButtonPressed; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__12_0; internal void b__12_0() { ModKeybindManager.ResetToDefaults(); RefreshAllDisplays(); } } private static MenuScreen _keybindsMenuScreen; private static List _mappableEntries = new List(); private static bool _initialized = false; private static bool _isActive = false; private static ModMappableKeyEntry _pendingEntry; private static KeyCode _pendingKeyCode; private static MenuButton _resetButton; private static ScrollRect _scrollRect; private static Scrollbar _scrollbar; private static Font _gameFont; private static bool _isExiting = false; public static bool IsActive => _isActive; public static bool IsExiting => _isExiting; public static void Initialize() { if (_initialized) { return; } try { CreateFromKeyboardMenu(); _initialized = true; Plugin.Log.LogInfo((object)"ModKeybindsScreen initialized from keyboard menu"); } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to initialize ModKeybindsScreen: {arg}"); } } public static void Reset() { _initialized = false; _keybindsMenuScreen = null; _mappableEntries.Clear(); _isActive = false; } public static MenuScreen GetScreen() { return _keybindsMenuScreen; } private static void CreateFromKeyboardMenu() { UIManager instance = UIManager.instance; if ((Object)(object)instance == (Object)null) { Plugin.Log.LogError((object)"UIManager not found!"); return; } MenuScreen extrasMenuScreen = instance.extrasMenuScreen; if ((Object)(object)extrasMenuScreen == (Object)null) { Plugin.Log.LogError((object)"ExtrasMenuScreen not found!"); return; } Plugin.Log.LogInfo((object)("Creating ModKeybindsScreen from " + ((Object)extrasMenuScreen).name)); GameObject val = Object.Instantiate(((Component)extrasMenuScreen).gameObject, ((Component)extrasMenuScreen).transform.parent); ((Object)val).name = "ModKeybindsMenuScreen"; _keybindsMenuScreen = val.GetComponent(); if ((Object)(object)_keybindsMenuScreen == (Object)null) { Object.Destroy((Object)(object)val); Plugin.Log.LogError((object)"Cloned screen doesn't have MenuScreen!"); return; } MenuButtonList component = val.GetComponent(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); Plugin.Log.LogInfo((object)"Removed MenuButtonList from cloned screen"); } val.SetActive(false); CanvasGroup component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.alpha = 0f; component2.interactable = false; component2.blocksRaycasts = false; } ModifyClonedScreen(val); Plugin.Log.LogInfo((object)"Mod keybinds screen created successfully"); } private static void ModifyClonedScreen(GameObject screenObj) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Expected O, but got Unknown //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Expected O, but got Unknown //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Unknown result type (might be due to invalid IL or missing references) MenuButton backButton = _keybindsMenuScreen.backButton; if ((Object)(object)backButton != (Object)null) { ((Component)backButton).transform.SetParent(screenObj.transform, false); ((Component)backButton).gameObject.SetActive(false); } List list = new List(); Transform val = null; Transform val2 = null; foreach (Transform item in screenObj.transform) { Transform val3 = item; if (!((Object)(object)backButton != (Object)null) || !((Object)(object)val3 == (Object)(object)((Component)backButton).transform)) { string text = ((Object)val3).name.ToLower(); if (text.Contains("title")) { val = val3; } else if (text.Contains("fleur")) { val2 = val3; } else { list.Add(((Component)val3).gameObject); } } } foreach (GameObject item2 in list) { Object.DestroyImmediate((Object)(object)item2); } if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(true); DestroyLocalization(((Component)val).gameObject); Text component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { component.text = "Silksong Manager Keybinds"; _gameFont = component.font; } } if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(true); } UIButtonSkins uiButtonSkins = UIManager.instance.uiButtonSkins; MappableKey templateKey = null; if ((Object)(object)uiButtonSkins != (Object)null && (Object)(object)uiButtonSkins.mappableKeyboardButtons != (Object)null) { templateKey = ((Component)uiButtonSkins.mappableKeyboardButtons).GetComponentInChildren(true); } CreateContentContainer(screenObj.transform, templateKey); if ((Object)(object)backButton != (Object)null) { ((Component)backButton).gameObject.SetActive(true); backButton.OnSubmitPressed = new UnityEvent(); UnityEvent onSubmitPressed = backButton.OnSubmitPressed; object obj = <>O.<0>__OnBackButtonPressed; if (obj == null) { UnityAction val4 = OnBackButtonPressed; <>O.<0>__OnBackButtonPressed = val4; obj = (object)val4; } onSubmitPressed.AddListener((UnityAction)obj); DestroyLocalization(((Component)backButton).gameObject); RectTransform component2 = ((Component)backButton).GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.anchorMin = new Vector2(0.5f, 0f); component2.anchorMax = new Vector2(0.5f, 0f); component2.pivot = new Vector2(0.5f, 0.5f); component2.anchoredPosition = new Vector2(0f, 60f); } if (_mappableEntries.Count > 0) { ModMappableKeyEntry modMappableKeyEntry = _mappableEntries[_mappableEntries.Count - 1]; Navigation navigation = ((Selectable)backButton).navigation; ((Navigation)(ref navigation)).mode = (Mode)4; ((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)modMappableKeyEntry.button; ((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)_mappableEntries[0].button; ((Selectable)backButton).navigation = navigation; } } if ((Object)(object)backButton != (Object)null) { GameObject obj2 = Object.Instantiate(((Component)backButton).gameObject, ((Component)backButton).transform.parent); ((Object)obj2).name = "ResetButton"; obj2.SetActive(true); MenuButton component3 = obj2.GetComponent(); if ((Object)(object)component3 != (Object)null) { component3.OnSubmitPressed = new UnityEvent(); UnityEvent onSubmitPressed2 = component3.OnSubmitPressed; object obj3 = <>c.<>9__12_0; if (obj3 == null) { UnityAction val5 = delegate { ModKeybindManager.ResetToDefaults(); RefreshAllDisplays(); }; <>c.<>9__12_0 = val5; obj3 = (object)val5; } onSubmitPressed2.AddListener((UnityAction)obj3); } Text componentInChildren = obj2.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = "RESET TO DEFAULTS"; } RectTransform component4 = obj2.GetComponent(); if ((Object)(object)component4 != (Object)null) { component4.anchorMin = new Vector2(0.5f, 0f); component4.anchorMax = new Vector2(0.5f, 0f); component4.pivot = new Vector2(0.5f, 0.5f); component4.anchoredPosition = new Vector2(0f, 120f); } _resetButton = component3; } if (_mappableEntries.Count > 0) { _keybindsMenuScreen.defaultHighlight = (Selectable)(object)_mappableEntries[0].button; } } private static GameObject CreateContentContainer(Transform parent, MappableKey templateKey) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Expected O, but got Unknown //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ScrollArea"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.05f, 0.22f); obj.anchorMax = new Vector2(0.95f, 0.82f); obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; GameObject val2 = new GameObject("Viewport"); val2.transform.SetParent(val.transform, false); RectTransform val3 = val2.AddComponent(); val3.anchorMin = Vector2.zero; val3.anchorMax = new Vector2(0.96f, 1f); val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; val2.AddComponent(); ((Graphic)val2.AddComponent()).color = Color.clear; GameObject val4 = new GameObject("Content"); val4.transform.SetParent(val2.transform, false); RectTransform val5 = val4.AddComponent(); val5.anchorMin = new Vector2(0f, 1f); val5.anchorMax = new Vector2(1f, 1f); val5.pivot = new Vector2(0.5f, 1f); val5.anchoredPosition = Vector2.zero; ContentSizeFitter obj2 = val4.AddComponent(); obj2.verticalFit = (FitMode)2; obj2.horizontalFit = (FitMode)0; VerticalLayoutGroup obj3 = val4.AddComponent(); ((LayoutGroup)obj3).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)obj3).spacing = 10f; ((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = true; ((LayoutGroup)obj3).padding = new RectOffset(0, 0, 10, 10); ModAction[] array = (ModAction[])Enum.GetValues(typeof(ModAction)); int num = (array.Length + 1) / 2; _mappableEntries.Clear(); for (int i = 0; i < num; i++) { GameObject val6 = new GameObject($"Row_{i}"); val6.transform.SetParent(val4.transform, false); RectTransform obj4 = val6.AddComponent(); obj4.anchorMin = new Vector2(0f, 1f); obj4.anchorMax = new Vector2(1f, 1f); obj4.pivot = new Vector2(0.5f, 1f); LayoutElement obj5 = val6.AddComponent(); obj5.preferredHeight = 60f; obj5.minHeight = 60f; GameObject val7 = new GameObject("LeftHalf"); val7.transform.SetParent(val6.transform, false); RectTransform obj6 = val7.AddComponent(); obj6.anchorMin = new Vector2(0f, 0f); obj6.anchorMax = new Vector2(0.4f, 1f); obj6.offsetMin = Vector2.zero; obj6.offsetMax = Vector2.zero; obj6.pivot = new Vector2(1f, 0.5f); ModMappableKeyEntry item = CreateKeybindEntry(val7.transform, array[i], templateKey, (TextAnchor)5); _mappableEntries.Add(item); int num2 = i + num; if (num2 < array.Length) { GameObject val8 = new GameObject("RightHalf"); val8.transform.SetParent(val6.transform, false); RectTransform obj7 = val8.AddComponent(); obj7.anchorMin = new Vector2(0.6f, 0f); obj7.anchorMax = new Vector2(1f, 1f); obj7.offsetMin = Vector2.zero; obj7.offsetMax = Vector2.zero; obj7.pivot = new Vector2(0f, 0.5f); ModMappableKeyEntry item2 = CreateKeybindEntry(val8.transform, array[num2], templateKey, (TextAnchor)3); _mappableEntries.Add(item2); } if (i == 0) { Plugin.Log.LogInfo((object)"[KeybindsLayout] Row_0 created. LeftHalf anchors: min(0,0) max(0.45,1), RightHalf anchors: min(0.55,0) max(1,1)"); } } Plugin.Log.LogInfo((object)$"[KeybindsLayout] Created {num} rows with {_mappableEntries.Count} entries"); _scrollbar = CloneAchievementsScrollbar(val.transform); _scrollRect = val.AddComponent(); _scrollRect.content = val5; _scrollRect.viewport = val3; _scrollRect.horizontal = false; _scrollRect.vertical = true; _scrollRect.movementType = (MovementType)2; _scrollRect.scrollSensitivity = 30f; _scrollRect.inertia = true; _scrollRect.decelerationRate = 0.135f; if ((Object)(object)_scrollbar != (Object)null) { _scrollRect.verticalScrollbar = _scrollbar; _scrollRect.verticalScrollbarVisibility = (ScrollbarVisibility)2; _scrollRect.verticalScrollbarSpacing = -5f; } SetupNavigation(); return val; } private static Scrollbar CloneAchievementsScrollbar(Transform parent) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) try { MenuScreen achievementsMenuScreen = UIManager.instance.achievementsMenuScreen; if ((Object)(object)achievementsMenuScreen == (Object)null) { Plugin.Log.LogWarning((object)"Achievements screen not found, creating default scrollbar"); return CreateDefaultScrollbar(parent); } Scrollbar componentInChildren = ((Component)achievementsMenuScreen).GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { Plugin.Log.LogWarning((object)"Scrollbar not found in achievements screen, creating default"); return CreateDefaultScrollbar(parent); } GameObject obj = Object.Instantiate(((Component)componentInChildren).gameObject, parent); ((Object)obj).name = "Scrollbar"; obj.SetActive(true); RectTransform component = obj.GetComponent(); component.anchorMin = new Vector2(0.97f, 0.05f); component.anchorMax = new Vector2(1f, 0.95f); component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; Scrollbar component2 = obj.GetComponent(); component2.direction = (Direction)2; Plugin.Log.LogInfo((object)"Cloned scrollbar from achievements screen"); return component2; } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to clone scrollbar: " + ex.Message)); return CreateDefaultScrollbar(parent); } } private static Scrollbar CreateDefaultScrollbar(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Scrollbar"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.97f, 0.05f); obj.anchorMax = new Vector2(1f, 0.95f); obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; ((Graphic)val.AddComponent()).color = new Color(0.2f, 0.2f, 0.2f, 0.5f); GameObject val2 = new GameObject("Handle"); val2.transform.SetParent(val.transform, false); RectTransform val3 = val2.AddComponent(); val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = new Vector2(2f, 2f); val3.offsetMax = new Vector2(-2f, -2f); Image val4 = val2.AddComponent(); ((Graphic)val4).color = new Color(0.7f, 0.7f, 0.7f, 0.8f); Scrollbar obj2 = val.AddComponent(); obj2.handleRect = val3; ((Selectable)obj2).targetGraphic = (Graphic)(object)val4; obj2.direction = (Direction)2; return obj2; } private static ModMappableKeyEntry CreateKeybindEntry(Transform parent, ModAction action, MappableKey templateKey, TextAnchor alignment) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Expected O, but got Unknown //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Expected O, but got Unknown GameObject val = new GameObject($"Entry_{action}"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; HorizontalLayoutGroup obj2 = val.AddComponent(); ((LayoutGroup)obj2).childAlignment = alignment; ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 15f; ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false; ((LayoutGroup)obj2).padding = new RectOffset(5, 5, 0, 0); GameObject val2 = new GameObject("Label"); val2.transform.SetParent(val.transform, false); val2.AddComponent().sizeDelta = new Vector2(250f, 45f); LayoutElement obj3 = val2.AddComponent(); obj3.preferredWidth = 250f; obj3.flexibleWidth = 0f; Text obj4 = val2.AddComponent(); obj4.font = GetGameFont(); obj4.fontSize = 42; obj4.fontStyle = (FontStyle)0; obj4.alignment = (TextAnchor)5; ((Graphic)obj4).color = Color.white; obj4.text = ModKeybindManager.GetActionName(action).ToUpper(); obj4.horizontalOverflow = (HorizontalWrapMode)1; GameObject val3 = new GameObject("KeyButton"); val3.transform.SetParent(val.transform, false); val3.AddComponent().sizeDelta = new Vector2(90f, 55f); LayoutElement obj5 = val3.AddComponent(); obj5.preferredWidth = 90f; obj5.preferredHeight = 55f; obj5.flexibleWidth = 0f; UIButtonSkins val4 = UIManager.instance?.uiButtonSkins; Image val5 = val3.AddComponent(); val5.sprite = val4?.squareKey; ((Graphic)val5).color = Color.white; val5.type = (Type)1; GameObject val6 = new GameObject("Text"); val6.transform.SetParent(val3.transform, false); RectTransform obj6 = val6.AddComponent(); obj6.anchorMin = Vector2.zero; obj6.anchorMax = Vector2.one; obj6.offsetMin = Vector2.zero; obj6.offsetMax = Vector2.zero; Text val7 = val6.AddComponent(); val7.font = GetGameFont(); val7.fontSize = 34; val7.fontStyle = (FontStyle)1; val7.alignment = (TextAnchor)4; ((Graphic)val7).color = Color.white; MenuButton val8 = val3.AddComponent(); val8.OnSubmitPressed = new UnityEvent(); ModMappableKeyEntry entry = new ModMappableKeyEntry { action = action, button = val8, keyText = val7, keyBg = val5, isListening = false }; val8.OnSubmitPressed.AddListener((UnityAction)delegate { OnKeyEntryClicked(entry); }); UpdateEntryDisplay(entry); return entry; } private static void SetupNavigation() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) int count = _mappableEntries.Count; int num = (count + 1) / 2; for (int i = 0; i < count; i++) { ModMappableKeyEntry modMappableKeyEntry = _mappableEntries[i]; Navigation navigation = ((Selectable)modMappableKeyEntry.button).navigation; ((Navigation)(ref navigation)).mode = (Mode)4; bool flag = i % 2 == 0; int num2 = i / 2; if (flag) { int num3 = i + 1; if (num3 < count) { ((Navigation)(ref navigation)).selectOnRight = (Selectable)(object)_mappableEntries[num3].button; } } else { ((Navigation)(ref navigation)).selectOnLeft = (Selectable)(object)_mappableEntries[i - 1].button; } if (num2 > 0) { int num4 = (num2 - 1) * 2 + ((!flag) ? 1 : 0); if (num4 < count) { ((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)_mappableEntries[num4].button; } } else if ((Object)(object)_keybindsMenuScreen.backButton != (Object)null) { ((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)_keybindsMenuScreen.backButton; } if (num2 < num - 1) { int num5 = (num2 + 1) * 2 + ((!flag) ? 1 : 0); if (num5 < count) { ((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)_mappableEntries[num5].button; } else if ((num2 + 1) * 2 < count) { ((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)_mappableEntries[(num2 + 1) * 2].button; } } else if ((Object)(object)_resetButton != (Object)null) { ((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)_resetButton; } ((Selectable)modMappableKeyEntry.button).navigation = navigation; } if ((Object)(object)_resetButton != (Object)null) { Navigation navigation2 = ((Selectable)_resetButton).navigation; ((Navigation)(ref navigation2)).mode = (Mode)4; if (count > 0) { int index = (count - 1) / 2 * 2; ((Navigation)(ref navigation2)).selectOnUp = (Selectable)(object)_mappableEntries[index].button; } if ((Object)(object)_keybindsMenuScreen.backButton != (Object)null) { ((Navigation)(ref navigation2)).selectOnDown = (Selectable)(object)_keybindsMenuScreen.backButton; } ((Selectable)_resetButton).navigation = navigation2; } if ((Object)(object)_keybindsMenuScreen.backButton != (Object)null) { Navigation navigation3 = ((Selectable)_keybindsMenuScreen.backButton).navigation; if ((Object)(object)_resetButton != (Object)null) { ((Navigation)(ref navigation3)).selectOnUp = (Selectable)(object)_resetButton; } else if (count > 0) { ((Navigation)(ref navigation3)).selectOnUp = (Selectable)(object)_mappableEntries[0].button; } if (count > 0) { ((Navigation)(ref navigation3)).selectOnDown = (Selectable)(object)_mappableEntries[0].button; } ((Selectable)_keybindsMenuScreen.backButton).navigation = navigation3; } } private static void OnKeyEntryClicked(ModMappableKeyEntry entry) { if (!entry.isListening) { entry.isListening = true; entry.keyText.text = "..."; ((MonoBehaviour)UIManager.instance).StartCoroutine(ListenForKey(entry)); } } private static IEnumerator ListenForKey(ModMappableKeyEntry entry) { yield return null; yield return null; while (entry.isListening) { if (Input.GetKeyDown((KeyCode)27)) { entry.isListening = false; UpdateEntryDisplay(entry); break; } foreach (KeyCode value in Enum.GetValues(typeof(KeyCode))) { if ((int)value != 0 && (int)value != 323 && (int)value != 324 && (int)value != 27 && Input.GetKeyDown(value)) { entry.isListening = false; HandleKeySelected(entry, value); yield break; } } yield return null; } } private static void HandleKeySelected(ModMappableKeyEntry entry, KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (ModKeybindManager.IsModKeybindConflicting(key, entry.action, out var conflictingAction)) { ModKeybindManager.SetKeybind(conflictingAction, (KeyCode)0); RefreshAllDisplays(); } ModKeybindManager.SetKeybind(entry.action, key); UpdateEntryDisplay(entry); } private static void UpdateEntryDisplay(ModMappableKeyEntry entry) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) KeyCode keybind = ModKeybindManager.GetKeybind(entry.action); entry.keyText.text = KeyCodeToShortString(keybind); UIButtonSkins val = UIManager.instance?.uiButtonSkins; if ((Object)(object)val != (Object)null) { if ((int)keybind == 0) { entry.keyBg.sprite = val.blankKey; } else if (IsWideKey(keybind)) { entry.keyBg.sprite = val.rectangleKey; } else { entry.keyBg.sprite = val.squareKey; } } } private static void RefreshAllDisplays() { foreach (ModMappableKeyEntry mappableEntry in _mappableEntries) { UpdateEntryDisplay(mappableEntry); } } private static void OnBackButtonPressed() { Plugin.Log.LogInfo((object)"Back from Keybinds screen"); MainMenuHook.ReturnFromKeybindsScreen(); } private static Font GetGameFont() { if ((Object)(object)_gameFont != (Object)null) { return _gameFont; } Text val = Object.FindAnyObjectByType(); if ((Object)(object)val != (Object)null) { return val.font; } return Resources.GetBuiltinResource("LegacyRuntime.ttf"); } private static void DestroyLocalization(GameObject obj) { if ((Object)(object)obj == (Object)null) { return; } MonoBehaviour[] componentsInChildren = obj.GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val != (Object)null && ((object)val).GetType().Name.Contains("Locali")) { Object.DestroyImmediate((Object)(object)val); } } } private static bool IsWideKey(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 if ((int)key != 32 && (int)key != 9 && (int)key != 13 && (int)key != 304 && (int)key != 303 && (int)key != 306 && (int)key != 305 && (int)key != 308 && (int)key != 307) { return (int)key == 8; } return true; } private unsafe static string KeyCodeToShortString(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected I4, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected I4, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected I4, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 if ((int)key == 0) { return "---"; } if ((int)key <= 27) { if ((int)key <= 9) { if ((int)key == 8) { return "Bksp"; } if ((int)key == 9) { return "Tab"; } } else { if ((int)key == 13) { return "Enter"; } if ((int)key == 27) { return "Esc"; } } } else if ((int)key <= 57) { if ((int)key == 32) { return "Space"; } switch (key - 48) { case 0: return "0"; case 1: return "1"; case 2: return "2"; case 3: return "3"; case 4: return "4"; case 5: return "5"; case 6: return "6"; case 7: return "7"; case 8: return "8"; case 9: return "9"; } } else { switch (key - 256) { case 0: return "Num0"; case 1: return "Num1"; case 2: return "Num2"; case 3: return "Num3"; case 4: return "Num4"; case 5: return "Num5"; case 6: return "Num6"; case 7: return "Num7"; case 8: return "Num8"; case 9: return "Num9"; } switch (key - 303) { case 1: return "LShift"; case 0: return "RShift"; case 3: return "LCtrl"; case 2: return "RCtrl"; } } return (((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString().Length > 5) ? ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString().Substring(0, 5) : ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); } public static IEnumerator Show(UIManager ui) { if ((Object)(object)_keybindsMenuScreen == (Object)null) { Plugin.Log.LogError((object)"Keybinds screen not initialized!"); yield break; } _isActive = true; RefreshAllDisplays(); MainMenuHook.HideMainMenu(ui); CanvasGroup cg = ((Component)_keybindsMenuScreen).GetComponent(); ((Component)_keybindsMenuScreen).gameObject.SetActive(true); KeybindsInputController keybindsInputController = ((Component)_keybindsMenuScreen).gameObject.GetComponent(); if ((Object)(object)keybindsInputController == (Object)null) { keybindsInputController = ((Component)_keybindsMenuScreen).gameObject.AddComponent(); } ((Behaviour)keybindsInputController).enabled = true; if ((Object)(object)cg != (Object)null) { cg.interactable = true; cg.blocksRaycasts = true; float alpha = 0f; while (alpha < 1f) { alpha = (cg.alpha = alpha + Time.unscaledDeltaTime * 4f); yield return null; } cg.alpha = 1f; } if (_mappableEntries.Count > 0) { EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject(((Component)_mappableEntries[0].button).gameObject); } } Plugin.Log.LogInfo((object)"Keybinds screen shown"); } public static IEnumerator Hide(UIManager ui) { if ((Object)(object)_keybindsMenuScreen == (Object)null) { yield break; } _isExiting = true; CanvasGroup cg = ((Component)_keybindsMenuScreen).GetComponent(); if ((Object)(object)cg != (Object)null) { float alpha = 1f; while (alpha > 0f) { alpha = (cg.alpha = alpha - Time.unscaledDeltaTime * 4f); yield return null; } cg.alpha = 0f; cg.interactable = false; cg.blocksRaycasts = false; } ((Component)_keybindsMenuScreen).gameObject.SetActive(false); _isActive = false; _isExiting = false; } } internal class ModMappableKeyEntry { public ModAction action; public MenuButton button; public Text keyText; public Image keyBg; public bool isListening; } public class KeybindsInputController : MonoBehaviour { private void Update() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) if (!ModKeybindsScreen.IsActive) { return; } UIManager instance = UIManager.instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.mainMenuScreen != (Object)null && ((Component)instance.mainMenuScreen).gameObject.activeSelf) { ((Component)instance.mainMenuScreen).gameObject.SetActive(false); if ((Object)(object)instance.gameTitle != (Object)null && (instance.gameTitle.color.a > 0.1f || ((Renderer)instance.gameTitle).enabled)) { instance.gameTitle.color = new Color(instance.gameTitle.color.r, instance.gameTitle.color.g, instance.gameTitle.color.b, 0f); ((Renderer)instance.gameTitle).enabled = false; } } if (Input.GetKeyDown((KeyCode)27) && !ModKeybindsScreen.IsExiting) { Plugin.Log.LogInfo((object)"Escape pressed in keybinds menu, returning to SS Manager"); MainMenuHook.ReturnFromKeybindsScreen(); } } } } namespace SilksongManager.Inventory { public enum SilkAbility { Dash, Walljump, DoubleJump, SuperJump, SilkSpecial, NeedleThrow, ThreadSphere, Parry, HarpoonDash, SilkCharge, SilkBomb, Needolin } public static class AbilityActions { private static readonly Dictionary AbilityNames = new Dictionary { { SilkAbility.Dash, "Dash" }, { SilkAbility.Walljump, "Wall Jump" }, { SilkAbility.DoubleJump, "Double Jump" }, { SilkAbility.SuperJump, "Super Jump" }, { SilkAbility.SilkSpecial, "Silk Special" }, { SilkAbility.NeedleThrow, "Needle Throw" }, { SilkAbility.ThreadSphere, "Thread Sphere" }, { SilkAbility.Parry, "Parry" }, { SilkAbility.HarpoonDash, "Harpoon Dash" }, { SilkAbility.SilkCharge, "Silk Charge" }, { SilkAbility.SilkBomb, "Silk Bomb" }, { SilkAbility.Needolin, "Needolin" } }; public static bool GrantAbility(SilkAbility ability) { PlayerData pD = Plugin.PD; if (pD == null) { return false; } SetAbilityState(pD, ability, state: true); Plugin.Log.LogInfo((object)("Granted ability: " + GetAbilityName(ability))); return true; } public static bool RevokeAbility(SilkAbility ability) { PlayerData pD = Plugin.PD; if (pD == null) { return false; } SetAbilityState(pD, ability, state: false); Plugin.Log.LogInfo((object)("Revoked ability: " + GetAbilityName(ability))); return true; } public static void GrantAllAbilities() { PlayerData pD = Plugin.PD; if (pD == null) { return; } foreach (SilkAbility value in Enum.GetValues(typeof(SilkAbility))) { SetAbilityState(pD, value, state: true); } Plugin.Log.LogInfo((object)"Granted all abilities."); } public static void RevokeAllAbilities() { PlayerData pD = Plugin.PD; if (pD == null) { return; } foreach (SilkAbility value in Enum.GetValues(typeof(SilkAbility))) { SetAbilityState(pD, value, state: false); } Plugin.Log.LogInfo((object)"Revoked all abilities."); } public static List GetAllAbilities() { List list = new List(); PlayerData pD = Plugin.PD; foreach (SilkAbility value in Enum.GetValues(typeof(SilkAbility))) { list.Add(new AbilityInfo { Ability = value, Name = GetAbilityName(value), IsUnlocked = (pD != null && GetAbilityState(pD, value)) }); } return list; } public static bool HasAbility(SilkAbility ability) { PlayerData pD = Plugin.PD; if (pD != null) { return GetAbilityState(pD, ability); } return false; } public static string GetAbilityName(SilkAbility ability) { if (!AbilityNames.TryGetValue(ability, out var value)) { return ability.ToString(); } return value; } private static bool GetAbilityState(PlayerData pd, SilkAbility ability) { return ability switch { SilkAbility.Dash => pd.hasDash, SilkAbility.Walljump => pd.hasWalljump, SilkAbility.DoubleJump => pd.hasDoubleJump, SilkAbility.SuperJump => pd.hasSuperJump, SilkAbility.SilkSpecial => pd.hasSilkSpecial, SilkAbility.NeedleThrow => pd.hasNeedleThrow, SilkAbility.ThreadSphere => pd.hasThreadSphere, SilkAbility.Parry => pd.hasParry, SilkAbility.HarpoonDash => pd.hasHarpoonDash, SilkAbility.SilkCharge => pd.hasSilkCharge, SilkAbility.SilkBomb => pd.hasSilkBomb, SilkAbility.Needolin => pd.hasNeedolin, _ => false, }; } private static void SetAbilityState(PlayerData pd, SilkAbility ability, bool state) { switch (ability) { case SilkAbility.Dash: pd.hasDash = state; break; case SilkAbility.Walljump: pd.hasWalljump = state; break; case SilkAbility.DoubleJump: pd.hasDoubleJump = state; break; case SilkAbility.SuperJump: pd.hasSuperJump = state; break; case SilkAbility.SilkSpecial: pd.hasSilkSpecial = state; break; case SilkAbility.NeedleThrow: pd.hasNeedleThrow = state; break; case SilkAbility.ThreadSphere: pd.hasThreadSphere = state; break; case SilkAbility.Parry: pd.hasParry = state; break; case SilkAbility.HarpoonDash: pd.hasHarpoonDash = state; break; case SilkAbility.SilkCharge: pd.hasSilkCharge = state; break; case SilkAbility.SilkBomb: pd.hasSilkBomb = state; break; case SilkAbility.Needolin: pd.hasNeedolin = state; break; } } } public struct AbilityInfo { public SilkAbility Ability; public string Name; public bool IsUnlocked; } public static class CrestActions { public const string HunterCrestName = "Hunter"; public static bool UnlockCrest(string crestName) { ToolCrest crestByName = ToolItemManager.GetCrestByName(crestName); if ((Object)(object)crestByName == (Object)null) { Plugin.Log.LogWarning((object)("Crest not found: " + crestName)); return false; } crestByName.Unlock(); Plugin.Log.LogInfo((object)("Unlocked crest: " + crestName)); return true; } public static bool LockCrest(string crestName) { PlayerData pD = Plugin.PD; if (pD == null) { return false; } ToolCrest baseCrest = GetBaseCrest(crestName); if ((Object)(object)baseCrest == (Object)null) { Plugin.Log.LogWarning((object)("Crest not found: " + crestName)); return false; } if (baseCrest.name.StartsWith("Hunter")) { ResetCrestToInitialState(baseCrest.name); Plugin.Log.LogInfo((object)"Reset Hunter crest to initial state"); return true; } LockCrestChain(baseCrest.name); if (pD.CurrentCrestID != null && pD.CurrentCrestID.StartsWith(crestName)) { EquipCrest("Hunter"); } Plugin.Log.LogInfo((object)("Locked crest: " + crestName)); return true; } public static void UnlockAllCrests() { ToolItemManager.UnlockAllCrests(); Plugin.Log.LogInfo((object)"Unlocked all crests."); } public static void ResetAllCrests() { if (Plugin.PD == null) { return; } foreach (ToolCrest allCrest in ToolItemManager.GetAllCrests()) { if (!((Object)(object)allCrest == (Object)null)) { if (GetBaseCrestName(allCrest.name) == "Hunter") { ResetCrestToInitialState(allCrest.name); } else { LockCrestChain(allCrest.name); } } } EquipCrest("Hunter"); Plugin.Log.LogInfo((object)"Reset all crests."); } public static bool EquipCrest(string crestName) { ToolCrest val = ToolItemManager.GetCrestByName(crestName); if ((Object)(object)val == (Object)null) { val = ((IEnumerable)ToolItemManager.GetAllCrests()).FirstOrDefault((Func)((ToolCrest c) => (Object)(object)c != (Object)null && c.name.StartsWith(crestName))); } if ((Object)(object)val == (Object)null || !val.IsUnlocked) { Plugin.Log.LogWarning((object)("Cannot equip crest: " + crestName + " (not found or not unlocked)")); return false; } ToolItemManager.SetEquippedCrest(val.name); Plugin.Log.LogInfo((object)("Equipped crest: " + val.name)); return true; } public static string GetEquippedCrestName() { return Plugin.PD?.CurrentCrestID ?? ""; } public static List GetAllCrests() { List list = new List(); List allCrests = ToolItemManager.GetAllCrests(); HashSet hashSet = new HashSet(); foreach (ToolCrest item in allCrests) { if (!((Object)(object)item == (Object)null)) { string baseCrestName = GetBaseCrestName(item.name); if (!hashSet.Contains(baseCrestName)) { hashSet.Add(baseCrestName); ToolCrest highestUnlockedVersion = GetHighestUnlockedVersion(baseCrestName); bool isUnlocked = (Object)(object)highestUnlockedVersion != (Object)null; list.Add(new CrestInfo { Name = baseCrestName, DisplayName = baseCrestName, IsUnlocked = isUnlocked, CurrentVersion = (((highestUnlockedVersion != null) ? highestUnlockedVersion.name : null) ?? baseCrestName), IsEquipped = (Plugin.PD?.CurrentCrestID?.StartsWith(baseCrestName) == true) }); } } } return list; } public static bool IsCrestUnlocked(string crestName) { ToolCrest val = ToolItemManager.GetCrestByName(crestName); if ((Object)(object)val == (Object)null) { val = ((IEnumerable)ToolItemManager.GetAllCrests()).FirstOrDefault((Func)((ToolCrest c) => (Object)(object)c != (Object)null && c.name.StartsWith(crestName) && c.IsUnlocked)); } if (val == null) { return false; } return val.IsUnlocked; } private static string GetBaseCrestName(string crestName) { int num = crestName.LastIndexOf('_'); if (num > 0 && crestName.Length > num + 1) { string text = crestName.Substring(num + 1); if (text.StartsWith("V") && text.Length > 1) { return crestName.Substring(0, num); } } return crestName; } private static ToolCrest GetBaseCrest(string crestName) { List allCrests = ToolItemManager.GetAllCrests(); string baseName = GetBaseCrestName(crestName); foreach (ToolCrest item in allCrests) { if ((Object)(object)item != (Object)null && item.name.StartsWith(baseName) && item.IsBaseVersion) { return item; } } return ((IEnumerable)allCrests).FirstOrDefault((Func)((ToolCrest c) => (Object)(object)c != (Object)null && c.name.StartsWith(baseName))); } private static ToolCrest GetHighestUnlockedVersion(string baseName) { List allCrests = ToolItemManager.GetAllCrests(); ToolCrest val = null; foreach (ToolCrest item in allCrests) { if (!((Object)(object)item == (Object)null) && item.name.StartsWith(baseName) && item.IsUnlocked && ((Object)(object)val == (Object)null || item.name.Length > val.name.Length)) { val = item; } } return val; } private static void ResetCrestToInitialState(string crestName) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) PlayerData pD = Plugin.PD; if (pD == null) { return; } string baseCrestName = GetBaseCrestName(crestName); foreach (ToolCrest allCrest in ToolItemManager.GetAllCrests()) { if (!((Object)(object)allCrest == (Object)null) && allCrest.name.StartsWith(baseCrestName) && !allCrest.IsBaseVersion) { Data data = ((SerializableNamedList)(object)pD.ToolEquips).GetData(allCrest.name); data.IsUnlocked = false; ((SerializableNamedList)(object)pD.ToolEquips).SetData(allCrest.name, data); } } } private static void LockCrestChain(string crestName) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) PlayerData pD = Plugin.PD; if (pD == null) { return; } string baseCrestName = GetBaseCrestName(crestName); foreach (ToolCrest allCrest in ToolItemManager.GetAllCrests()) { if (!((Object)(object)allCrest == (Object)null) && allCrest.name.StartsWith(baseCrestName)) { Data data = ((SerializableNamedList)(object)pD.ToolEquips).GetData(allCrest.name); data.IsUnlocked = false; ((SerializableNamedList)(object)pD.ToolEquips).SetData(allCrest.name, data); } } } } public struct CrestInfo { public string Name; public string DisplayName; public bool IsUnlocked; public string CurrentVersion; public bool IsEquipped; } } namespace SilksongManager.Hitbox { public static class Drawing { private static Texture2D _whiteTexture; public static Texture2D WhiteTexture { get { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_whiteTexture == (Object)null) { _whiteTexture = new Texture2D(1, 1); _whiteTexture.SetPixel(0, 0, Color.white); _whiteTexture.Apply(); } return _whiteTexture; } } public static void DrawLine(Vector2 pointA, Vector2 pointB, Color color, float width) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Atan2(pointB.y - pointA.y, pointB.x - pointA.x) * 57.29578f; float num2 = Vector2.Distance(pointA, pointB); Matrix4x4 matrix = GUI.matrix; GUIUtility.RotateAroundPivot(num, pointA); GUI.color = color; GUI.DrawTexture(new Rect(pointA.x, pointA.y, num2, width), (Texture)(object)WhiteTexture); GUI.color = Color.white; GUI.matrix = matrix; } public static void DrawHollowRect(Rect rect, Color color, float width) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) DrawLine(new Vector2(((Rect)(ref rect)).x, ((Rect)(ref rect)).y), new Vector2(((Rect)(ref rect)).x + ((Rect)(ref rect)).width, ((Rect)(ref rect)).y), color, width); DrawLine(new Vector2(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + ((Rect)(ref rect)).height), new Vector2(((Rect)(ref rect)).x + ((Rect)(ref rect)).width, ((Rect)(ref rect)).y + ((Rect)(ref rect)).height), color, width); DrawLine(new Vector2(((Rect)(ref rect)).x, ((Rect)(ref rect)).y), new Vector2(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + ((Rect)(ref rect)).height), color, width); DrawLine(new Vector2(((Rect)(ref rect)).x + ((Rect)(ref rect)).width, ((Rect)(ref rect)).y), new Vector2(((Rect)(ref rect)).x + ((Rect)(ref rect)).width, ((Rect)(ref rect)).y + ((Rect)(ref rect)).height), color, width); } public static void DrawCircle(Vector2 center, float radius, Color color, float width, int segments = 32) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) float num = 360f / (float)segments; Vector2 pointA = center + new Vector2(radius, 0f); for (int i = 1; i <= segments; i++) { float num2 = (float)i * num * (MathF.PI / 180f); Vector2 val = center + new Vector2(Mathf.Cos(num2) * radius, Mathf.Sin(num2) * radius); DrawLine(pointA, val, color, width); pointA = val; } } } public enum HitboxLayer { Player, Enemy, Attack, Terrain, Trigger, Hazard, Breakable, Interactive } public static class HitboxConfig { public static bool ShowHitboxes = false; public static bool ShowPlayer = true; public static bool ShowEnemy = true; public static bool ShowAttack = true; public static bool ShowTerrain = true; public static bool ShowTrigger = false; public static bool ShowHazard = true; public static bool ShowBreakable = true; public static bool ShowInteractive = true; public static Color PlayerColor = Color.green; public static Color EnemyColor = Color.red; public static Color AttackColor = Color.yellow; public static Color TerrainColor = Color.grey; public static Color TriggerColor = Color.cyan; public static Color HazardColor = new Color(1f, 0.5f, 0f); public static Color BreakableColor = Color.magenta; public static Color InteractiveColor = Color.blue; public static float LineThickness = 2f; public static bool FillHitboxes = false; public static float FillAlpha = 0.2f; } public static class HitboxManager { private static HitboxRenderer _renderer; public static void Initialize(GameObject host) { if ((Object)(object)_renderer == (Object)null) { _renderer = host.AddComponent(); Plugin.Log.LogInfo((object)"Hitbox system initialized."); } } public static void ToggleHitboxes() { HitboxConfig.ShowHitboxes = !HitboxConfig.ShowHitboxes; } } public class HitboxRenderer : MonoBehaviour { private List _visibleColliders = new List(); private Camera _cam; private void Start() { _cam = Camera.main; } private void Update() { if (HitboxConfig.ShowHitboxes) { if ((Object)(object)_cam == (Object)null) { _cam = Camera.main; } if (!((Object)(object)_cam == (Object)null)) { UpdateVisibleColliders(); } } } private void UpdateVisibleColliders() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) _visibleColliders.Clear(); float num = 2f * _cam.orthographicSize; float num2 = num * _cam.aspect; Vector2 val = Vector2.op_Implicit(((Component)_cam).transform.position); Vector2 val2 = new Vector2(num2, num) * 1.1f; Vector2 val3 = val - val2 / 2f; Vector2 val4 = val + val2 / 2f; Collider2D[] collection = Physics2D.OverlapAreaAll(val3, val4); _visibleColliders.AddRange(collection); } private void OnGUI() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (!HitboxConfig.ShowHitboxes || (int)Event.current.type != 7 || (Object)(object)_cam == (Object)null) { return; } foreach (Collider2D visibleCollider in _visibleColliders) { if (!((Object)(object)visibleCollider == (Object)null) && ((Behaviour)visibleCollider).enabled && ((Component)visibleCollider).gameObject.activeInHierarchy) { HitboxLayer layer = ClassifyCollider(visibleCollider); if (ShouldShow(layer)) { DrawCollider(visibleCollider, GetColor(layer)); } } } } private HitboxLayer ClassifyCollider(Collider2D col) { switch (((Component)col).gameObject.layer) { case 9: case 20: return HitboxLayer.Player; case 11: return HitboxLayer.Enemy; case 12: case 17: case 22: return HitboxLayer.Attack; case 8: case 25: return HitboxLayer.Terrain; case 23: return HitboxLayer.Hazard; case 19: return HitboxLayer.Interactive; case 29: return HitboxLayer.Trigger; default: if (col.isTrigger) { return HitboxLayer.Trigger; } return HitboxLayer.Terrain; } } private bool ShouldShow(HitboxLayer layer) { return layer switch { HitboxLayer.Player => HitboxConfig.ShowPlayer, HitboxLayer.Enemy => HitboxConfig.ShowEnemy, HitboxLayer.Attack => HitboxConfig.ShowAttack, HitboxLayer.Terrain => HitboxConfig.ShowTerrain, HitboxLayer.Trigger => HitboxConfig.ShowTrigger, HitboxLayer.Hazard => HitboxConfig.ShowHazard, HitboxLayer.Breakable => HitboxConfig.ShowBreakable, HitboxLayer.Interactive => HitboxConfig.ShowInteractive, _ => false, }; } private Color GetColor(HitboxLayer layer) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) return (Color)(layer switch { HitboxLayer.Player => HitboxConfig.PlayerColor, HitboxLayer.Enemy => HitboxConfig.EnemyColor, HitboxLayer.Attack => HitboxConfig.AttackColor, HitboxLayer.Terrain => HitboxConfig.TerrainColor, HitboxLayer.Trigger => HitboxConfig.TriggerColor, HitboxLayer.Hazard => HitboxConfig.HazardColor, HitboxLayer.Breakable => HitboxConfig.BreakableColor, HitboxLayer.Interactive => HitboxConfig.InteractiveColor, _ => Color.white, }); } private void DrawCollider(Collider2D col, Color color) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) BoxCollider2D val = (BoxCollider2D)(object)((col is BoxCollider2D) ? col : null); if (val != null) { DrawBoxCollider(val, color); return; } CircleCollider2D val2 = (CircleCollider2D)(object)((col is CircleCollider2D) ? col : null); if (val2 != null) { DrawCircleCollider(val2, color); return; } PolygonCollider2D val3 = (PolygonCollider2D)(object)((col is PolygonCollider2D) ? col : null); if (val3 != null) { DrawPolygonCollider(val3, color); return; } EdgeCollider2D val4 = (EdgeCollider2D)(object)((col is EdgeCollider2D) ? col : null); if (val4 != null) { DrawEdgeCollider(val4, color); } } private Vector2 WorldToGUIPoint(Vector3 worldPos) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) Vector3 val = _cam.WorldToScreenPoint(worldPos); return new Vector2(val.x, (float)Screen.height - val.y); } private void DrawBoxCollider(BoxCollider2D box, Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) Vector2 offset = ((Collider2D)box).offset; Vector2 val = box.size * 0.5f; Vector2 val2 = offset + new Vector2(0f - val.x, 0f - val.y); Vector2 val3 = offset + new Vector2(val.x, 0f - val.y); Vector2 val4 = offset + new Vector2(val.x, val.y); Vector2 val5 = offset + new Vector2(0f - val.x, val.y); Transform transform = ((Component)box).transform; Vector2 val6 = Vector2.op_Implicit(transform.TransformPoint(Vector2.op_Implicit(val2))); Vector2 val7 = Vector2.op_Implicit(transform.TransformPoint(Vector2.op_Implicit(val3))); Vector2 val8 = Vector2.op_Implicit(transform.TransformPoint(Vector2.op_Implicit(val4))); Vector2 val9 = Vector2.op_Implicit(transform.TransformPoint(Vector2.op_Implicit(val5))); Vector2 val10 = WorldToGUIPoint(Vector2.op_Implicit(val6)); Vector2 val11 = WorldToGUIPoint(Vector2.op_Implicit(val7)); Vector2 val12 = WorldToGUIPoint(Vector2.op_Implicit(val8)); Vector2 val13 = WorldToGUIPoint(Vector2.op_Implicit(val9)); Drawing.DrawLine(val10, val11, color, HitboxConfig.LineThickness); Drawing.DrawLine(val11, val12, color, HitboxConfig.LineThickness); Drawing.DrawLine(val12, val13, color, HitboxConfig.LineThickness); Drawing.DrawLine(val13, val10, color, HitboxConfig.LineThickness); } private void DrawCircleCollider(CircleCollider2D circle, Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) Vector2 offset = ((Collider2D)circle).offset; Transform transform = ((Component)circle).transform; Vector2 val = Vector2.op_Implicit(transform.TransformPoint(Vector2.op_Implicit(offset))); float num = circle.radius * Mathf.Max(Mathf.Abs(transform.lossyScale.x), Mathf.Abs(transform.lossyScale.y)); Vector2 val2 = WorldToGUIPoint(Vector2.op_Implicit(val)); Vector3 worldPos = Vector2.op_Implicit(val + new Vector2(num, 0f)); Vector2 val3 = WorldToGUIPoint(worldPos); float radius = Vector2.Distance(val2, val3); Drawing.DrawCircle(val2, radius, color, HitboxConfig.LineThickness); } private void DrawPolygonCollider(PolygonCollider2D poly, Color color) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)poly).transform; for (int i = 0; i < poly.pathCount; i++) { Vector2[] path = poly.GetPath(i); for (int j = 0; j < path.Length; j++) { Vector2 val = path[j]; Vector2 val2 = path[(j + 1) % path.Length]; Vector2 val3 = Vector2.op_Implicit(transform.TransformPoint(Vector2.op_Implicit(val + ((Collider2D)poly).offset))); Vector2 val4 = Vector2.op_Implicit(transform.TransformPoint(Vector2.op_Implicit(val2 + ((Collider2D)poly).offset))); Drawing.DrawLine(WorldToGUIPoint(Vector2.op_Implicit(val3)), WorldToGUIPoint(Vector2.op_Implicit(val4)), color, HitboxConfig.LineThickness); } } } private void DrawEdgeCollider(EdgeCollider2D edge, Color color) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)edge).transform; Vector2[] points = edge.points; if (points != null && points.Length >= 2) { for (int i = 0; i < points.Length - 1; i++) { Vector2 val = points[i]; Vector2 val2 = points[i + 1]; Vector2 val3 = Vector2.op_Implicit(transform.TransformPoint(Vector2.op_Implicit(val + ((Collider2D)edge).offset))); Vector2 val4 = Vector2.op_Implicit(transform.TransformPoint(Vector2.op_Implicit(val2 + ((Collider2D)edge).offset))); Drawing.DrawLine(WorldToGUIPoint(Vector2.op_Implicit(val3)), WorldToGUIPoint(Vector2.op_Implicit(val4)), color, HitboxConfig.LineThickness); } } } } } namespace SilksongManager.Enemies { public static class EnemyActions { private static bool _enemiesFrozen; public static bool AreEnemiesFrozen => _enemiesFrozen; public static int GetEnemyCount() { HealthManager[] array = Object.FindObjectsOfType(); int num = 0; HealthManager[] array2 = array; foreach (HealthManager val in array2) { if ((Object)(object)val != (Object)null && !val.GetIsDead()) { num++; } } return num; } public static void FreezeEnemies(bool freeze) { if (freeze) { FreezeAllEnemies(); } else { UnfreezeAllEnemies(); } _enemiesFrozen = freeze; } public static List FindAllEnemies() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) List list = new List(); HealthManager[] array = Object.FindObjectsOfType(); foreach (HealthManager val in array) { if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null) { list.Add(new EnemyInfo { Name = ((Object)((Component)val).gameObject).name, Position = ((Component)val).transform.position, CurrentHP = val.hp, MaxHP = val.hp, IsAlive = !val.GetIsDead(), GameObject = ((Component)val).gameObject }); } } return list; } public static void KillAllEnemies() { HealthManager[] array = Object.FindObjectsOfType(); int num = 0; HealthManager[] array2 = array; foreach (HealthManager val in array2) { if ((Object)(object)val != (Object)null && !val.GetIsDead()) { val.Die((float?)0f, (AttackTypes)1, false); num++; } } Plugin.Log.LogInfo((object)$"Killed {num} enemies."); } public static void DamageAllEnemies(int damage) { HealthManager[] array = Object.FindObjectsOfType(); foreach (HealthManager val in array) { if ((Object)(object)val != (Object)null && !val.GetIsDead()) { val.ApplyExtraDamage(damage); } } Plugin.Log.LogInfo((object)$"Dealt {damage} damage to all enemies."); } public static void FreezeAllEnemies() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) HealthManager[] array = Object.FindObjectsOfType(); foreach (HealthManager val in array) { if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null) { Animator[] componentsInChildren = ((Component)val).GetComponentsInChildren(); for (int j = 0; j < componentsInChildren.Length; j++) { componentsInChildren[j].speed = 0f; } Rigidbody2D[] componentsInChildren2 = ((Component)val).GetComponentsInChildren(); foreach (Rigidbody2D obj in componentsInChildren2) { obj.linearVelocity = Vector2.zero; obj.simulated = false; } } } Plugin.Log.LogInfo((object)"Froze all enemies."); } public static void UnfreezeAllEnemies() { HealthManager[] array = Object.FindObjectsOfType(); foreach (HealthManager val in array) { if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null) { Animator[] componentsInChildren = ((Component)val).GetComponentsInChildren(); for (int j = 0; j < componentsInChildren.Length; j++) { componentsInChildren[j].speed = 1f; } Rigidbody2D[] componentsInChildren2 = ((Component)val).GetComponentsInChildren(); for (int j = 0; j < componentsInChildren2.Length; j++) { componentsInChildren2[j].simulated = true; } } } Plugin.Log.LogInfo((object)"Unfroze all enemies."); } public static void KillEnemy(int index) { List list = FindAllEnemies(); if (index >= 0 && index < list.Count) { HealthManager component = list[index].GameObject.GetComponent(); if ((Object)(object)component != (Object)null) { component.Die((float?)0f, (AttackTypes)1, false); Plugin.Log.LogInfo((object)("Killed enemy: " + list[index].Name)); } } } } public struct EnemyInfo { public string Name; public Vector3 Position; public int CurrentHP; public int MaxHP; public bool IsAlive; public GameObject GameObject; } } namespace SilksongManager.DebugMenu { public static class DebugMenuConfig { public enum OpacityMode { BackgroundOnly, FullMenu } public struct WindowState { public Vector2 Position; public Vector2 Size; public bool IsVisible; public override string ToString() { return string.Format(CultureInfo.InvariantCulture, "{0:F0},{1:F0},{2:F0},{3:F0},{4}", Position.x, Position.y, Size.x, Size.y, IsVisible ? 1 : 0); } public static WindowState Parse(string s, Vector2 defaultPos, Vector2 defaultSize) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) WindowState result = new WindowState { Position = defaultPos, Size = defaultSize, IsVisible = false }; if (string.IsNullOrEmpty(s)) { return result; } string[] array = s.Split(','); if (array.Length >= 5) { CultureInfo invariantCulture = CultureInfo.InvariantCulture; if (float.TryParse(array[0], NumberStyles.Float, invariantCulture, out var result2)) { result.Position.x = result2; } if (float.TryParse(array[1], NumberStyles.Float, invariantCulture, out var result3)) { result.Position.y = result3; } if (float.TryParse(array[2], NumberStyles.Float, invariantCulture, out var result4)) { result.Size.x = Mathf.Max(200f, result4); } if (float.TryParse(array[3], NumberStyles.Float, invariantCulture, out var result5)) { result.Size.y = Mathf.Max(150f, result5); } if (int.TryParse(array[4], out var result6)) { result.IsVisible = result6 == 1; } } return result; } } private static ConfigFile _config; private static ConfigEntry _backgroundOpacity; private static ConfigEntry _fullMenuOpacity; private static ConfigEntry _opacityMode; private static ConfigEntry _pauseGameOnMenu; private static Dictionary> _windowStates = new Dictionary>(); private static bool _initialized = false; public static float BackgroundOpacity { get { return _backgroundOpacity?.Value ?? 0.9f; } set { if (_backgroundOpacity != null) { _backgroundOpacity.Value = value; } } } public static float FullMenuOpacity { get { return _fullMenuOpacity?.Value ?? 1f; } set { if (_fullMenuOpacity != null) { _fullMenuOpacity.Value = value; } } } public static OpacityMode CurrentOpacityMode { get { return _opacityMode?.Value ?? OpacityMode.BackgroundOnly; } set { if (_opacityMode != null) { _opacityMode.Value = value; } } } public static bool PauseGameOnMenu { get { return _pauseGameOnMenu?.Value ?? false; } set { if (_pauseGameOnMenu != null) { _pauseGameOnMenu.Value = value; } } } public static Vector2 MainWindowPosition { get { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return GetWindowState(10001).Position; } set { //IL_0005: Unknown result type (might be due to invalid IL or missing references) SaveWindowPosition(10001, value); } } public static void Initialize(ConfigFile config) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown if (!_initialized) { _config = config; _backgroundOpacity = config.Bind("DebugMenu", "BackgroundOpacity", 0.9f, new ConfigDescription("Opacity of window backgrounds (0-1)", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); _fullMenuOpacity = config.Bind("DebugMenu", "FullMenuOpacity", 1f, new ConfigDescription("Opacity of entire menu including text (0-1)", (AcceptableValueBase)(object)new AcceptableValueRange(0.3f, 1f), Array.Empty())); _opacityMode = config.Bind("DebugMenu", "OpacityMode", OpacityMode.BackgroundOnly, "Whether transparency applies to background only or entire menu"); _pauseGameOnMenu = config.Bind("DebugMenu", "PauseGameOnMenu", false, "Pause the game when debug menu is opened"); _initialized = true; } } public static float GetEffectiveAlpha() { if (CurrentOpacityMode != OpacityMode.FullMenu) { return 1f; } return FullMenuOpacity; } public static float GetBackgroundAlpha() { return BackgroundOpacity; } public static WindowState GetWindowState(int windowId) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) return GetWindowState(windowId, new Vector2(20f, 20f), new Vector2(280f, 300f)); } public static WindowState GetWindowState(int windowId, Vector2 defaultPos, Vector2 defaultSize) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) if (_config == null) { return new WindowState { Position = defaultPos, Size = defaultSize, IsVisible = false }; } if (!_windowStates.TryGetValue(windowId, out var value)) { value = _config.Bind("DebugMenu.WindowStates", $"Window_{windowId}", "", $"State for window {windowId}: x,y,width,height,visible"); _windowStates[windowId] = value; } return WindowState.Parse(value.Value, defaultPos, defaultSize); } public static void SaveWindowState(int windowId, Rect rect, bool isVisible) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (_config != null) { if (!_windowStates.TryGetValue(windowId, out var value)) { value = _config.Bind("DebugMenu.WindowStates", $"Window_{windowId}", "", $"State for window {windowId}: x,y,width,height,visible"); _windowStates[windowId] = value; } WindowState windowState = new WindowState { Position = new Vector2(((Rect)(ref rect)).x, ((Rect)(ref rect)).y), Size = new Vector2(((Rect)(ref rect)).width, ((Rect)(ref rect)).height), IsVisible = isVisible }; value.Value = windowState.ToString(); } } public static void SaveWindowPosition(int windowId, Vector2 pos) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) WindowState windowState = GetWindowState(windowId); windowState.Position = pos; if (_windowStates.TryGetValue(windowId, out var value)) { value.Value = windowState.ToString(); } } } public class DebugMenuController : MonoBehaviour { private bool _isVisible; private bool _previousCursorVisible; private CursorLockMode _previousCursorLockState; private float _previousTimeScale = 1f; private bool _pausedByUs; private static FieldInfo _controllerPressedField; private static bool _reflectionInitialized; private List _windows; private MainWindow _mainWindow; public bool IsVisible => _isVisible; private void Awake() { DebugMenuConfig.Initialize(Plugin.ModConfig.ConfigFile); InitializeReflection(); _windows = new List(); _mainWindow = new MainWindow(this); _windows.Add(_mainWindow); _windows.Add(new PlayerWindow()); _windows.Add(new WorldWindow()); _windows.Add(new EnemiesWindow()); _windows.Add(new InventoryWindow()); _windows.Add(new KeybindsWindow()); _windows.Add(new SettingsWindow()); _windows.Add(new DebugInfoWindow()); _windows.Add(new CombatWindow()); _windows.Add(new HitboxWindow()); _windows.Add(new SaveStateWindow()); _windows.Add(new SpeedControlWindow()); Plugin.Log.LogInfo((object)("DebugMenuController initialized with " + _windows.Count + " windows")); } private static void InitializeReflection() { if (_reflectionInitialized) { return; } try { _controllerPressedField = typeof(InputHandler).GetField("_controllerPressed", BindingFlags.Static | BindingFlags.NonPublic); if (_controllerPressedField != null) { Plugin.Log.LogInfo((object)"Found InputHandler._controllerPressed field for cursor fix"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not find _controllerPressed field: " + ex.Message)); } _reflectionInitialized = true; } private void Update() { foreach (BaseWindow window in _windows) { window.Update(); } } private void LateUpdate() { if (_isVisible) { ForceCursorVisible(); } } private void ForceCursorVisible() { Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; try { if (_controllerPressedField != null) { _controllerPressedField.SetValue(null, false); } } catch { } try { UIManager instance = UIManager.instance; if ((Object)(object)instance?.inputModule != (Object)null) { instance.inputModule.allowMouseInput = true; } } catch { } } private void OnGUI() { if (!_isVisible) { return; } Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; DebugMenuStyles.EnsureInitialized(); foreach (BaseWindow window in _windows) { window.Draw(); } } public void ToggleMenu() { if (_isVisible) { HideMenu(); } else { ShowMenu(); } } public void ShowMenu() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (_isVisible) { return; } _isVisible = true; _previousCursorVisible = Cursor.visible; _previousCursorLockState = Cursor.lockState; _previousTimeScale = Time.timeScale; ForceCursorVisible(); if (DebugMenuConfig.PauseGameOnMenu) { _pausedByUs = true; Time.timeScale = 0f; } else { _pausedByUs = false; } foreach (BaseWindow window in _windows) { if (window == _mainWindow) { window.IsVisible = true; } else { window.IsVisible = DebugMenuConfig.GetWindowState(window.WindowId).IsVisible; } } Plugin.Log.LogInfo((object)"Debug menu opened"); } public void HideMenu() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!_isVisible) { return; } _isVisible = false; foreach (BaseWindow window in _windows) { window.SaveState(); } Cursor.visible = _previousCursorVisible; Cursor.lockState = _previousCursorLockState; if (_pausedByUs && Time.timeScale == 0f) { Time.timeScale = ((_previousTimeScale > 0f) ? _previousTimeScale : 1f); _pausedByUs = false; } foreach (BaseWindow window2 in _windows) { window2.IsVisible = false; } Plugin.Log.LogInfo((object)"Debug menu closed"); } public T GetWindow() where T : BaseWindow { foreach (BaseWindow window in _windows) { if (window is T result) { return result; } } return null; } public void ToggleWindow() where T : BaseWindow { GetWindow()?.Toggle(); } } public static class DebugMenuStyles { public static readonly Color BackgroundDark = Color32.op_Implicit(new Color32((byte)26, (byte)26, (byte)26, byte.MaxValue)); public static readonly Color BackgroundMedium = Color32.op_Implicit(new Color32((byte)35, (byte)35, (byte)35, byte.MaxValue)); public static readonly Color BackgroundLight = Color32.op_Implicit(new Color32((byte)50, (byte)50, (byte)50, byte.MaxValue)); public static readonly Color AccentRed = Color32.op_Implicit(new Color32((byte)192, (byte)57, (byte)43, byte.MaxValue)); public static readonly Color AccentRedHover = Color32.op_Implicit(new Color32((byte)231, (byte)76, (byte)60, byte.MaxValue)); public static readonly Color AccentRedActive = Color32.op_Implicit(new Color32((byte)155, (byte)45, (byte)35, byte.MaxValue)); public static readonly Color TextLight = Color32.op_Implicit(new Color32((byte)236, (byte)240, (byte)241, byte.MaxValue)); public static readonly Color TextMuted = Color32.op_Implicit(new Color32((byte)127, (byte)140, (byte)141, byte.MaxValue)); public static readonly Color TextDisabled = Color32.op_Implicit(new Color32((byte)100, (byte)100, (byte)100, byte.MaxValue)); public static readonly Color BorderGray = Color32.op_Implicit(new Color32((byte)52, (byte)73, (byte)94, byte.MaxValue)); public static readonly Color SeparatorDark = Color32.op_Implicit(new Color32((byte)40, (byte)40, (byte)40, byte.MaxValue)); public static readonly Color StatusOn = Color32.op_Implicit(new Color32((byte)39, (byte)174, (byte)96, byte.MaxValue)); public static readonly Color StatusOff = Color32.op_Implicit(new Color32((byte)192, (byte)57, (byte)43, byte.MaxValue)); public static readonly Color StatusWarning = Color32.op_Implicit(new Color32((byte)241, (byte)196, (byte)15, byte.MaxValue)); private static Texture2D _backgroundTex; private static Texture2D _buttonNormalTex; private static Texture2D _buttonHoverTex; private static Texture2D _buttonActiveTex; private static Texture2D _windowTex; private static Texture2D _headerTex; private static Texture2D _sliderBgTex; private static Texture2D _sliderFillTex; private static GUIStyle _windowStyle; private static GUIStyle _headerStyle; private static GUIStyle _labelStyle; private static GUIStyle _labelBoldStyle; private static GUIStyle _labelCenteredStyle; private static GUIStyle _labelSmallStyle; private static GUIStyle _buttonStyle; private static GUIStyle _buttonSmallStyle; private static GUIStyle _toggleStyle; private static GUIStyle _toggleOnStyle; private static GUIStyle _textFieldStyle; private static GUIStyle _boxStyle; private static GUIStyle _keybindStyle; private static GUIStyle _keybindListeningStyle; private static GUIStyle _statusOnStyle; private static GUIStyle _statusOffStyle; private static GUIStyle _closeButtonStyle; private static GUIStyle _sectionStyle; private static bool _stylesInitialized = false; public static Texture2D BackgroundTex => _backgroundTex ?? (_backgroundTex = MakeTexture(2, 2, BackgroundDark)); public static Texture2D ButtonNormalTex => _buttonNormalTex ?? (_buttonNormalTex = MakeTexture(2, 2, BackgroundLight)); public static Texture2D ButtonHoverTex => _buttonHoverTex ?? (_buttonHoverTex = MakeTexture(2, 2, AccentRed)); public static Texture2D ButtonActiveTex => _buttonActiveTex ?? (_buttonActiveTex = MakeTexture(2, 2, AccentRedActive)); public static Texture2D WindowTex => _windowTex ?? (_windowTex = MakeTexture(2, 2, BackgroundMedium)); public static Texture2D HeaderTex => _headerTex ?? (_headerTex = MakeTexture(2, 2, AccentRed)); public static Texture2D SliderBgTex => _sliderBgTex ?? (_sliderBgTex = MakeTexture(2, 2, BackgroundDark)); public static Texture2D SliderFillTex => _sliderFillTex ?? (_sliderFillTex = MakeTexture(2, 2, AccentRed)); public static GUIStyle Window => _windowStyle; public static GUIStyle Header => _headerStyle; public static GUIStyle Label => _labelStyle; public static GUIStyle LabelSmall => _labelSmallStyle; public static GUIStyle LabelBold => _labelBoldStyle; public static GUIStyle LabelCentered => _labelCenteredStyle; public static GUIStyle Button => _buttonStyle; public static GUIStyle ButtonSmall => _buttonSmallStyle; public static GUIStyle Toggle => _toggleStyle; public static GUIStyle ToggleOn => _toggleOnStyle; public static GUIStyle TextField => _textFieldStyle; public static GUIStyle Box => _boxStyle; public static GUIStyle Keybind => _keybindStyle; public static GUIStyle KeybindListening => _keybindListeningStyle; public static GUIStyle StatusOnStyle => _statusOnStyle; public static GUIStyle StatusOffStyle => _statusOffStyle; public static GUIStyle CloseButton => _closeButtonStyle; public static GUIStyle Section => _sectionStyle; private static Texture2D MakeTexture(int width, int height, Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(width, height); Color[] array = (Color[])(object)new Color[width * height]; for (int i = 0; i < array.Length; i++) { array[i] = color; } val.SetPixels(array); val.Apply(); return val; } public static void EnsureInitialized() { if (!_stylesInitialized) { InitializeStyles(); _stylesInitialized = true; } } private static void InitializeStyles() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00c7: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Expected O, but got Unknown //IL_0198: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Expected O, but got Unknown //IL_024a: Expected O, but got Unknown //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Expected O, but got Unknown //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Expected O, but got Unknown //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Expected O, but got Unknown //IL_02c2: Expected O, but got Unknown //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Expected O, but got Unknown //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Expected O, but got Unknown //IL_0344: Expected O, but got Unknown //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Expected O, but got Unknown //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Expected O, but got Unknown //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Expected O, but got Unknown //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Expected O, but got Unknown //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Expected O, but got Unknown //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Expected O, but got Unknown //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_0461: Expected O, but got Unknown //IL_0466: Expected O, but got Unknown //IL_0470: Unknown result type (might be due to invalid IL or missing references) _windowStyle = new GUIStyle(GUI.skin.window) { padding = new RectOffset(8, 8, 24, 8), border = new RectOffset(4, 4, 4, 4), contentOffset = Vector2.zero }; _windowStyle.normal.background = WindowTex; _windowStyle.normal.textColor = TextLight; _windowStyle.onNormal.background = WindowTex; _windowStyle.onNormal.textColor = TextLight; _headerStyle = new GUIStyle(GUI.skin.label) { fontSize = 16, fontStyle = (FontStyle)1, alignment = (TextAnchor)4, padding = new RectOffset(0, 0, 4, 4) }; _headerStyle.normal.textColor = TextLight; _labelStyle = new GUIStyle(GUI.skin.label) { fontSize = 13, wordWrap = true }; _labelStyle.normal.textColor = TextLight; _labelBoldStyle = new GUIStyle(_labelStyle) { fontStyle = (FontStyle)1 }; _labelCenteredStyle = new GUIStyle(_labelStyle) { alignment = (TextAnchor)4 }; _labelSmallStyle = new GUIStyle(_labelStyle) { fontSize = 11 }; _buttonStyle = new GUIStyle(GUI.skin.button) { fontSize = 13, fontStyle = (FontStyle)0, padding = new RectOffset(12, 12, 6, 6), margin = new RectOffset(2, 2, 2, 2) }; _buttonStyle.normal.background = ButtonNormalTex; _buttonStyle.normal.textColor = TextLight; _buttonStyle.hover.background = ButtonHoverTex; _buttonStyle.hover.textColor = TextLight; _buttonStyle.active.background = ButtonActiveTex; _buttonStyle.active.textColor = TextLight; _buttonStyle.focused = _buttonStyle.normal; _buttonSmallStyle = new GUIStyle(_buttonStyle) { fontSize = 11, padding = new RectOffset(8, 8, 4, 4) }; _toggleStyle = new GUIStyle(_buttonStyle) { alignment = (TextAnchor)4 }; _toggleOnStyle = new GUIStyle(_toggleStyle); _toggleOnStyle.normal.background = ButtonHoverTex; _toggleOnStyle.normal.textColor = TextLight; _textFieldStyle = new GUIStyle(GUI.skin.textField) { fontSize = 13, padding = new RectOffset(6, 6, 4, 4) }; _textFieldStyle.normal.background = BackgroundTex; _textFieldStyle.normal.textColor = TextLight; _textFieldStyle.focused.background = ButtonNormalTex; _textFieldStyle.focused.textColor = TextLight; _boxStyle = new GUIStyle(GUI.skin.box) { padding = new RectOffset(8, 8, 8, 8), margin = new RectOffset(0, 0, 4, 4) }; _boxStyle.normal.background = BackgroundTex; _keybindStyle = new GUIStyle(_buttonSmallStyle) { alignment = (TextAnchor)4, fixedWidth = 80f }; _keybindListeningStyle = new GUIStyle(_keybindStyle); _keybindListeningStyle.normal.background = ButtonHoverTex; _keybindListeningStyle.normal.textColor = TextLight; _statusOnStyle = new GUIStyle(_labelBoldStyle); _statusOnStyle.normal.textColor = StatusOn; _statusOffStyle = new GUIStyle(_labelBoldStyle); _statusOffStyle.normal.textColor = StatusOff; _closeButtonStyle = new GUIStyle(_buttonSmallStyle) { fontSize = 14, fontStyle = (FontStyle)1, fixedWidth = 24f, fixedHeight = 24f, padding = new RectOffset(0, 0, 0, 0), alignment = (TextAnchor)4 }; _sectionStyle = new GUIStyle(_labelBoldStyle) { fontSize = 14, padding = new RectOffset(4, 4, 8, 4) }; _sectionStyle.normal.textColor = AccentRed; } public static void DrawSeparator() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) GUILayout.Space(4f); EditorDrawLine(GUILayoutUtility.GetRect(1f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }), SeparatorDark); GUILayout.Space(4f); } private static void EditorDrawLine(Rect rect, Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Color color2 = GUI.color; GUI.color = color; GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture); GUI.color = color2; } public static void DrawSectionHeader(string title) { GUILayout.Space(8f); GUILayout.Label(title, Section, Array.Empty()); DrawSeparator(); } public static void DrawStatus(string label, bool isOn) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(label, Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }); GUILayout.Label(isOn ? "ON" : "OFF", isOn ? StatusOnStyle : StatusOffStyle, Array.Empty()); GUILayout.EndHorizontal(); } public static bool DrawToggleButton(string label, bool isOn, float width = 0f) { GUIStyle val = (isOn ? ToggleOn : Toggle); GUILayoutOption[] array = (GUILayoutOption[])(object)((!(width > 0f)) ? new GUILayoutOption[0] : new GUILayoutOption[1] { GUILayout.Width(width) }); return GUILayout.Button(label, val, array); } public static bool DrawKeybindButton(KeyCode key, bool isListening) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) string obj = (isListening ? "..." : KeyCodeToString(key)); GUIStyle val = (isListening ? KeybindListening : Keybind); return GUILayout.Button(obj, val, Array.Empty()); } public unsafe static string KeyCodeToString(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected I4, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected I4, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected I4, but got Unknown if ((int)key == 0) { return "---"; } switch (key - 45) { default: switch (key - 256) { case 0: return "Num0"; case 1: return "Num1"; case 2: return "Num2"; case 3: return "Num3"; case 4: return "Num4"; case 5: return "Num5"; case 6: return "Num6"; case 7: return "Num7"; case 8: return "Num8"; case 9: return "Num9"; } switch (key - 303) { case 1: return "LShift"; case 0: return "RShift"; case 3: return "LCtrl"; case 2: return "RCtrl"; case 5: return "LAlt"; case 4: return "RAlt"; } break; case 3: return "0"; case 4: return "1"; case 5: return "2"; case 6: return "3"; case 7: return "4"; case 8: return "5"; case 9: return "6"; case 10: return "7"; case 11: return "8"; case 12: return "9"; case 16: return "="; case 0: return "-"; case 1: case 2: case 13: case 14: case 15: break; } return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); } public static bool DrawDropdown(string[] options, int selectedIndex, out int newIndex, bool isExpanded, float width = 0f) { newIndex = selectedIndex; GUILayoutOption[] array = (GUILayoutOption[])(object)((!(width > 0f)) ? new GUILayoutOption[0] : new GUILayoutOption[1] { GUILayout.Width(width) }); if (GUILayout.Button((selectedIndex >= 0 && selectedIndex < options.Length) ? (options[selectedIndex] + " ▼") : "Select... ▼", ButtonSmall, array)) { return true; } return false; } public static bool DrawDropdownList(string[] options, int selectedIndex, out int newIndex, float width = 0f, int maxVisible = 8) { newIndex = selectedIndex; GUILayoutOption[] array = (GUILayoutOption[])(object)((!(width > 0f)) ? new GUILayoutOption[0] : new GUILayoutOption[1] { GUILayout.Width(width) }); Mathf.Min(options.Length, maxVisible); for (int i = 0; i < options.Length && i < maxVisible; i++) { GUIStyle val = ((i == selectedIndex) ? ToggleOn : ButtonSmall); if (GUILayout.Button(options[i], val, array)) { newIndex = i; return true; } } if (options.Length > maxVisible) { GUILayout.Label($"... +{options.Length - maxVisible} more", LabelSmall, Array.Empty()); } return false; } } } namespace SilksongManager.DebugMenu.Windows { public abstract class BaseWindow { private enum ResizeDirection { None, Right, Bottom, BottomRight, Left, Top, TopLeft, TopRight, BottomLeft } private bool _isResizing; private ResizeDirection _resizeDir; private Vector2 _resizeStartPos; private Rect _resizeStartRect; private const float RESIZE_BORDER = 8f; public abstract int WindowId { get; } public abstract string Title { get; } protected virtual Vector2 DefaultSize => new Vector2(280f, 300f); protected virtual Vector2 MinSize => new Vector2(200f, 150f); protected virtual Vector2 MaxSize => new Vector2(800f, 800f); public Rect WindowRect { get; set; } public bool IsVisible { get; set; } public bool IsDetached { get; set; } public virtual KeyCode ToggleKey => (KeyCode)0; protected Vector2 ScrollPosition { get; set; } protected BaseWindow() { LoadState(); } public void LoadState() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) DebugMenuConfig.WindowState windowState = DebugMenuConfig.GetWindowState(WindowId, GetDefaultPosition(), DefaultSize); WindowRect = new Rect(windowState.Position.x, windowState.Position.y, windowState.Size.x, windowState.Size.y); IsVisible = windowState.IsVisible; IsDetached = false; } public void SaveState() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) DebugMenuConfig.SaveWindowState(WindowId, WindowRect, IsVisible); } protected virtual Vector2 GetDefaultPosition() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) return new Vector2((float)(20 + WindowId % 5 * 30), (float)(20 + WindowId % 5 * 30)); } public void Draw() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) if (IsVisible) { HandleResize(); Color color = GUI.color; float effectiveAlpha = DebugMenuConfig.GetEffectiveAlpha(); GUI.color = new Color(1f, 1f, 1f, effectiveAlpha); WindowRect = GUILayout.Window(WindowId, WindowRect, new WindowFunction(DrawWindowInternal), "", DebugMenuStyles.Window, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.MinWidth(MinSize.x), GUILayout.MinHeight(MinSize.y) }); DrawResizeHandle(); WindowRect = ClampToScreen(WindowRect); GUI.color = color; } } private void HandleResize() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(Input.mousePosition.x, (float)Screen.height - Input.mousePosition.y); _ = Event.current; if (!_isResizing && Input.GetMouseButtonDown(0)) { _resizeDir = GetResizeDirection(val); if (_resizeDir != ResizeDirection.None) { _isResizing = true; _resizeStartPos = val; _resizeStartRect = WindowRect; } } if (_isResizing && Input.GetMouseButton(0)) { Vector2 val2 = val - _resizeStartPos; Rect resizeStartRect = _resizeStartRect; switch (_resizeDir) { case ResizeDirection.Right: ((Rect)(ref resizeStartRect)).width = Mathf.Clamp(((Rect)(ref _resizeStartRect)).width + val2.x, MinSize.x, MaxSize.x); break; case ResizeDirection.Bottom: ((Rect)(ref resizeStartRect)).height = Mathf.Clamp(((Rect)(ref _resizeStartRect)).height + val2.y, MinSize.y, MaxSize.y); break; case ResizeDirection.BottomRight: ((Rect)(ref resizeStartRect)).width = Mathf.Clamp(((Rect)(ref _resizeStartRect)).width + val2.x, MinSize.x, MaxSize.x); ((Rect)(ref resizeStartRect)).height = Mathf.Clamp(((Rect)(ref _resizeStartRect)).height + val2.y, MinSize.y, MaxSize.y); break; case ResizeDirection.Left: { float num6 = Mathf.Clamp(((Rect)(ref _resizeStartRect)).width - val2.x, MinSize.x, MaxSize.x); ((Rect)(ref resizeStartRect)).x = ((Rect)(ref _resizeStartRect)).x + (((Rect)(ref _resizeStartRect)).width - num6); ((Rect)(ref resizeStartRect)).width = num6; break; } case ResizeDirection.Top: { float num5 = Mathf.Clamp(((Rect)(ref _resizeStartRect)).height - val2.y, MinSize.y, MaxSize.y); ((Rect)(ref resizeStartRect)).y = ((Rect)(ref _resizeStartRect)).y + (((Rect)(ref _resizeStartRect)).height - num5); ((Rect)(ref resizeStartRect)).height = num5; break; } case ResizeDirection.TopLeft: { float num3 = Mathf.Clamp(((Rect)(ref _resizeStartRect)).width - val2.x, MinSize.x, MaxSize.x); float num4 = Mathf.Clamp(((Rect)(ref _resizeStartRect)).height - val2.y, MinSize.y, MaxSize.y); ((Rect)(ref resizeStartRect)).x = ((Rect)(ref _resizeStartRect)).x + (((Rect)(ref _resizeStartRect)).width - num3); ((Rect)(ref resizeStartRect)).y = ((Rect)(ref _resizeStartRect)).y + (((Rect)(ref _resizeStartRect)).height - num4); ((Rect)(ref resizeStartRect)).width = num3; ((Rect)(ref resizeStartRect)).height = num4; break; } case ResizeDirection.TopRight: { ((Rect)(ref resizeStartRect)).width = Mathf.Clamp(((Rect)(ref _resizeStartRect)).width + val2.x, MinSize.x, MaxSize.x); float num2 = Mathf.Clamp(((Rect)(ref _resizeStartRect)).height - val2.y, MinSize.y, MaxSize.y); ((Rect)(ref resizeStartRect)).y = ((Rect)(ref _resizeStartRect)).y + (((Rect)(ref _resizeStartRect)).height - num2); ((Rect)(ref resizeStartRect)).height = num2; break; } case ResizeDirection.BottomLeft: { float num = Mathf.Clamp(((Rect)(ref _resizeStartRect)).width - val2.x, MinSize.x, MaxSize.x); ((Rect)(ref resizeStartRect)).x = ((Rect)(ref _resizeStartRect)).x + (((Rect)(ref _resizeStartRect)).width - num); ((Rect)(ref resizeStartRect)).width = num; ((Rect)(ref resizeStartRect)).height = Mathf.Clamp(((Rect)(ref _resizeStartRect)).height + val2.y, MinSize.y, MaxSize.y); break; } } WindowRect = resizeStartRect; } if (_isResizing && Input.GetMouseButtonUp(0)) { _isResizing = false; _resizeDir = ResizeDirection.None; } } private ResizeDirection GetResizeDirection(Vector2 mousePos) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) Rect windowRect = WindowRect; if (!((Rect)(ref windowRect)).Contains(mousePos)) { return ResizeDirection.None; } bool flag = mousePos.x < ((Rect)(ref windowRect)).x + 8f; bool flag2 = mousePos.x > ((Rect)(ref windowRect)).xMax - 8f; bool flag3 = mousePos.y < ((Rect)(ref windowRect)).y + 8f; bool flag4 = mousePos.y > ((Rect)(ref windowRect)).yMax - 8f; if (flag4 && flag2) { return ResizeDirection.BottomRight; } if (flag3 && flag) { return ResizeDirection.TopLeft; } if (flag3 && flag2) { return ResizeDirection.TopRight; } if (flag4 && flag) { return ResizeDirection.BottomLeft; } if (flag2) { return ResizeDirection.Right; } if (flag4) { return ResizeDirection.Bottom; } if (flag) { return ResizeDirection.Left; } if (flag3) { return ResizeDirection.Top; } return ResizeDirection.None; } private void DrawResizeHandle() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) Rect windowRect = WindowRect; float num = ((Rect)(ref windowRect)).xMax - 16f; windowRect = WindowRect; GUI.DrawTexture(new Rect(num, ((Rect)(ref windowRect)).yMax - 16f, 14f, 14f), (Texture)(object)DebugMenuStyles.ButtonNormalTex); } private void DrawWindowInternal(int id) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) DrawHeader(); ScrollPosition = GUILayout.BeginScrollView(ScrollPosition, Array.Empty()); DrawContent(); GUILayout.EndScrollView(); Rect windowRect = WindowRect; GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref windowRect)).width, 30f)); } protected virtual void DrawHeader() { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(Title, DebugMenuStyles.Header, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (GUILayout.Button("×", DebugMenuStyles.CloseButton, Array.Empty())) { IsVisible = false; } GUILayout.EndHorizontal(); DebugMenuStyles.DrawSeparator(); } protected abstract void DrawContent(); public virtual void Update() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if ((int)ToggleKey != 0 && Input.GetKeyDown(ToggleKey)) { Toggle(); } } public void Toggle() { IsVisible = !IsVisible; } public void Show() { IsVisible = true; } public void Hide() { IsVisible = false; SaveState(); } private Rect ClampToScreen(Rect rect) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) ((Rect)(ref rect)).x = Mathf.Clamp(((Rect)(ref rect)).x, 0f, (float)(Screen.width - 50)); ((Rect)(ref rect)).y = Mathf.Clamp(((Rect)(ref rect)).y, 0f, (float)(Screen.height - 50)); return rect; } } public class CombatWindow : BaseWindow { private string _nailInput = "5"; private string _toolInput = "10"; private string _spellInput = "15"; private string _summonInput = "8"; private string _globalMultInput = "1"; public override int WindowId => 10009; public override string Title => "Combat"; protected override Vector2 DefaultSize => new Vector2(320f, 500f); protected override void DrawContent() { DrawDamageSection("NAIL DAMAGE", DamageType.Nail, ref _nailInput); GUILayout.Space(8f); DrawDamageSection("TOOL DAMAGE", DamageType.Tool, ref _toolInput); GUILayout.Space(8f); DrawDamageSection("SPELL DAMAGE", DamageType.Spell, ref _spellInput); GUILayout.Space(8f); DrawDamageSection("SUMMON DAMAGE", DamageType.Summon, ref _summonInput); GUILayout.Space(12f); DrawGlobalMultiplier(); } private void DrawDamageSection(string header, DamageType type, ref string inputField) { //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) DebugMenuStyles.DrawSectionHeader(header); bool flag = DamageSystem.IsCustomEnabled(type); float damage = DamageSystem.GetDamage(type); float multiplier = DamageSystem.GetMultiplier(type); GUILayout.BeginHorizontal(Array.Empty()); if (DebugMenuStyles.DrawToggleButton(flag ? "Custom ON" : "Custom OFF", flag)) { DamageSystem.ToggleCustomDamage(type); } GUILayout.EndHorizontal(); if (!flag) { return; } GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Value:", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); if (GUILayout.Button("-10", DebugMenuStyles.Button, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) })) { DamageSystem.AdjustDamage(type, -10f); inputField = DamageSystem.GetDamage(type).ToString("F1"); } if (GUILayout.Button("-1", DebugMenuStyles.Button, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) })) { DamageSystem.AdjustDamage(type, -1f); inputField = DamageSystem.GetDamage(type).ToString("F1"); } string text = GUILayout.TextField(inputField, DebugMenuStyles.TextField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }); if (text != inputField) { inputField = text; if (float.TryParse(text, out var result)) { DamageSystem.SetDamage(type, result); } } if (GUILayout.Button("+1", DebugMenuStyles.Button, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) })) { DamageSystem.AdjustDamage(type, 1f); inputField = DamageSystem.GetDamage(type).ToString("F1"); } if (GUILayout.Button("+10", DebugMenuStyles.Button, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) })) { DamageSystem.AdjustDamage(type, 10f); inputField = DamageSystem.GetDamage(type).ToString("F1"); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label($"Mult: {multiplier:F2}x", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); float num = GUILayout.HorizontalSlider(multiplier, -2f, 10f, Array.Empty()); if (Mathf.Abs(num - multiplier) > 0.01f) { DamageSystem.SetMultiplier(type, num); } GUILayout.EndHorizontal(); float num2 = DamageSystem.CalculateFinalDamage(type, damage); Color color = ((num2 >= 0f) ? DebugMenuStyles.StatusOn : DebugMenuStyles.StatusWarning); Color color2 = GUI.color; GUI.color = color; GUILayout.Label($"Final: {num2:F1}", DebugMenuStyles.LabelBold, Array.Empty()); GUI.color = color2; } private void DrawGlobalMultiplier() { DebugMenuStyles.DrawSectionHeader("GLOBAL MULTIPLIER"); float globalMultiplier = DamageSystem.GlobalMultiplier; GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label($"Global: {globalMultiplier:F2}x", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }); if (GUILayout.Button("0.5x", DebugMenuStyles.Button, Array.Empty())) { DamageSystem.GlobalMultiplier = 0.5f; } if (GUILayout.Button("1x", DebugMenuStyles.Button, Array.Empty())) { DamageSystem.GlobalMultiplier = 1f; } if (GUILayout.Button("2x", DebugMenuStyles.Button, Array.Empty())) { DamageSystem.GlobalMultiplier = 2f; } if (GUILayout.Button("10x", DebugMenuStyles.Button, Array.Empty())) { DamageSystem.GlobalMultiplier = 10f; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); float num = GUILayout.HorizontalSlider(globalMultiplier, -5f, 100f, Array.Empty()); if (Mathf.Abs(num - globalMultiplier) > 0.01f) { DamageSystem.GlobalMultiplier = num; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Exact:", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); string text = GUILayout.TextField(_globalMultInput, DebugMenuStyles.TextField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }); if (text != _globalMultInput) { _globalMultInput = text; if (float.TryParse(text, out var result)) { DamageSystem.GlobalMultiplier = result; } } if (GUILayout.Button("Apply", DebugMenuStyles.Button, Array.Empty()) && float.TryParse(_globalMultInput, out var result2)) { DamageSystem.GlobalMultiplier = result2; } GUILayout.EndHorizontal(); GUILayout.Space(4f); GUILayout.Label("Negative = Heal enemies", DebugMenuStyles.Label, Array.Empty()); GUILayout.Label("Zero = No damage", DebugMenuStyles.Label, Array.Empty()); } } public class DebugInfoWindow : BaseWindow { private float _deltaTime; private float _fps; private float _fpsUpdateTimer; private float _minFrameTime = float.MaxValue; private float _maxFrameTime; private float _avgFrameTime; private int _frameCount; private float _frameTimeSum; private const float CACHE_REFRESH_INTERVAL = 1f; private float _cacheTimer; private int _cachedEnemyCount; private float _cachedMemory; private Rigidbody2D _cachedRigidbody; private bool _rigidbodyCached; public override int WindowId => 10008; public override string Title => "Debug Info"; protected override Vector2 DefaultSize => new Vector2(320f, 450f); public override void Update() { base.Update(); _deltaTime += (Time.unscaledDeltaTime - _deltaTime) * 0.1f; _fpsUpdateTimer += Time.unscaledDeltaTime; if (_fpsUpdateTimer >= 0.5f) { _fps = 1f / _deltaTime; _fpsUpdateTimer = 0f; } float num = Time.unscaledDeltaTime * 1000f; _minFrameTime = Mathf.Min(_minFrameTime, num); _maxFrameTime = Mathf.Max(_maxFrameTime, num); _frameTimeSum += num; _frameCount++; _avgFrameTime = _frameTimeSum / (float)_frameCount; if (_frameCount > 300) { _minFrameTime = num; _maxFrameTime = num; _frameTimeSum = num; _frameCount = 1; } _cacheTimer += Time.unscaledDeltaTime; if (_cacheTimer >= 1f) { RefreshCachedValues(); _cacheTimer = 0f; } } private void RefreshCachedValues() { _cachedEnemyCount = EnemyActions.GetEnemyCount(); _cachedMemory = (float)GC.GetTotalMemory(forceFullCollection: false) / 1048576f; if (!_rigidbodyCached || (Object)(object)_cachedRigidbody == (Object)null) { HeroController hero = Plugin.Hero; if ((Object)(object)hero != (Object)null) { _cachedRigidbody = ((Component)hero).GetComponent(); _rigidbodyCached = true; } } } protected override void DrawContent() { DrawPerformanceSection(); DrawGameStateSection(); DrawPlayerSection(); DrawPositionSection(); DrawSceneSection(); DrawInputSection(); } private void DrawPerformanceSection() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) DebugMenuStyles.DrawSectionHeader("PERFORMANCE"); Color color = ((_fps >= 60f) ? DebugMenuStyles.StatusOn : ((_fps >= 30f) ? DebugMenuStyles.StatusWarning : DebugMenuStyles.StatusOff)); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("FPS:", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); Color color2 = GUI.color; GUI.color = color; GUILayout.Label($"{_fps:F1}", DebugMenuStyles.LabelBold, Array.Empty()); GUI.color = color2; GUILayout.EndHorizontal(); GUILayout.Label($"Frame Time: {_deltaTime * 1000f:F2} ms", DebugMenuStyles.Label, Array.Empty()); GUILayout.Label($"Min/Avg/Max: {_minFrameTime:F1}/{_avgFrameTime:F1}/{_maxFrameTime:F1} ms", DebugMenuStyles.Label, Array.Empty()); GUILayout.Label($"Memory (GC): {_cachedMemory:F1} MB", DebugMenuStyles.Label, Array.Empty()); } private void DrawGameStateSection() { DebugMenuStyles.DrawSectionHeader("GAME STATE"); GameManager gM = Plugin.GM; GUILayout.Label($"Game Speed: {Time.timeScale:F2}x", DebugMenuStyles.Label, Array.Empty()); GUILayout.Label($"Time: {Time.time:F1}s", DebugMenuStyles.Label, Array.Empty()); if ((Object)(object)gM != (Object)null) { GUILayout.Label("Scene: " + gM.sceneName, DebugMenuStyles.Label, Array.Empty()); } } private void DrawPlayerSection() { DebugMenuStyles.DrawSectionHeader("PLAYER"); PlayerData pD = Plugin.PD; HeroController hero = Plugin.Hero; if (pD == null || (Object)(object)hero == (Object)null) { GUILayout.Label("Not in game", DebugMenuStyles.Label, Array.Empty()); return; } GUILayout.Label($"Health: {pD.health}/{pD.maxHealth}", DebugMenuStyles.Label, Array.Empty()); GUILayout.Label($"Silk: {pD.silk}/{pD.silkMax}", DebugMenuStyles.Label, Array.Empty()); GUILayout.Label($"Geo: {pD.geo}", DebugMenuStyles.Label, Array.Empty()); GUILayout.Label("Invincible: " + (pD.isInvincible ? "ON" : "OFF"), DebugMenuStyles.Label, Array.Empty()); GUILayout.Label("Noclip: " + (PlayerActions.IsNoclipEnabled ? "ON" : "OFF"), DebugMenuStyles.Label, Array.Empty()); if (hero.cState != null) { GUILayout.Label("Grounded: " + (hero.cState.onGround ? "Yes" : "No"), DebugMenuStyles.Label, Array.Empty()); } } private void DrawPositionSection() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) DebugMenuStyles.DrawSectionHeader("POSITION"); HeroController hero = Plugin.Hero; if ((Object)(object)hero == (Object)null) { GUILayout.Label("N/A", DebugMenuStyles.Label, Array.Empty()); return; } Vector3 position = ((Component)hero).transform.position; GUILayout.Label($"X: {position.x:F2} Y: {position.y:F2}", DebugMenuStyles.Label, Array.Empty()); if ((Object)(object)_cachedRigidbody != (Object)null) { Vector2 linearVelocity = _cachedRigidbody.linearVelocity; GUILayout.Label($"Speed: {((Vector2)(ref linearVelocity)).magnitude:F1}", DebugMenuStyles.Label, Array.Empty()); } } private void DrawSceneSection() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) DebugMenuStyles.DrawSectionHeader("SCENE"); Scene activeScene = SceneManager.GetActiveScene(); GUILayout.Label("Name: " + ((Scene)(ref activeScene)).name, DebugMenuStyles.Label, Array.Empty()); GUILayout.Label($"Enemies: {_cachedEnemyCount}", DebugMenuStyles.Label, Array.Empty()); } private void DrawInputSection() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) DebugMenuStyles.DrawSectionHeader("INPUT"); Vector3 mousePosition = Input.mousePosition; GUILayout.Label($"Mouse: ({mousePosition.x:F0}, {mousePosition.y:F0})", DebugMenuStyles.Label, Array.Empty()); } } public class EnemiesWindow : BaseWindow { private Vector2 _enemyListScroll; private List _cachedEnemies; private float _cacheTimer; private const float CACHE_INTERVAL = 0.5f; public override int WindowId => 10004; public override string Title => "Enemies"; protected override Vector2 DefaultSize => new Vector2(300f, 400f); public override void Update() { base.Update(); _cacheTimer += Time.unscaledDeltaTime; if (_cacheTimer >= 0.5f) { _cachedEnemies = EnemyActions.FindAllEnemies(); _cacheTimer = 0f; } } protected override void DrawContent() { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) DebugMenuStyles.DrawSectionHeader("ACTIONS"); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Kill All", DebugMenuStyles.Button, Array.Empty())) { EnemyActions.KillAllEnemies(); } DrawKeybindHint(ModAction.KillAllEnemies); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); bool areEnemiesFrozen = EnemyActions.AreEnemiesFrozen; if (DebugMenuStyles.DrawToggleButton(areEnemiesFrozen ? "Freeze ✓" : "Freeze", areEnemiesFrozen)) { EnemyActions.FreezeEnemies(!areEnemiesFrozen); } DrawKeybindHint(ModAction.FreezeEnemies); GUILayout.EndHorizontal(); DebugMenuStyles.DrawSectionHeader("STATS"); int num = _cachedEnemies?.Count ?? 0; GUILayout.Label($"Enemies in room: {num}", DebugMenuStyles.Label, Array.Empty()); DebugMenuStyles.DrawStatus("Frozen", areEnemiesFrozen); DebugMenuStyles.DrawSectionHeader("ENEMY LIST"); if (_cachedEnemies == null || _cachedEnemies.Count == 0) { GUILayout.Label("No enemies in room", DebugMenuStyles.LabelCentered, Array.Empty()); } else { _enemyListScroll = GUILayout.BeginScrollView(_enemyListScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(150f) }); for (int i = 0; i < _cachedEnemies.Count; i++) { EnemyInfo enemyInfo = _cachedEnemies[i]; if (enemyInfo.IsAlive) { GUILayout.BeginHorizontal(Array.Empty()); string text = enemyInfo.Name; if (text.Length > 18) { text = text.Substring(0, 15) + "..."; } GUILayout.Label(text, DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) }); GUILayout.Label($"HP:{enemyInfo.CurrentHP}", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }); if (GUILayout.Button("Kill", DebugMenuStyles.ButtonSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) })) { EnemyActions.KillEnemy(i); _cachedEnemies = EnemyActions.FindAllEnemies(); } GUILayout.EndHorizontal(); } } GUILayout.EndScrollView(); } if (GUILayout.Button("Refresh List", DebugMenuStyles.Button, Array.Empty())) { _cachedEnemies = EnemyActions.FindAllEnemies(); } } private void DrawKeybindHint(ModAction action) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) KeyCode keybind = ModKeybindManager.GetKeybind(action); if ((int)keybind != 0) { GUILayout.Label("[" + DebugMenuStyles.KeyCodeToString(keybind) + "]", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); } } } public class HitboxWindow : BaseWindow { public override int WindowId => 10010; public override string Title => "Hitbox Visualizer"; protected override Vector2 DefaultSize => new Vector2(300f, 480f); protected override void DrawContent() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) DebugMenuStyles.DrawSectionHeader("GENERAL"); bool showHitboxes = HitboxConfig.ShowHitboxes; if (DebugMenuStyles.DrawToggleButton(showHitboxes ? "Enabled ✓" : "Enabled", showHitboxes)) { HitboxManager.ToggleHitboxes(); } KeyCode keybind = ModKeybindManager.GetKeybind(ModAction.ToggleHitboxes); GUILayout.Label("Keybind: " + DebugMenuStyles.KeyCodeToString(keybind), DebugMenuStyles.Label, Array.Empty()); GUILayout.Space(10f); DebugMenuStyles.DrawSectionHeader("LAYERS"); DrawLayerToggle("Player", HitboxLayer.Player); DrawLayerToggle("Enemy", HitboxLayer.Enemy); DrawLayerToggle("Attack", HitboxLayer.Attack); DrawLayerToggle("Terrain", HitboxLayer.Terrain); DrawLayerToggle("Trigger", HitboxLayer.Trigger); DrawLayerToggle("Hazard", HitboxLayer.Hazard); DrawLayerToggle("Breakable", HitboxLayer.Breakable); DrawLayerToggle("Interactive", HitboxLayer.Interactive); GUILayout.Space(10f); DebugMenuStyles.DrawSectionHeader("SETTINGS"); GUILayout.Label($"Line Thickness: {HitboxConfig.LineThickness:F1}", DebugMenuStyles.Label, Array.Empty()); HitboxConfig.LineThickness = GUILayout.HorizontalSlider(HitboxConfig.LineThickness, 0.5f, 5f, Array.Empty()); } private void DrawLayerToggle(string label, HitboxLayer layer) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) bool layerState = GetLayerState(layer); Color layerColor = GetLayerColor(layer); GUILayout.BeginHorizontal(Array.Empty()); Color color = GUI.color; GUI.color = layerColor; GUI.DrawTexture(GUILayoutUtility.GetRect(20f, 20f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }), (Texture)(object)Texture2D.whiteTexture); GUI.color = color; GUILayout.Space(5f); if (DebugMenuStyles.DrawToggleButton(layerState ? (label + " ✓") : label, layerState)) { SetLayerState(layer, !layerState); } GUILayout.EndHorizontal(); GUILayout.Space(2f); } private bool GetLayerState(HitboxLayer layer) { return layer switch { HitboxLayer.Player => HitboxConfig.ShowPlayer, HitboxLayer.Enemy => HitboxConfig.ShowEnemy, HitboxLayer.Attack => HitboxConfig.ShowAttack, HitboxLayer.Terrain => HitboxConfig.ShowTerrain, HitboxLayer.Trigger => HitboxConfig.ShowTrigger, HitboxLayer.Hazard => HitboxConfig.ShowHazard, HitboxLayer.Breakable => HitboxConfig.ShowBreakable, HitboxLayer.Interactive => HitboxConfig.ShowInteractive, _ => false, }; } private void SetLayerState(HitboxLayer layer, bool state) { switch (layer) { case HitboxLayer.Player: HitboxConfig.ShowPlayer = state; break; case HitboxLayer.Enemy: HitboxConfig.ShowEnemy = state; break; case HitboxLayer.Attack: HitboxConfig.ShowAttack = state; break; case HitboxLayer.Terrain: HitboxConfig.ShowTerrain = state; break; case HitboxLayer.Trigger: HitboxConfig.ShowTrigger = state; break; case HitboxLayer.Hazard: HitboxConfig.ShowHazard = state; break; case HitboxLayer.Breakable: HitboxConfig.ShowBreakable = state; break; case HitboxLayer.Interactive: HitboxConfig.ShowInteractive = state; break; } } private Color GetLayerColor(HitboxLayer layer) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) return (Color)(layer switch { HitboxLayer.Player => HitboxConfig.PlayerColor, HitboxLayer.Enemy => HitboxConfig.EnemyColor, HitboxLayer.Attack => HitboxConfig.AttackColor, HitboxLayer.Terrain => HitboxConfig.TerrainColor, HitboxLayer.Trigger => HitboxConfig.TriggerColor, HitboxLayer.Hazard => HitboxConfig.HazardColor, HitboxLayer.Breakable => HitboxConfig.BreakableColor, HitboxLayer.Interactive => HitboxConfig.InteractiveColor, _ => Color.white, }); } } public class InventoryWindow : BaseWindow { private int _currentTab; private readonly string[] _tabNames = new string[4] { "Currency", "Crests", "Tools", "Abilities" }; private int _geoAmount = 1000; private int _shardsAmount = 5; private List _crests = new List(); private string[] _crestNames = new string[0]; private int _selectedCrestIndex; private bool _crestsNeedRefresh = true; private bool _crestDropdownOpen; private List _tools = new List(); private string[] _toolNames = new string[0]; private int _selectedToolIndex; private bool _toolsNeedRefresh = true; private bool _toolDropdownOpen; private List _abilities = new List(); private string[] _abilityNames = new string[0]; private int _selectedAbilityIndex; private bool _abilitiesNeedRefresh = true; private bool _abilityDropdownOpen; private Vector2 _scrollPos = Vector2.zero; public override int WindowId => 10005; public override string Title => "Inventory"; protected override Vector2 DefaultSize => new Vector2(320f, 500f); protected override void DrawContent() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) PlayerData pD = Plugin.PD; if (pD == null) { GUILayout.Label("Not in game", DebugMenuStyles.LabelCentered, Array.Empty()); return; } GUILayout.BeginHorizontal(Array.Empty()); for (int i = 0; i < _tabNames.Length; i++) { bool isOn = _currentTab == i; if (DebugMenuStyles.DrawToggleButton(_tabNames[i], isOn, 70f)) { if (_currentTab != i) { _crestDropdownOpen = false; _toolDropdownOpen = false; _abilityDropdownOpen = false; } _currentTab = i; } } GUILayout.EndHorizontal(); GUILayout.Space(5f); _scrollPos = GUILayout.BeginScrollView(_scrollPos, Array.Empty()); switch (_currentTab) { case 0: DrawCurrencyTab(pD); break; case 1: DrawCrestsTab(pD); break; case 2: DrawToolsTab(pD); break; case 3: DrawAbilitiesTab(pD); break; } GUILayout.EndScrollView(); } private void DrawCurrencyTab(PlayerData pd) { DebugMenuStyles.DrawSectionHeader("GEO"); GUILayout.Label($"Current: {pd.geo}", DebugMenuStyles.Label, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("+100", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.AddGeo(100); } if (GUILayout.Button("+1K", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.AddGeo(1000); } if (GUILayout.Button("+10K", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.AddGeo(10000); } DrawKeybindHint(ModAction.AddGeo); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("-100", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.TakeGeo(100); } if (GUILayout.Button("-1K", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.TakeGeo(1000); } if (GUILayout.Button("-10K", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.TakeGeo(10000); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Amount:", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }); if (int.TryParse(GUILayout.TextField(_geoAmount.ToString(), DebugMenuStyles.TextField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }), out var result)) { _geoAmount = Mathf.Clamp(result, 0, 999999); } if (GUILayout.Button("Add", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.AddGeo(_geoAmount); } if (GUILayout.Button("Take", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.TakeGeo(_geoAmount); } if (GUILayout.Button("Set", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.SetGeo(_geoAmount); } GUILayout.EndHorizontal(); GUILayout.Space(10f); DebugMenuStyles.DrawSectionHeader("SHELL SHARDS"); GUILayout.Label($"Current: {pd.ShellShards}", DebugMenuStyles.Label, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("+1", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.AddShards(1); } if (GUILayout.Button("+5", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.AddShards(5); } if (GUILayout.Button("+10", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.AddShards(10); } DrawKeybindHint(ModAction.AddShellShards); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("-1", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.TakeShards(1); } if (GUILayout.Button("-5", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.TakeShards(5); } if (GUILayout.Button("-10", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.TakeShards(10); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Amount:", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }); if (int.TryParse(GUILayout.TextField(_shardsAmount.ToString(), DebugMenuStyles.TextField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }), out var result2)) { _shardsAmount = Mathf.Clamp(result2, 0, 9999); } if (GUILayout.Button("Add", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.AddShards(_shardsAmount); } if (GUILayout.Button("Take", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.TakeShards(_shardsAmount); } if (GUILayout.Button("Set", DebugMenuStyles.ButtonSmall, Array.Empty())) { CurrencyActions.SetShards(_shardsAmount); } GUILayout.EndHorizontal(); } private void DrawCrestsTab(PlayerData pd) { DebugMenuStyles.DrawSectionHeader("CREST SELECTION"); if (_crestsNeedRefresh || _crests.Count == 0) { _crests = CrestActions.GetAllCrests(); _crestNames = _crests.Select((SilksongManager.Inventory.CrestInfo c) => c.Name).ToArray(); _crestsNeedRefresh = false; if (_selectedCrestIndex >= _crests.Count) { _selectedCrestIndex = 0; } } string equippedCrestName = CrestActions.GetEquippedCrestName(); GUILayout.Label("Equipped: " + equippedCrestName, DebugMenuStyles.Label, Array.Empty()); GUILayout.Space(5f); if (_crests.Count > 0) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Select:", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); string text = ((_selectedCrestIndex < _crestNames.Length) ? _crestNames[_selectedCrestIndex] : "---"); if (GUILayout.Button(_crestDropdownOpen ? ("▲ " + text) : ("▼ " + text), DebugMenuStyles.ButtonSmall, Array.Empty())) { _crestDropdownOpen = !_crestDropdownOpen; } GUILayout.EndHorizontal(); if (_crestDropdownOpen) { GUILayout.BeginVertical(DebugMenuStyles.Box, Array.Empty()); for (int num = 0; num < _crestNames.Length; num++) { GUIStyle val = ((num == _selectedCrestIndex) ? DebugMenuStyles.ToggleOn : DebugMenuStyles.ButtonSmall); string text2 = _crestNames[num]; if (_crests[num].IsUnlocked) { text2 += " ✓"; } if (_crests[num].IsEquipped) { text2 += " [E]"; } if (GUILayout.Button(text2, val, Array.Empty())) { _selectedCrestIndex = num; _crestDropdownOpen = false; } } GUILayout.EndVertical(); } if (!_crestDropdownOpen && _selectedCrestIndex < _crests.Count) { SilksongManager.Inventory.CrestInfo crestInfo = _crests[_selectedCrestIndex]; string text3 = (crestInfo.IsUnlocked ? "✓ Unlocked" : "✗ Locked"); if (crestInfo.IsEquipped) { text3 += " (Equipped)"; } GUILayout.Label(text3, DebugMenuStyles.Label, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Unlock", DebugMenuStyles.ButtonSmall, Array.Empty())) { CrestActions.UnlockCrest(crestInfo.Name); _crestsNeedRefresh = true; } if (GUILayout.Button("Lock/Reset", DebugMenuStyles.ButtonSmall, Array.Empty())) { CrestActions.LockCrest(crestInfo.Name); _crestsNeedRefresh = true; } if (GUILayout.Button("Equip", DebugMenuStyles.ButtonSmall, Array.Empty())) { CrestActions.EquipCrest(crestInfo.Name); _crestsNeedRefresh = true; } GUILayout.EndHorizontal(); } } GUILayout.Space(10f); DebugMenuStyles.DrawSectionHeader("ALL CRESTS"); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Unlock All", DebugMenuStyles.Button, Array.Empty())) { CrestActions.UnlockAllCrests(); _crestsNeedRefresh = true; } if (GUILayout.Button("Reset All", DebugMenuStyles.Button, Array.Empty())) { CrestActions.ResetAllCrests(); _crestsNeedRefresh = true; } GUILayout.EndHorizontal(); } private void DrawToolsTab(PlayerData pd) { DebugMenuStyles.DrawSectionHeader("TOOL SELECTION"); if (_toolsNeedRefresh || _tools.Count == 0) { _tools = ToolActions.GetNonCrestTools(); _toolNames = _tools.Select((ToolInfo t) => t.Name).ToArray(); _toolsNeedRefresh = false; if (_selectedToolIndex >= _tools.Count) { _selectedToolIndex = 0; } } if (_tools.Count > 0) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Select:", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); string text = ((_selectedToolIndex < _toolNames.Length) ? _toolNames[_selectedToolIndex] : "---"); if (text.Length > 20) { text = text.Substring(0, 17) + "..."; } if (GUILayout.Button(_toolDropdownOpen ? ("▲ " + text) : ("▼ " + text), DebugMenuStyles.ButtonSmall, Array.Empty())) { _toolDropdownOpen = !_toolDropdownOpen; } GUILayout.EndHorizontal(); if (_toolDropdownOpen) { GUILayout.BeginVertical(DebugMenuStyles.Box, Array.Empty()); for (int num = 0; num < _toolNames.Length; num++) { GUIStyle val = ((num == _selectedToolIndex) ? DebugMenuStyles.ToggleOn : DebugMenuStyles.ButtonSmall); string text2 = _toolNames[num]; if (text2.Length > 25) { text2 = text2.Substring(0, 22) + "..."; } ToolItem toolByName = ToolItemManager.GetToolByName(_tools[num].Name); if ((Object)(object)toolByName != (Object)null && toolByName.IsUnlockedNotHidden) { text2 += " ✓"; } if (GUILayout.Button(text2, val, Array.Empty())) { _selectedToolIndex = num; _toolDropdownOpen = false; } } GUILayout.EndVertical(); } if (!_toolDropdownOpen && _selectedToolIndex < _tools.Count) { GUILayout.Label("Full: " + _tools[_selectedToolIndex].Name, DebugMenuStyles.LabelSmall, Array.Empty()); ToolItem toolByName2 = ToolItemManager.GetToolByName(_tools[_selectedToolIndex].Name); GUILayout.Label(((Object)(object)toolByName2 != (Object)null && toolByName2.IsUnlockedNotHidden) ? "✓ Unlocked" : "✗ Locked", DebugMenuStyles.Label, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Unlock", DebugMenuStyles.ButtonSmall, Array.Empty())) { ToolActions.UnlockTool(_tools[_selectedToolIndex].Name); _toolsNeedRefresh = true; } if (GUILayout.Button("Lock", DebugMenuStyles.ButtonSmall, Array.Empty())) { ToolActions.LockTool(_tools[_selectedToolIndex].Name); _toolsNeedRefresh = true; } GUILayout.EndHorizontal(); } } else { GUILayout.Label("No tools available", DebugMenuStyles.Label, Array.Empty()); } GUILayout.Space(10f); DebugMenuStyles.DrawSectionHeader("ALL TOOLS"); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Unlock All", DebugMenuStyles.Button, Array.Empty())) { ToolActions.UnlockAllTools(); _toolsNeedRefresh = true; } if (GUILayout.Button("Lock All", DebugMenuStyles.Button, Array.Empty())) { ToolActions.LockAllTools(); _toolsNeedRefresh = true; } GUILayout.EndHorizontal(); if (GUILayout.Button("Replenish All", DebugMenuStyles.Button, Array.Empty())) { ToolActions.ReplenishAllTools(); } } private void DrawAbilitiesTab(PlayerData pd) { DebugMenuStyles.DrawSectionHeader("ABILITY SELECTION"); if (_abilitiesNeedRefresh || _abilities.Count == 0) { _abilities = AbilityActions.GetAllAbilities(); _abilityNames = _abilities.Select((AbilityInfo a) => a.Name).ToArray(); _abilitiesNeedRefresh = false; if (_selectedAbilityIndex >= _abilities.Count) { _selectedAbilityIndex = 0; } } if (_abilities.Count > 0) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Select:", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); string text = ((_selectedAbilityIndex < _abilityNames.Length) ? _abilityNames[_selectedAbilityIndex] : "---"); if (GUILayout.Button(_abilityDropdownOpen ? ("▲ " + text) : ("▼ " + text), DebugMenuStyles.ButtonSmall, Array.Empty())) { _abilityDropdownOpen = !_abilityDropdownOpen; } GUILayout.EndHorizontal(); if (_abilityDropdownOpen) { GUILayout.BeginVertical(DebugMenuStyles.Box, Array.Empty()); for (int num = 0; num < _abilityNames.Length; num++) { GUIStyle val = ((num == _selectedAbilityIndex) ? DebugMenuStyles.ToggleOn : DebugMenuStyles.ButtonSmall); string text2 = _abilityNames[num]; if (_abilities[num].IsUnlocked) { text2 += " ✓"; } if (GUILayout.Button(text2, val, Array.Empty())) { _selectedAbilityIndex = num; _abilityDropdownOpen = false; } } GUILayout.EndVertical(); } if (!_abilityDropdownOpen && _selectedAbilityIndex < _abilities.Count) { AbilityInfo abilityInfo = _abilities[_selectedAbilityIndex]; GUILayout.Label(abilityInfo.IsUnlocked ? "✓ Unlocked" : "✗ Locked", DebugMenuStyles.Label, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Grant", DebugMenuStyles.ButtonSmall, Array.Empty())) { AbilityActions.GrantAbility(abilityInfo.Ability); _abilitiesNeedRefresh = true; } if (GUILayout.Button("Revoke", DebugMenuStyles.ButtonSmall, Array.Empty())) { AbilityActions.RevokeAbility(abilityInfo.Ability); _abilitiesNeedRefresh = true; } GUILayout.EndHorizontal(); } } GUILayout.Space(10f); DebugMenuStyles.DrawSectionHeader("ALL ABILITIES"); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Grant All", DebugMenuStyles.Button, Array.Empty())) { AbilityActions.GrantAllAbilities(); _abilitiesNeedRefresh = true; } if (GUILayout.Button("Revoke All", DebugMenuStyles.Button, Array.Empty())) { AbilityActions.RevokeAllAbilities(); _abilitiesNeedRefresh = true; } GUILayout.EndHorizontal(); } private void DrawKeybindHint(ModAction action) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) KeyCode keybind = ModKeybindManager.GetKeybind(action); if ((int)keybind != 0) { GUILayout.Label("[" + DebugMenuStyles.KeyCodeToString(keybind) + "]", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) }); } } } public class KeybindsWindow : BaseWindow { private ModAction? _listeningAction; public override int WindowId => 10006; public override string Title => "Keybinds"; protected override Vector2 DefaultSize => new Vector2(320f, 400f); protected override void DrawContent() { DebugMenuStyles.DrawSectionHeader("MOD KEYBINDS"); GUILayout.Label("Click a keybind to change it. Press Escape to cancel.", DebugMenuStyles.Label, Array.Empty()); GUILayout.Space(8f); foreach (ModAction value in Enum.GetValues(typeof(ModAction))) { DrawKeybindRow(value); } GUILayout.FlexibleSpace(); DebugMenuStyles.DrawSeparator(); if (GUILayout.Button("Reset All to Defaults", DebugMenuStyles.Button, Array.Empty())) { ModKeybindManager.ResetToDefaults(); } } private void DrawKeybindRow(ModAction action) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(ModKeybindManager.GetActionName(action), DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) }); KeyCode keybind = ModKeybindManager.GetKeybind(action); bool flag = _listeningAction == action; if (DebugMenuStyles.DrawKeybindButton(keybind, flag)) { if (flag) { _listeningAction = null; } else { _listeningAction = action; } } if (GUILayout.Button("×", DebugMenuStyles.CloseButton, Array.Empty())) { ModKeybindManager.SetKeybind(action, (KeyCode)0); } GUILayout.EndHorizontal(); } public override void Update() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Invalid comparison between Unknown and I4 //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) base.Update(); if (!_listeningAction.HasValue) { return; } if (Input.GetKeyDown((KeyCode)27)) { _listeningAction = null; return; } foreach (KeyCode value in Enum.GetValues(typeof(KeyCode))) { if ((int)value != 0 && (int)value != 323 && (int)value != 324 && Input.GetKeyDown(value)) { ModKeybindManager.SetKeybind(_listeningAction.Value, value); _listeningAction = null; break; } } } } public class MainWindow : BaseWindow { private DebugMenuController _controller; public override int WindowId => 10001; public override string Title => "Silksong Manager"; protected override Vector2 DefaultSize => new Vector2(320f, 420f); public MainWindow(DebugMenuController controller) { _controller = controller; } protected override void DrawContent() { DrawStatusSection(); GUILayout.Space(8f); DrawQuickActions(); GUILayout.Space(8f); DrawWindowButtons(); GUILayout.FlexibleSpace(); DrawFooter(); } private void DrawStatusSection() { DebugMenuStyles.DrawSectionHeader("STATUS"); PlayerData pD = Plugin.PD; HeroController hero = Plugin.Hero; if (pD != null && (Object)(object)hero != (Object)null) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label($"Health: {pD.health}/{pD.maxHealth}", DebugMenuStyles.Label, Array.Empty()); GUILayout.FlexibleSpace(); GUILayout.Label($"Silk: {pD.silk}/{pD.silkMax}", DebugMenuStyles.Label, Array.Empty()); GUILayout.EndHorizontal(); GUILayout.Label($"Geo: {pD.geo}", DebugMenuStyles.Label, Array.Empty()); GUILayout.Space(4f); DebugMenuStyles.DrawStatus("Invincibility", pD.isInvincible); DebugMenuStyles.DrawStatus("Noclip", CheatSystem.NoclipEnabled); } else { GUILayout.Label("Not in game", DebugMenuStyles.LabelCentered, Array.Empty()); } } private void DrawQuickActions() { DebugMenuStyles.DrawSectionHeader("QUICK ACTIONS"); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Heal", DebugMenuStyles.Button, Array.Empty())) { PlayerActions.QuickHeal(); } if (GUILayout.Button("Max Silk", DebugMenuStyles.Button, Array.Empty())) { PlayerActions.QuickSilk(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); bool flag = Plugin.PD?.isInvincible ?? false; if (DebugMenuStyles.DrawToggleButton(flag ? "Invincible ✓" : "Invincible", flag)) { PlayerActions.ToggleInvincibility(); } bool noclipEnabled = CheatSystem.NoclipEnabled; if (DebugMenuStyles.DrawToggleButton(noclipEnabled ? "Noclip ✓" : "Noclip", noclipEnabled)) { CheatSystem.ToggleNoclip(); } GUILayout.EndHorizontal(); } private void DrawWindowButtons() { DebugMenuStyles.DrawSectionHeader("WINDOWS"); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.BeginVertical(Array.Empty()); if (GUILayout.Button("Player", DebugMenuStyles.Button, Array.Empty())) { _controller.ToggleWindow(); } if (GUILayout.Button("Enemies", DebugMenuStyles.Button, Array.Empty())) { _controller.ToggleWindow(); } if (GUILayout.Button("Keybinds", DebugMenuStyles.Button, Array.Empty())) { _controller.ToggleWindow(); } if (GUILayout.Button("World", DebugMenuStyles.Button, Array.Empty())) { _controller.ToggleWindow(); } if (GUILayout.Button("Speed", DebugMenuStyles.Button, Array.Empty())) { _controller.ToggleWindow(); } if (GUILayout.Button("Inventory", DebugMenuStyles.Button, Array.Empty())) { _controller.ToggleWindow(); } GUILayout.EndVertical(); GUILayout.BeginVertical(Array.Empty()); if (GUILayout.Button("Settings", DebugMenuStyles.Button, Array.Empty())) { _controller.ToggleWindow(); } if (GUILayout.Button("Debug Info", DebugMenuStyles.Button, Array.Empty())) { _controller.ToggleWindow(); } if (GUILayout.Button("Combat", DebugMenuStyles.Button, Array.Empty())) { _controller.ToggleWindow(); } if (GUILayout.Button("Hitboxes", DebugMenuStyles.Button, Array.Empty())) { _controller.ToggleWindow(); } if (GUILayout.Button("Save States", DebugMenuStyles.Button, Array.Empty())) { _controller.ToggleWindow(); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); } private void DrawFooter() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) DebugMenuStyles.DrawSeparator(); GUILayout.BeginHorizontal(Array.Empty()); KeyCode keybind = ModKeybindManager.GetKeybind(ModAction.ToggleDebugMenu); GUILayout.Label("Press [" + DebugMenuStyles.KeyCodeToString(keybind) + "] to close", DebugMenuStyles.LabelCentered, Array.Empty()); GUILayout.EndHorizontal(); } protected override void DrawHeader() { GUILayout.Label(Title, DebugMenuStyles.Header, Array.Empty()); DebugMenuStyles.DrawSeparator(); } } public class PlayerWindow : BaseWindow { private int _healthInput = 10; private int _silkInput = 10; private string _noclipSpeedInput = "15"; private string _noclipBoostInput = "30"; public override int WindowId => 10002; public override string Title => "Player"; protected override Vector2 DefaultSize => new Vector2(280f, 420f); protected override void DrawContent() { PlayerData pD = Plugin.PD; HeroController hero = Plugin.Hero; if (pD == null || (Object)(object)hero == (Object)null) { GUILayout.Label("Not in game", DebugMenuStyles.LabelCentered, Array.Empty()); return; } DebugMenuStyles.DrawSectionHeader("HEALTH"); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label($"Current: {pD.health}/{pD.maxHealth}", DebugMenuStyles.Label, Array.Empty()); if (GUILayout.Button("Full", DebugMenuStyles.ButtonSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { PlayerActions.QuickHeal(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Set:", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) }); if (int.TryParse(GUILayout.TextField(_healthInput.ToString(), DebugMenuStyles.TextField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }), out var result)) { _healthInput = Mathf.Clamp(result, 1, 100); } if (GUILayout.Button("Apply", DebugMenuStyles.ButtonSmall, Array.Empty())) { PlayerActions.SetHealth(_healthInput); } GUILayout.EndHorizontal(); DebugMenuStyles.DrawSectionHeader("SILK"); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label($"Current: {pD.silk}/{pD.silkMax}", DebugMenuStyles.Label, Array.Empty()); if (GUILayout.Button("Max", DebugMenuStyles.ButtonSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { PlayerActions.QuickSilk(); } GUILayout.EndHorizontal(); DebugMenuStyles.DrawSectionHeader("TOGGLES"); GUILayout.BeginHorizontal(Array.Empty()); bool userInvincible = CheatSystem.UserInvincible; if (DebugMenuStyles.DrawToggleButton(userInvincible ? "Invincibility ✓" : "Invincibility", userInvincible)) { PlayerActions.ToggleInvincibility(); } DrawKeybindHint(ModAction.ToggleInvincibility); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); bool noclipEnabled = CheatSystem.NoclipEnabled; if (DebugMenuStyles.DrawToggleButton(noclipEnabled ? "Noclip ✓" : "Noclip", noclipEnabled)) { CheatSystem.ToggleNoclip(); } DrawKeybindHint(ModAction.ToggleNoclip); GUILayout.EndHorizontal(); if (noclipEnabled) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(" Speed:", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }); string text = GUILayout.TextField(_noclipSpeedInput, DebugMenuStyles.TextField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) }); if (text != _noclipSpeedInput) { _noclipSpeedInput = text; if (float.TryParse(text, out var result2) && result2 > 0f) { CheatSystem.NoclipSpeed = result2; } } GUILayout.Label(" Boost:", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) }); string text2 = GUILayout.TextField(_noclipBoostInput, DebugMenuStyles.TextField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) }); if (text2 != _noclipBoostInput) { _noclipBoostInput = text2; if (float.TryParse(text2, out var result3) && result3 > 0f) { CheatSystem.NoclipBoostSpeed = result3; } } GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(Array.Empty()); bool infiniteJumps = CheatSystem.InfiniteJumps; if (DebugMenuStyles.DrawToggleButton(infiniteJumps ? "Infinite Jumps ✓" : "Infinite Jumps", infiniteJumps)) { CheatSystem.ToggleInfiniteJumps(); } DrawKeybindHint(ModAction.ToggleInfiniteJumps); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); bool infiniteHealth = CheatSystem.InfiniteHealth; if (DebugMenuStyles.DrawToggleButton(infiniteHealth ? "Infinite Health ✓" : "Infinite Health", infiniteHealth)) { CheatSystem.ToggleInfiniteHealth(); } DrawKeybindHint(ModAction.ToggleInfiniteHealth); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); bool infiniteSilk = CheatSystem.InfiniteSilk; if (DebugMenuStyles.DrawToggleButton(infiniteSilk ? "Infinite Silk ✓" : "Infinite Silk", infiniteSilk)) { CheatSystem.ToggleInfiniteSilk(); } DrawKeybindHint(ModAction.ToggleInfiniteSilk); GUILayout.EndHorizontal(); } private void DrawKeybindHint(ModAction action) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) KeyCode keybind = ModKeybindManager.GetKeybind(action); if ((int)keybind != 0) { GUILayout.Label("[" + DebugMenuStyles.KeyCodeToString(keybind) + "]", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }); } } } public class SaveStateWindow : BaseWindow { private string _newStateName = ""; private Vector2 _scrollPosition; public override int WindowId => 10011; public override string Title => "Save States"; protected override Vector2 DefaultSize => new Vector2(350f, 500f); protected override void DrawContent() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) DebugMenuStyles.DrawSectionHeader("CREATE NEW STATE"); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Name:", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); _newStateName = GUILayout.TextField(_newStateName, DebugMenuStyles.TextField, Array.Empty()); GUILayout.EndHorizontal(); if (GUILayout.Button("Save Current State", DebugMenuStyles.Button, Array.Empty())) { SaveStateManager.CaptureState(_newStateName); _newStateName = ""; } GUILayout.Space(10f); DebugMenuStyles.DrawSectionHeader("SAVED STATES"); List states = SaveStateManager.GetStates(); if (states.Count == 0) { GUILayout.Label("No saved states found.", DebugMenuStyles.LabelCentered, Array.Empty()); return; } _scrollPosition = GUILayout.BeginScrollView(_scrollPosition, Array.Empty()); for (int num = states.Count - 1; num >= 0; num--) { DrawStateRow(states[num]); GUILayout.Space(5f); } GUILayout.EndScrollView(); } private void DrawStateRow(SaveStateData state) { GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(state.GetDisplayName(), DebugMenuStyles.LabelBold, Array.Empty()); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.Label("Scene: " + state.SceneName, DebugMenuStyles.LabelSmall, Array.Empty()); GUILayout.Label($"HP: {state.Health}/{state.MaxHealth} Silk: {state.Silk} Geo: {state.Geo}", DebugMenuStyles.LabelSmall, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Load", DebugMenuStyles.Button, Array.Empty())) { SaveStateManager.LoadState(state); } if (GUILayout.Button("Delete", DebugMenuStyles.Button, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { SaveStateManager.DeleteState(state); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); } } public class SettingsWindow : BaseWindow { public override int WindowId => 10007; public override string Title => "Settings"; protected override Vector2 DefaultSize => new Vector2(280f, 300f); protected override void DrawContent() { DebugMenuStyles.DrawSectionHeader("TRANSPARENCY"); bool flag = DebugMenuConfig.CurrentOpacityMode == DebugMenuConfig.OpacityMode.FullMenu; GUILayout.BeginHorizontal(Array.Empty()); if (DebugMenuStyles.DrawToggleButton("Background Only", !flag)) { DebugMenuConfig.CurrentOpacityMode = DebugMenuConfig.OpacityMode.BackgroundOnly; } if (DebugMenuStyles.DrawToggleButton("Full Menu", flag)) { DebugMenuConfig.CurrentOpacityMode = DebugMenuConfig.OpacityMode.FullMenu; } GUILayout.EndHorizontal(); GUILayout.Space(8f); GUILayout.Label($"Background Opacity: {DebugMenuConfig.BackgroundOpacity:P0}", DebugMenuStyles.Label, Array.Empty()); DebugMenuConfig.BackgroundOpacity = GUILayout.HorizontalSlider(DebugMenuConfig.BackgroundOpacity, 0.1f, 1f, Array.Empty()); GUILayout.Space(4f); if (flag) { GUILayout.Label($"Menu Opacity: {DebugMenuConfig.FullMenuOpacity:P0}", DebugMenuStyles.Label, Array.Empty()); DebugMenuConfig.FullMenuOpacity = GUILayout.HorizontalSlider(DebugMenuConfig.FullMenuOpacity, 0.3f, 1f, Array.Empty()); } DebugMenuStyles.DrawSectionHeader("WINDOWS"); if (GUILayout.Button("Reset Window Positions", DebugMenuStyles.Button, Array.Empty())) { Plugin.Log.LogInfo((object)"Window positions reset"); } DebugMenuStyles.DrawSectionHeader("GAME"); bool pauseGameOnMenu = DebugMenuConfig.PauseGameOnMenu; if (DebugMenuStyles.DrawToggleButton(pauseGameOnMenu ? "Pause on Open ✓" : "Pause on Open", pauseGameOnMenu)) { DebugMenuConfig.PauseGameOnMenu = !pauseGameOnMenu; } GUILayout.Label("Pauses game when menu opens", DebugMenuStyles.Label, Array.Empty()); DebugMenuStyles.DrawSectionHeader("INFO"); GUILayout.Label("Version: 1.0.0.2", DebugMenuStyles.Label, Array.Empty()); GUILayout.Label("Author: Catalyst", DebugMenuStyles.Label, Array.Empty()); GUILayout.Label("Telegram: @Catalyst_Kyokai", DebugMenuStyles.Label, Array.Empty()); } } public class SpeedControlWindow : BaseWindow { private string _globalInput = "1.00"; private string _playerMoveInput = "1.00"; private string _playerAtkInput = "1.00"; private string _playerAllInput = "1.00"; private string _enemyMoveInput = "1.00"; private string _enemyAtkInput = "1.00"; private string _enemyAllInput = "1.00"; public override int WindowId => 10012; public override string Title => "Speed Control"; protected override Vector2 DefaultSize => new Vector2(340f, 520f); protected override void DrawContent() { DebugMenuStyles.DrawSectionHeader("GLOBAL SPEED"); DrawSpeedInput("Time Scale", ref _globalInput, () => SpeedControlConfig.GlobalSpeed, delegate(float v) { SpeedControlManager.SetGlobalSpeed(v); }); DrawPresetButtons(new float[5] { 0.25f, 0.5f, 1f, 2f, 5f }, delegate(float v) { SpeedControlManager.SetGlobalSpeed(v); }, ref _globalInput); GUILayout.Space(10f); DebugMenuStyles.DrawSectionHeader("PLAYER SPEED"); DrawSpeedInput("Movement", ref _playerMoveInput, () => SpeedControlConfig.PlayerMovementSpeed, delegate(float v) { SpeedControlManager.SetPlayerMovementSpeed(v); }); DrawSpeedInput("Attack", ref _playerAtkInput, () => SpeedControlConfig.PlayerAttackSpeed, delegate(float v) { SpeedControlManager.SetPlayerAttackSpeed(v); }); DrawSpeedInput("All (Combined)", ref _playerAllInput, () => SpeedControlConfig.PlayerAllSpeed, delegate(float v) { SpeedControlManager.SetPlayerAllSpeed(v); }); GUILayout.Space(10f); DebugMenuStyles.DrawSectionHeader("ENEMY SPEED"); DrawSpeedInput("Movement", ref _enemyMoveInput, () => SpeedControlConfig.EnemyMovementSpeed, delegate(float v) { SpeedControlManager.SetEnemyMovementSpeed(v); }); DrawSpeedInput("Attack", ref _enemyAtkInput, () => SpeedControlConfig.EnemyAttackSpeed, delegate(float v) { SpeedControlManager.SetEnemyAttackSpeed(v); }); DrawSpeedInput("All (Combined)", ref _enemyAllInput, () => SpeedControlConfig.EnemyAllSpeed, delegate(float v) { SpeedControlManager.SetEnemyAllSpeed(v); }); GUILayout.Space(15f); DebugMenuStyles.DrawSeparator(); if (GUILayout.Button("RESET ALL TO 1.0x", DebugMenuStyles.Button, Array.Empty())) { SpeedControlManager.ResetAll(); RefreshInputs(); NotificationManager.Show("Speed Reset", "All speeds reset to 1.0x"); } GUILayout.Space(10f); DrawStatusDisplay(); } private void DrawSpeedInput(string label, ref string inputField, Func getValue, Action setValue, float step = 0.1f, float largeStep = 1f) { float num = getValue(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(label + ":", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }); if (GUILayout.Button($"-{largeStep}", DebugMenuStyles.ButtonSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(35f) })) { float obj = Mathf.Max(0.1f, num - largeStep); setValue(obj); inputField = obj.ToString("F2"); } if (GUILayout.Button($"-{step}", DebugMenuStyles.ButtonSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(35f) })) { float obj2 = Mathf.Max(0.1f, num - step); setValue(obj2); inputField = obj2.ToString("F2"); } string text = GUILayout.TextField(inputField, DebugMenuStyles.TextField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }); if (text != inputField) { inputField = text; if (float.TryParse(text, out var result) && result > 0f) { setValue(result); } } if (GUILayout.Button($"+{step}", DebugMenuStyles.ButtonSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(35f) })) { float obj3 = num + step; setValue(obj3); inputField = obj3.ToString("F2"); } if (GUILayout.Button($"+{largeStep}", DebugMenuStyles.ButtonSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(35f) })) { float obj4 = num + largeStep; setValue(obj4); inputField = obj4.ToString("F2"); } GUILayout.EndHorizontal(); } private void DrawPresetButtons(float[] presets, Action setValue, ref string inputField) { GUILayout.BeginHorizontal(Array.Empty()); for (int i = 0; i < presets.Length; i++) { float num = presets[i]; if (GUILayout.Button($"{num}x", DebugMenuStyles.ButtonSmall, Array.Empty())) { setValue(num); inputField = num.ToString("F2"); } } GUILayout.EndHorizontal(); } private void RefreshInputs() { _globalInput = SpeedControlConfig.GlobalSpeed.ToString("F2"); _playerMoveInput = SpeedControlConfig.PlayerMovementSpeed.ToString("F2"); _playerAtkInput = SpeedControlConfig.PlayerAttackSpeed.ToString("F2"); _playerAllInput = SpeedControlConfig.PlayerAllSpeed.ToString("F2"); _enemyMoveInput = SpeedControlConfig.EnemyMovementSpeed.ToString("F2"); _enemyAtkInput = SpeedControlConfig.EnemyAttackSpeed.ToString("F2"); _enemyAllInput = SpeedControlConfig.EnemyAllSpeed.ToString("F2"); } private void DrawStatusDisplay() { GUILayout.Label("Current Status:", DebugMenuStyles.LabelBold, Array.Empty()); GUILayout.Label($"Time Scale: {Time.timeScale:F2}x", DebugMenuStyles.Label, Array.Empty()); } } public class WorldWindow : BaseWindow { public override int WindowId => 10003; public override string Title => "World"; protected override Vector2 DefaultSize => new Vector2(300f, 380f); protected override void DrawContent() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) DebugMenuStyles.DrawSectionHeader("POSITION"); HeroController hero = Plugin.Hero; if ((Object)(object)hero != (Object)null) { Vector3 position = ((Component)hero).transform.position; GUILayout.Label($"X: {position.x:F2} Y: {position.y:F2} Z: {position.z:F2}", DebugMenuStyles.Label, Array.Empty()); } else { GUILayout.Label("Not in game", DebugMenuStyles.LabelCentered, Array.Empty()); } GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Save Pos", DebugMenuStyles.Button, Array.Empty())) { WorldActions.SavePosition(); } DrawKeybindHint(ModAction.SavePosition); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Load Pos", DebugMenuStyles.Button, Array.Empty())) { WorldActions.LoadPosition(); } DrawKeybindHint(ModAction.LoadPosition); GUILayout.EndHorizontal(); GUILayout.Space(8f); DebugMenuStyles.DrawSectionHeader("ACTIONS"); if (GUILayout.Button("Reload Scene", DebugMenuStyles.Button, Array.Empty())) { WorldActions.ReloadCurrentScene(); } GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Pause", DebugMenuStyles.Button, Array.Empty())) { WorldActions.PauseGame(); } if (GUILayout.Button("Resume", DebugMenuStyles.Button, Array.Empty())) { WorldActions.ResumeGame(); } GUILayout.EndHorizontal(); DebugMenuStyles.DrawSectionHeader("SCENE"); GameManager gM = Plugin.GM; if ((Object)(object)gM != (Object)null) { GUILayout.Label("Current: " + gM.sceneName, DebugMenuStyles.Label, Array.Empty()); } } private void DrawKeybindHint(ModAction action) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) KeyCode keybind = ModKeybindManager.GetKeybind(action); if ((int)keybind != 0) { GUILayout.Label("[" + DebugMenuStyles.KeyCodeToString(keybind) + "]", DebugMenuStyles.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); } } } } namespace SilksongManager.Damage { public enum DamageType { Nail, Tool, Spell, Summon } public static class DamageSystem { private static bool _customNailEnabled = false; private static bool _customToolEnabled = false; private static bool _customSpellEnabled = false; private static bool _customSummonEnabled = false; private static float _nailDamage = 5f; private static float _toolDamage = 10f; private static float _spellDamage = 15f; private static float _summonDamage = 8f; private static float _nailMultiplier = 1f; private static float _toolMultiplier = 1f; private static float _spellMultiplier = 1f; private static float _summonMultiplier = 1f; private static float _globalMultiplier = 1f; private static ConfigEntry _customNailEnabledConfig; private static ConfigEntry _customToolEnabledConfig; private static ConfigEntry _customSpellEnabledConfig; private static ConfigEntry _customSummonEnabledConfig; private static ConfigEntry _nailDamageConfig; private static ConfigEntry _toolDamageConfig; private static ConfigEntry _spellDamageConfig; private static ConfigEntry _summonDamageConfig; private static ConfigEntry _nailMultiplierConfig; private static ConfigEntry _toolMultiplierConfig; private static ConfigEntry _spellMultiplierConfig; private static ConfigEntry _summonMultiplierConfig; private static ConfigEntry _globalMultiplierConfig; public static bool CustomNailEnabled { get { return _customNailEnabled; } set { _customNailEnabled = value; if (_customNailEnabledConfig != null) { _customNailEnabledConfig.Value = value; } } } public static bool CustomToolEnabled { get { return _customToolEnabled; } set { _customToolEnabled = value; if (_customToolEnabledConfig != null) { _customToolEnabledConfig.Value = value; } } } public static bool CustomSpellEnabled { get { return _customSpellEnabled; } set { _customSpellEnabled = value; if (_customSpellEnabledConfig != null) { _customSpellEnabledConfig.Value = value; } } } public static bool CustomSummonEnabled { get { return _customSummonEnabled; } set { _customSummonEnabled = value; if (_customSummonEnabledConfig != null) { _customSummonEnabledConfig.Value = value; } } } public static float NailDamage { get { return _nailDamage; } set { _nailDamage = value; if (_nailDamageConfig != null) { _nailDamageConfig.Value = value; } } } public static float ToolDamage { get { return _toolDamage; } set { _toolDamage = value; if (_toolDamageConfig != null) { _toolDamageConfig.Value = value; } } } public static float SpellDamage { get { return _spellDamage; } set { _spellDamage = value; if (_spellDamageConfig != null) { _spellDamageConfig.Value = value; } } } public static float SummonDamage { get { return _summonDamage; } set { _summonDamage = value; if (_summonDamageConfig != null) { _summonDamageConfig.Value = value; } } } public static float NailMultiplier { get { return _nailMultiplier; } set { _nailMultiplier = value; if (_nailMultiplierConfig != null) { _nailMultiplierConfig.Value = value; } } } public static float ToolMultiplier { get { return _toolMultiplier; } set { _toolMultiplier = value; if (_toolMultiplierConfig != null) { _toolMultiplierConfig.Value = value; } } } public static float SpellMultiplier { get { return _spellMultiplier; } set { _spellMultiplier = value; if (_spellMultiplierConfig != null) { _spellMultiplierConfig.Value = value; } } } public static float SummonMultiplier { get { return _summonMultiplier; } set { _summonMultiplier = value; if (_summonMultiplierConfig != null) { _summonMultiplierConfig.Value = value; } } } public static float GlobalMultiplier { get { return _globalMultiplier; } set { _globalMultiplier = value; if (_globalMultiplierConfig != null) { _globalMultiplierConfig.Value = value; } } } public static void Initialize(ConfigFile config) { _customNailEnabledConfig = config.Bind("Damage", "CustomNailEnabled", false, "Enable custom nail damage"); _customToolEnabledConfig = config.Bind("Damage", "CustomToolEnabled", false, "Enable custom tool damage"); _customSpellEnabledConfig = config.Bind("Damage", "CustomSpellEnabled", false, "Enable custom spell damage"); _customSummonEnabledConfig = config.Bind("Damage", "CustomSummonEnabled", false, "Enable custom summon damage"); _nailDamageConfig = config.Bind("Damage", "NailDamage", 5f, "Custom nail damage value"); _toolDamageConfig = config.Bind("Damage", "ToolDamage", 10f, "Custom tool damage value"); _spellDamageConfig = config.Bind("Damage", "SpellDamage", 15f, "Custom spell damage value"); _summonDamageConfig = config.Bind("Damage", "SummonDamage", 8f, "Custom summon damage value"); _nailMultiplierConfig = config.Bind("Damage", "NailMultiplier", 1f, "Nail damage multiplier"); _toolMultiplierConfig = config.Bind("Damage", "ToolMultiplier", 1f, "Tool damage multiplier"); _spellMultiplierConfig = config.Bind("Damage", "SpellMultiplier", 1f, "Spell damage multiplier"); _summonMultiplierConfig = config.Bind("Damage", "SummonMultiplier", 1f, "Summon damage multiplier"); _globalMultiplierConfig = config.Bind("Damage", "GlobalMultiplier", 1f, "Global damage multiplier"); _customNailEnabled = _customNailEnabledConfig.Value; _customToolEnabled = _customToolEnabledConfig.Value; _customSpellEnabled = _customSpellEnabledConfig.Value; _customSummonEnabled = _customSummonEnabledConfig.Value; _nailDamage = _nailDamageConfig.Value; _toolDamage = _toolDamageConfig.Value; _spellDamage = _spellDamageConfig.Value; _summonDamage = _summonDamageConfig.Value; _nailMultiplier = _nailMultiplierConfig.Value; _toolMultiplier = _toolMultiplierConfig.Value; _spellMultiplier = _spellMultiplierConfig.Value; _summonMultiplier = _summonMultiplierConfig.Value; _globalMultiplier = _globalMultiplierConfig.Value; Plugin.Log.LogInfo((object)"DamageSystem initialized"); } public static float CalculateFinalDamage(DamageType type, float baseDamage) { float num = baseDamage; float num2 = _globalMultiplier; switch (type) { case DamageType.Nail: if (_customNailEnabled) { num = _nailDamage; } num2 *= _nailMultiplier; break; case DamageType.Tool: if (_customToolEnabled) { num = _toolDamage; } num2 *= _toolMultiplier; break; case DamageType.Spell: if (_customSpellEnabled) { num = _spellDamage; } num2 *= _spellMultiplier; break; case DamageType.Summon: if (_customSummonEnabled) { num = _summonDamage; } num2 *= _summonMultiplier; break; } return num * num2; } public static float? GetCustomDamage(DamageType type) { switch (type) { case DamageType.Nail: if (!_customNailEnabled) { return null; } return _nailDamage; case DamageType.Tool: if (!_customToolEnabled) { return null; } return _toolDamage; case DamageType.Spell: if (!_customSpellEnabled) { return null; } return _spellDamage; case DamageType.Summon: if (!_customSummonEnabled) { return null; } return _summonDamage; default: return null; } } public static bool IsCustomEnabled(DamageType type) { return type switch { DamageType.Nail => _customNailEnabled, DamageType.Tool => _customToolEnabled, DamageType.Spell => _customSpellEnabled, DamageType.Summon => _customSummonEnabled, _ => false, }; } public static void ToggleCustomDamage(DamageType type) { switch (type) { case DamageType.Nail: CustomNailEnabled = !_customNailEnabled; break; case DamageType.Tool: CustomToolEnabled = !_customToolEnabled; break; case DamageType.Spell: CustomSpellEnabled = !_customSpellEnabled; break; case DamageType.Summon: CustomSummonEnabled = !_customSummonEnabled; break; } } public static void SetDamage(DamageType type, float value) { switch (type) { case DamageType.Nail: NailDamage = value; break; case DamageType.Tool: ToolDamage = value; break; case DamageType.Spell: SpellDamage = value; break; case DamageType.Summon: SummonDamage = value; break; } } public static float GetDamage(DamageType type) { return type switch { DamageType.Nail => _nailDamage, DamageType.Tool => _toolDamage, DamageType.Spell => _spellDamage, DamageType.Summon => _summonDamage, _ => 0f, }; } public static void AdjustDamage(DamageType type, float delta) { SetDamage(type, GetDamage(type) + delta); } public static void SetMultiplier(DamageType type, float value) { switch (type) { case DamageType.Nail: NailMultiplier = value; break; case DamageType.Tool: ToolMultiplier = value; break; case DamageType.Spell: SpellMultiplier = value; break; case DamageType.Summon: SummonMultiplier = value; break; } } public static float GetMultiplier(DamageType type) { return type switch { DamageType.Nail => _nailMultiplier, DamageType.Tool => _toolMultiplier, DamageType.Spell => _spellMultiplier, DamageType.Summon => _summonMultiplier, _ => 1f, }; } } } namespace SilksongManager.Currency { public static class CurrencyActions { public static void AddGeo(int amount) { PlayerData pD = Plugin.PD; if (pD == null) { Plugin.Log.LogWarning((object)"Cannot add geo: not in game."); return; } pD.geo += amount; CurrencyManager.AddGeoToCounter(amount); Plugin.Log.LogInfo((object)$"Added {amount} geo. Current: {pD.geo}"); } public static void SetGeo(int amount) { PlayerData pD = Plugin.PD; if (pD != null) { pD.geo = Mathf.Max(0, amount); Plugin.Log.LogInfo((object)$"Set geo to {pD.geo}"); } } public static void TakeGeo(int amount) { PlayerData pD = Plugin.PD; if (pD != null) { pD.geo = Mathf.Max(0, pD.geo - amount); Plugin.Log.LogInfo((object)$"Removed {amount} geo. Current: {pD.geo}"); } } public static void AddShards(int amount) { PlayerData pD = Plugin.PD; if (pD != null) { pD.ShellShards += amount; Plugin.Log.LogInfo((object)$"Added {amount} shards. Current: {pD.ShellShards}"); } } public static void SetShards(int amount) { PlayerData pD = Plugin.PD; if (pD != null) { pD.ShellShards = Mathf.Max(0, amount); Plugin.Log.LogInfo((object)$"Set shards to {pD.ShellShards}"); } } public static void TakeShards(int amount) { PlayerData pD = Plugin.PD; if (pD != null) { pD.ShellShards = Mathf.Max(0, pD.ShellShards - amount); Plugin.Log.LogInfo((object)$"Removed {amount} shards. Current: {pD.ShellShards}"); } } public static CurrencyInfo GetCurrencyInfo() { PlayerData pD = Plugin.PD; if (pD == null) { return default(CurrencyInfo); } return new CurrencyInfo { Geo = pD.geo, ShellShards = pD.ShellShards }; } } public struct CurrencyInfo { public int Geo; public int ShellShards; } }