Decompiled source of Ice Cloak Tool v1.0.0

IceCloakMod.dll

Decompiled a week ago
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<string, List<(string key, string value)>> dict = new Dictionary<string, List<(string, string)>>(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.<br><br>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<GameManager>() != (Object)null && (int)GameManager.instance.GameState == 4 && (Object)(object)Object.FindFirstObjectByType<UIManager>() != (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<t>(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<t>(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<ToolItemBasic>("displayName", flags, val, (object)new LocalisedString("Tools", name.ToUpper() + "_NAME"));
		SetFieldVal<ToolItemBasic>("description", flags, val, (object)new LocalisedString("Tools", name.ToUpper() + "_DESC"));
		SetFieldVal<ToolItemBasic>("inventorySprite", flags, val, sprite ?? origin.GetInventorySprite((IconVariants)0));
		SetFieldVal<ToolItem>("type", flags, val, type);
		SetFieldVal<ToolItem>("BaseStorageAmount", flags, val, 0);
		if (useCountKey)
		{
			SetFieldVal<ToolItem>("countKey", flags, val, origin.CountKey);
		}
		((ToolItem)val).SavedData = savedData;
		((NamedScriptableObjectList<ToolItem>)(ToolItemList)GetFieldVal<ToolItemManager>("toolItems", flags, ManagerSingleton<ToolItemManager>.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;
			}
		}
	}
}