using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using GlobalEnums; using HarmonyLib; using Microsoft.CodeAnalysis; using TeamCherry.Localization; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ModTesting")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ModTesting")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("1d98869c-572f-4682-a5f7-7027f5879069")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [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; } } } [BepInPlugin("com.silksong.icecloak", "Ice Cloak Tool", "1.0")] public class IceCloakMod : BaseUnityPlugin { private static ToolItem CustomTool; private static float CoolDown = 2f; private static bool SilkFix = false; private static int ReturnSilk; private static ManualLogSource logger; private static float Charge = 0f; private static float ChargeCool = 0f; private static readonly float maxCharge = 100f; private static Color backgroundColor; private static Color barColor; private static Color fullBarColor; private static string currentText; private static Color textColor; private static bool isShaking; private static bool reviveEnabled = false; private static readonly Dictionary> dict = new Dictionary>(StringComparer.OrdinalIgnoreCase); private void Awake() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading Plugin..."); logger = ((BaseUnityPlugin)this).Logger; SetupTool("IceDash", "Ice Cloak", "A Gleaming Cloak Of Ice.

When Fully Charged, Allows The Bearer To Dash Sharply Through Enemies Using Ice!"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin loaded and initialized!"); Harmony.CreateAndPatchAll(typeof(IceCloakMod), (string)null); } [HarmonyPostfix] [HarmonyPatch(typeof(GameManager), "SetLoadedGameData", new Type[] { typeof(SaveGameData), typeof(int) })] private static void SetLoadedGameData_Postfix(GameManager __instance, SaveGameData saveGameData, int saveSlot) { CustomTool = (ToolItem)(object)CreateTool("IceDash", (ToolItemType)1, GetTool("Revenge Crystal"), null, null, useCountKey: true); try { ChargeCool = 0f; Charge = 0f; logger.LogInfo((object)"Loaded!"); } catch (Exception arg) { logger.LogError((object)$"Failed to load, exited with: {arg}"); } if (GetTool("Pinstress Tool").IsUnlockedNotHidden && GetTool("Revenge Crystal").IsUnlocked) { logger.LogInfo((object)"Unlocking..."); CustomTool.Unlock((Action)null, (PopupFlags)3); } else if (!GetTool("Pinstress Tool").IsUnlockedNotHidden || !GetTool("Revenge Crystal").IsUnlocked) { logger.LogInfo((object)"Locking..."); CustomTool.Lock(); } } private void Update() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 CoolDown += Time.deltaTime; if ((Object)(object)Object.FindFirstObjectByType() != (Object)null && (int)GameManager.instance.GameState == 4 && (Object)(object)Object.FindFirstObjectByType() != (Object)null && (int)UIManager.instance.uiState == 4) { ChargeCool += Time.deltaTime; if (ChargeCool >= 1.5f) { Charge -= Time.deltaTime * 2f; if (Charge < 0f) { Charge = 0f; } } } if (Charge > 0f && PlayerData.instance.atBench) { Charge = 0f; } } private void OnGUI() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0093: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Invalid comparison between Unknown and I4 //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: 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) //IL_00c4: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Invalid comparison between Unknown and I4 //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: 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_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021d: 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_0254: 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_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) if (reviveEnabled) { Rect val = default(Rect); ((Rect)(ref val))..ctor((float)(Screen.width / 2 - 200), (float)(Screen.height / 2 - 25), 400f, 50f); if (isShaking) { float num = 5f; ((Rect)(ref val)).y = ((Rect)(ref val)).y + Random.Range(0f - num, num); ((Rect)(ref val)).x = ((Rect)(ref val)).x + Random.Range(0f - num, num); } GUIStyle val2 = new GUIStyle(); val2.fontSize = 32; val2.normal.textColor = ((textColor == Color.clear) ? Color.white : textColor); val2.alignment = (TextAnchor)4; GUIStyle val3 = new GUIStyle(); val3.fontSize = 34; val3.normal.textColor = Color.black; val3.alignment = (TextAnchor)4; GUI.Label(val, currentText, val3); GUI.Label(val, currentText, val2); } if ((Object)(object)CustomTool != (Object)null && ((ToolBase)CustomTool).IsEquipped && (int)UIManager.instance.uiState == 4 && (Object)(object)GameManager.instance != (Object)null && (int)GameManager.instance.GameState == 4) { Texture2D whiteTexture = Texture2D.whiteTexture; float num2 = (float)Screen.width * 0.01f; float num3 = (float)Screen.height * 0.25f; float num4 = (float)Screen.width * 0.01f; float num5 = (float)Screen.height / 2f - num3 / 2f; GUI.BeginGroup(new Rect(num4, num5, num2, num3)); float num6 = Mathf.Clamp01(Charge / maxCharge); float num7 = num3 * num6; float num8 = num3 - num7; if (backgroundColor == Color.clear || barColor == Color.clear || fullBarColor == Color.clear) { backgroundColor = RGB(100f, 100f, 100f, 70f); barColor = RGB(0f, 200f, 200f); fullBarColor = RGB(0f, 255f, 255f); } GUI.color = backgroundColor; GUI.DrawTexture(new Rect(0f, 0f, num2, num3), (Texture)(object)whiteTexture); if (num6 >= 1f) { GUI.color = fullBarColor; } else { GUI.color = barColor; } GUI.DrawTexture(new Rect(0f, num8, num2, num7), (Texture)(object)whiteTexture); GUI.color = Color.white; GUI.EndGroup(); } } private static Color RGB(float R, float G, float B, float o = 100f) { //IL_001d: 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) //IL_0025: Unknown result type (might be due to invalid IL or missing references) return new Color(R / 255f, G / 255f, B / 255f, o / 100f); } [HarmonyPostfix] [HarmonyPatch(typeof(HeroController), "HeroDash")] private static void HeroDash_PostFix(HeroController __instance, bool startAlreadyDashing) { if ((Object)(object)CustomTool != (Object)null && ((ToolBase)CustomTool).IsEquipped && !startAlreadyDashing && Charge >= maxCharge && CoolDown >= 2f && HeroController.instance.vertical_input != 0f) { typeof(HeroController).GetMethod("StartInvulnerable", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod).Invoke(__instance, new object[1] { __instance.INVUL_TIME_SILKDASH + 0.2f }); SilkFix = true; object? value = typeof(HeroController).GetField("skillEventTarget", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance); ((PlayMakerFSM)((value is PlayMakerFSM) ? value : null)).SendEvent("SILK CHARGE"); CoolDown = 0f; Charge = 0f; } else if (((ToolBase)CustomTool).IsEquipped && !startAlreadyDashing && Charge < maxCharge) { Charge += 1f; ChargeCool = 0f; } } public static IEnumerator writeText(string text) { currentText = ""; for (int i = 0; i < text.Length; i++) { currentText += text[i]; for (float timer = 0f; timer < 0.05f; timer += Time.unscaledDeltaTime) { yield return null; } } } public static IEnumerator triggerRevive() { TimeControlInstance deathTimeControl = TimeManager.CreateTimeControl(0f, (Type)0); try { for (float timer = 0f; timer < 0.5f; timer += Time.unscaledDeltaTime) { yield return null; } yield return writeText("..."); for (float timer2 = 0f; timer2 < 1.5f; timer2 += Time.unscaledDeltaTime) { yield return null; } yield return writeText("You Died"); for (float timer3 = 0f; timer3 < 2f; timer3 += Time.unscaledDeltaTime) { yield return null; } yield return writeText(". . ."); for (float timer4 = 0f; timer4 < 1.5f; timer4 += Time.unscaledDeltaTime) { yield return null; } textColor = Color.red; isShaking = true; yield return writeText("Don't let it happen again."); for (float timer5 = 0f; timer5 < 2.5f; timer5 += Time.unscaledDeltaTime) { yield return null; } } finally { isShaking = false; currentText = ""; textColor = Color.white; HeroController.instance.ResetState(); ((Behaviour)GameCameras.instance.hudCamera).enabled = true; HeroController.instance.AddHealth(3); deathTimeControl.Release(); } } [HarmonyPrefix] [HarmonyPatch(typeof(HeroController), "Die")] private static bool Die_PreFix(HeroController __instance, bool nonLethal, bool frostDeath, ref IEnumerator __result) { if (reviveEnabled && Charge >= maxCharge) { Charge = 0f; __result = triggerRevive(); return false; } return true; } [HarmonyPostfix] [HarmonyPatch(typeof(HeroController), "TakeDamage")] private static void TakeDamage_PostFix(HeroController __instance, GameObject go, CollisionSide damageSide, int damageAmount, HazardType hazardType, DamagePropertyFlags damagePropertyFlags = (DamagePropertyFlags)0) { Charge += damageAmount * 3; ChargeCool = 0f; } [HarmonyPrefix] [HarmonyPatch(typeof(HealthManager), "Hit")] private static void Hit_PreFix(HealthManager __instance, HitInstance hitInstance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (hitInstance.IsFirstHit && ((ToolBase)CustomTool).IsEquipped) { ChargeCool = 0f; Charge += 5f; } } [HarmonyPrefix] [HarmonyPatch(typeof(PlayMakerFSM), "SendEvent")] private static void SendEvent_PreFix(PlayMakerFSM __instance, string eventName) { if (eventName == "SILK CHARGE" && SilkFix) { int num = PlayerData.instance.silk - PlayerData.instance.SilkSkillCost; if (num < 0) { ReturnSilk = PlayerData.instance.silk; } else { ReturnSilk = PlayerData.instance.SilkSkillCost; } } } [HarmonyPostfix] [HarmonyPatch(typeof(EventRegister), "SendEvent", new Type[] { typeof(int), typeof(GameObject) })] private static void ESendEvent_PostFix(EventRegister __instance, int eventNameHash, GameObject excludeGameObject = null) { if (eventNameHash == EventRegisterEvents.HeroHealed && ((ToolBase)CustomTool).IsEquipped) { ChargeCool = 0f; Charge += 10f; } } [HarmonyPostfix] [HarmonyPatch(typeof(PlayMakerFSM), "SendEvent")] private static void SendEvent_PostFix(PlayMakerFSM __instance, string eventName) { if (eventName == "SILK CHARGE" && SilkFix) { HeroController.instance.AddSilk(ReturnSilk, false); SilkFix = false; } } [HarmonyPrefix] [HarmonyPatch(typeof(Language), "Has", new Type[] { typeof(string), typeof(string) })] private static bool Has_Prefix(string key, string sheetTitle, ref bool __result) { if (dict.ContainsKey(sheetTitle) && dict[sheetTitle].Find(((string key, string value) item) => item.key == key).key == key) { __result = true; return false; } return true; } [HarmonyPrefix] [HarmonyPatch(typeof(Language), "Get", new Type[] { typeof(string), typeof(string) })] private static bool Get_Prefix(string key, string sheetTitle, ref string __result) { if (dict.ContainsKey(sheetTitle)) { (string, string) tuple = dict[sheetTitle].Find(((string key, string value) item) => item.key == key); if (tuple.Item1 == key) { __result = tuple.Item2; return false; } } return true; } private static void AddSheetEntry(string sheet, string key, string value) { if (!dict.ContainsKey(sheet)) { dict.Add(sheet, new List<(string, string)>()); } List<(string, string)> list = dict[sheet]; list.RemoveAll(((string key, string value) touple) => touple.key == key); list.Add((key, value)); } private static ToolItem GetTool(string tool) { return ToolItemManager.GetToolByName(tool); } public static void SetFieldVal(string field, BindingFlags flags, object obj, object val) { Type typeFromHandle = typeof(t); FieldInfo field2 = typeFromHandle.GetField(field, flags); if (field2 != null) { field2.SetValue(obj, val); } else { typeFromHandle.GetProperty(field, flags)?.SetValue(obj, val); } } public static object GetFieldVal(string field, BindingFlags flags, object obj) { Type typeFromHandle = typeof(t); FieldInfo field2 = typeFromHandle.GetField(field, flags); if (field2 != null) { return field2.GetValue(obj); } return typeFromHandle.GetProperty(field, flags)?.GetValue(obj); } public static void SetupTool(string name, string displayName, string description) { AddSheetEntry("Tools", name.ToUpper() + "_NAME", displayName); AddSheetEntry("Tools", name.ToUpper() + "_DESC", description); } public static ToolItemBasic CreateTool(string name, ToolItemType type, ToolItem origin, Sprite? sprite = null, Data? data = null, bool useCountKey = false) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_004c: 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_0046: 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_0076: 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_00d2: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown ToolItemBasic val = new ToolItemBasic(); BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic; Data savedData = (Data)(((??)data) ?? new Data { IsUnlocked = true, IsHidden = false, HasBeenSeen = true, HasBeenSelected = true, AmountLeft = 0 }); ((ToolItem)val).name = name; SetFieldVal("displayName", flags, val, (object)new LocalisedString("Tools", name.ToUpper() + "_NAME")); SetFieldVal("description", flags, val, (object)new LocalisedString("Tools", name.ToUpper() + "_DESC")); SetFieldVal("inventorySprite", flags, val, sprite ?? origin.GetInventorySprite((IconVariants)0)); SetFieldVal("type", flags, val, type); SetFieldVal("BaseStorageAmount", flags, val, 0); if (useCountKey) { SetFieldVal("countKey", flags, val, origin.CountKey); } ((ToolItem)val).SavedData = savedData; ((NamedScriptableObjectList)(ToolItemList)GetFieldVal("toolItems", flags, ManagerSingleton.Instance)).Add((ToolItem)(object)val); return val; } [HarmonyPostfix] [HarmonyPatch(typeof(ToolItem), "Unlock")] public static void Unlock_Postfix(ToolItem __instance, Action afterTutorialMsg = null, PopupFlags popupFlags = (PopupFlags)3) { //IL_0075: 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_008d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)null) { if (__instance.name == GetTool("Pinstress Tool").name && GetTool("Revenge Crystal").IsUnlocked) { CustomTool.Unlock((Action)null, (PopupFlags)3); } if (__instance.name == CustomTool.name) { Data savedData = GetTool("Revenge Crystal").SavedData; savedData.IsHidden = true; GetTool("Revenge Crystal").SavedData = savedData; } if (__instance.name == GetTool("Revenge Crystal").name && GetTool("Pinstress Tool").IsUnlockedNotHidden) { CustomTool.Unlock((Action)null, (PopupFlags)3); } } } [HarmonyPostfix] [HarmonyPatch(typeof(ToolItem), "Lock")] public static void Lock_Postfix(ToolItem __instance) { //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_0074: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)null) { if (__instance.name == GetTool("Pinstress Tool").name) { CustomTool.Lock(); } if (__instance.name == CustomTool.name) { Data savedData = GetTool("Revenge Crystal").SavedData; savedData.IsHidden = false; GetTool("Revenge Crystal").SavedData = savedData; } } } }