Decompiled source of CooldownUI v1.0.0

bellusfennec-CooldownUI.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnboundLib.GameModes;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BellusFennec")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Universal UI library for displaying cooldowns and timers in ROUNDS")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CooldownUI")]
[assembly: AssemblyTitle("CooldownUI")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 CooldownUILib
{
	public class CooldownUI : MonoBehaviour
	{
		private TextMesh mainText;

		private TextMesh[] shadowTexts;

		private GameObject[] shadowObjects;

		private const int SHADOW_COUNT = 4;

		private GameObject iconObject;

		private TextMesh iconText;

		private TextMesh[] iconShadowTexts;

		private GameObject[] iconShadowObjects;

		private string currentIcon = "";

		private Color iconColor = Color.white;

		private const float ICON_OFFSET_X = -0.65f;

		private const float BODY_RADIUS = 0.8f;

		private const float GAP_FROM_BODY = 0.2f;

		private const float STACK_OFFSET_Y = 0.6f;

		private const int FONT_SIZE = 46;

		private const float CHAR_SIZE = 0.138f;

		private const float SHADOW_OFFSET = 0.046f;

		private const float SHADOW_Z = 0.01f;

		private Color readyColor = new Color(0.3f, 1f, 0.5f, 1f);

		private Color cooldownColor = new Color(1f, 0.3f, 0.3f, 1f);

		private Color activeColor = new Color(0.3f, 0.8f, 1f, 1f);

		private Color shadowColor = new Color(0f, 0f, 0f, 0.9f);

		private Transform parentTransform;

		private float lastParentScale = 1f;

		private static Dictionary<Transform, List<CooldownUI>> activeUIsByTarget = new Dictionary<Transform, List<CooldownUI>>();

		private Transform registeredTarget;

		private int visibleStackIndex = 0;

		private bool isCurrentlyVisible = false;

		private float customScaleMultiplier = 1f;

		public static CooldownUI Create(Transform parent, float customScale = 1f)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			if ((Object)(object)parent == (Object)null)
			{
				Debug.LogError((object)"[CooldownUI] Cannot create UI with null parent");
				return null;
			}
			GameObject val = new GameObject("CooldownUI");
			val.transform.SetParent(parent);
			CooldownUI cooldownUI = val.AddComponent<CooldownUI>();
			cooldownUI.parentTransform = parent;
			cooldownUI.registeredTarget = parent;
			cooldownUI.customScaleMultiplier = customScale;
			cooldownUI.UpdateScaleCompensation();
			cooldownUI.RegisterUI(parent);
			return cooldownUI;
		}

		private void UpdateScaleCompensation()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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)
			if ((Object)(object)parentTransform == (Object)null)
			{
				return;
			}
			float num = Mathf.Max(parentTransform.lossyScale.x, parentTransform.lossyScale.y);
			if (num < 0.01f)
			{
				num = 1f;
			}
			if (Mathf.Abs(num - lastParentScale) > 0.001f)
			{
				lastParentScale = num;
				float num2 = customScaleMultiplier / num;
				((Component)this).transform.localScale = Vector3.one * num2;
				if (isCurrentlyVisible)
				{
					ApplyPosition();
				}
			}
		}

		private void RegisterUI(Transform target)
		{
			if (!((Object)(object)target == (Object)null))
			{
				if (!activeUIsByTarget.ContainsKey(target))
				{
					activeUIsByTarget[target] = new List<CooldownUI>();
				}
				activeUIsByTarget[target].Add(this);
			}
		}

		private void UnregisterUI()
		{
			if (!((Object)(object)registeredTarget == (Object)null) && activeUIsByTarget.ContainsKey(registeredTarget))
			{
				activeUIsByTarget[registeredTarget].Remove(this);
				if (activeUIsByTarget[registeredTarget].Count == 0)
				{
					activeUIsByTarget.Remove(registeredTarget);
				}
				else
				{
					RecalculateVisiblePositions(registeredTarget);
				}
			}
		}

		private static void RecalculateVisiblePositions(Transform target)
		{
			if ((Object)(object)target == (Object)null || !activeUIsByTarget.ContainsKey(target))
			{
				return;
			}
			List<CooldownUI> list = activeUIsByTarget[target];
			int num = 0;
			for (int i = 0; i < list.Count; i++)
			{
				CooldownUI cooldownUI = list[i];
				if (!((Object)(object)cooldownUI == (Object)null) && cooldownUI.isCurrentlyVisible)
				{
					cooldownUI.visibleStackIndex = num;
					cooldownUI.ApplyPosition();
					num++;
				}
			}
		}

		private void ApplyPosition()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			float num = ((lastParentScale > 0.01f) ? (1f / lastParentScale) : 1f);
			float num2 = -0.8f - (0.2f + (float)visibleStackIndex * 0.6f) * num;
			((Component)this).transform.localPosition = new Vector3(0f, num2, 0f);
			UpdateSortingOrder();
		}

		private void UpdateSortingOrder()
		{
			int num = 200 + visibleStackIndex * 2;
			MeshRenderer component = ((Component)this).GetComponent<MeshRenderer>();
			if ((Object)(object)component != (Object)null)
			{
				((Renderer)component).sortingOrder = num;
			}
			if (shadowObjects == null)
			{
				return;
			}
			for (int i = 0; i < shadowObjects.Length; i++)
			{
				if ((Object)(object)shadowObjects[i] != (Object)null)
				{
					MeshRenderer component2 = shadowObjects[i].GetComponent<MeshRenderer>();
					if ((Object)(object)component2 != (Object)null)
					{
						((Renderer)component2).sortingOrder = num - 1;
					}
				}
			}
		}

		private void Awake()
		{
			CreateVisuals();
		}

		private void LateUpdate()
		{
			UpdateScaleCompensation();
		}

		private void CreateVisuals()
		{
			//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_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_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_006d: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			shadowObjects = (GameObject[])(object)new GameObject[4];
			shadowTexts = (TextMesh[])(object)new TextMesh[4];
			Vector2[] array = (Vector2[])(object)new Vector2[4]
			{
				new Vector2(-0.046f, -0.046f),
				new Vector2(0.046f, -0.046f),
				new Vector2(-0.046f, 0.046f),
				new Vector2(0.046f, 0.046f)
			};
			for (int i = 0; i < 4; i++)
			{
				shadowObjects[i] = new GameObject($"Shadow_{i}");
				shadowObjects[i].transform.SetParent(((Component)this).transform);
				shadowObjects[i].transform.localPosition = new Vector3(array[i].x, array[i].y, 0.01f);
				shadowTexts[i] = shadowObjects[i].AddComponent<TextMesh>();
				shadowTexts[i].fontSize = 46;
				shadowTexts[i].characterSize = 0.138f;
				shadowTexts[i].anchor = (TextAnchor)4;
				shadowTexts[i].alignment = (TextAlignment)1;
				shadowTexts[i].color = shadowColor;
				shadowTexts[i].fontStyle = (FontStyle)1;
				MeshRenderer component = shadowObjects[i].GetComponent<MeshRenderer>();
				if ((Object)(object)component != (Object)null)
				{
					((Renderer)component).sortingLayerName = "MostFront";
					((Renderer)component).sortingOrder = 199;
				}
			}
			mainText = ((Component)this).gameObject.AddComponent<TextMesh>();
			mainText.fontSize = 46;
			mainText.characterSize = 0.138f;
			mainText.anchor = (TextAnchor)4;
			mainText.alignment = (TextAlignment)1;
			mainText.color = readyColor;
			mainText.fontStyle = (FontStyle)1;
			MeshRenderer component2 = ((Component)this).GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				((Renderer)component2).sortingLayerName = "MostFront";
				((Renderer)component2).sortingOrder = 200;
			}
			CreateIconVisuals();
			((Component)this).gameObject.SetActive(false);
		}

		private void CreateIconVisuals()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0042: 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_007c: 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_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_00b9: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			//IL_0131: 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_024d: Unknown result type (might be due to invalid IL or missing references)
			iconObject = new GameObject("Icon");
			iconObject.transform.SetParent(((Component)this).transform);
			iconObject.transform.localPosition = new Vector3(-0.65f, 0f, 0f);
			iconShadowObjects = (GameObject[])(object)new GameObject[4];
			iconShadowTexts = (TextMesh[])(object)new TextMesh[4];
			Vector2[] array = (Vector2[])(object)new Vector2[4]
			{
				new Vector2(-0.046f, -0.046f),
				new Vector2(0.046f, -0.046f),
				new Vector2(-0.046f, 0.046f),
				new Vector2(0.046f, 0.046f)
			};
			for (int i = 0; i < 4; i++)
			{
				iconShadowObjects[i] = new GameObject($"IconShadow_{i}");
				iconShadowObjects[i].transform.SetParent(iconObject.transform);
				iconShadowObjects[i].transform.localPosition = new Vector3(array[i].x, array[i].y, 0.01f);
				iconShadowTexts[i] = iconShadowObjects[i].AddComponent<TextMesh>();
				iconShadowTexts[i].fontSize = 46;
				iconShadowTexts[i].characterSize = 0.138f;
				iconShadowTexts[i].anchor = (TextAnchor)4;
				iconShadowTexts[i].alignment = (TextAlignment)1;
				iconShadowTexts[i].color = shadowColor;
				iconShadowTexts[i].fontStyle = (FontStyle)1;
				MeshRenderer component = iconShadowObjects[i].GetComponent<MeshRenderer>();
				if ((Object)(object)component != (Object)null)
				{
					((Renderer)component).sortingLayerName = "MostFront";
					((Renderer)component).sortingOrder = 199;
				}
			}
			iconText = iconObject.AddComponent<TextMesh>();
			iconText.fontSize = 46;
			iconText.characterSize = 0.138f;
			iconText.anchor = (TextAnchor)4;
			iconText.alignment = (TextAlignment)1;
			iconText.color = iconColor;
			iconText.fontStyle = (FontStyle)1;
			MeshRenderer component2 = iconObject.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				((Renderer)component2).sortingLayerName = "MostFront";
				((Renderer)component2).sortingOrder = 200;
			}
			iconObject.SetActive(false);
		}

		private void OnDestroy()
		{
			UnregisterUI();
			if (shadowObjects != null)
			{
				for (int i = 0; i < shadowObjects.Length; i++)
				{
					if ((Object)(object)shadowObjects[i] != (Object)null)
					{
						Object.Destroy((Object)(object)shadowObjects[i]);
					}
				}
			}
			if (iconShadowObjects != null)
			{
				for (int j = 0; j < iconShadowObjects.Length; j++)
				{
					if ((Object)(object)iconShadowObjects[j] != (Object)null)
					{
						Object.Destroy((Object)(object)iconShadowObjects[j]);
					}
				}
			}
			if ((Object)(object)iconObject != (Object)null)
			{
				Object.Destroy((Object)(object)iconObject);
			}
		}

		public void ShowCooldown(float remaining, float total)
		{
			//IL_0037: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			SetVisible(visible: true);
			string text = FormatTime(remaining);
			mainText.text = text;
			SetShadowText(text);
			float num = 1f - remaining / total;
			mainText.color = Color.Lerp(cooldownColor, readyColor, num);
			UpdateIconVisibility();
		}

		public void ShowActive(float remaining)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			SetVisible(visible: true);
			string text = FormatTime(remaining);
			mainText.text = text;
			SetShadowText(text);
			mainText.color = activeColor;
			UpdateIconVisibility();
		}

		public void ShowText(string text, Color color)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			SetVisible(visible: true);
			mainText.text = text;
			SetShadowText(text);
			mainText.color = color;
			UpdateIconVisibility();
		}

		public void ShowReady()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			ShowText("READY", readyColor);
		}

		public void ShowStacks(int count, Color? color = null)
		{
			//IL_0026: 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)
			ShowText($"x{count}", (Color)(((??)color) ?? Color.white));
		}

		public void Hide()
		{
			if ((Object)(object)iconObject != (Object)null && iconObject.activeSelf)
			{
				iconObject.SetActive(false);
			}
			SetVisible(visible: false);
		}

		public void SetIcon(string icon, Color? color = null)
		{
			//IL_0026: 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_002b: 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)
			currentIcon = icon ?? "";
			iconColor = (Color)(((??)color) ?? Color.white);
			if ((Object)(object)iconText != (Object)null)
			{
				iconText.text = currentIcon;
				iconText.color = iconColor;
			}
			if (iconShadowTexts != null)
			{
				for (int i = 0; i < iconShadowTexts.Length; i++)
				{
					if ((Object)(object)iconShadowTexts[i] != (Object)null)
					{
						iconShadowTexts[i].text = currentIcon;
					}
				}
			}
			UpdateIconVisibility();
		}

		public void ClearIcon()
		{
			SetIcon("");
		}

		public void SetColors(Color ready, Color cooldown, Color active)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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_000a: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			readyColor = ready;
			cooldownColor = cooldown;
			activeColor = active;
		}

		public void SetShadowColor(Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			shadowColor = color;
			if (shadowTexts != null)
			{
				for (int i = 0; i < shadowTexts.Length; i++)
				{
					if ((Object)(object)shadowTexts[i] != (Object)null)
					{
						shadowTexts[i].color = shadowColor;
					}
				}
			}
			if (iconShadowTexts == null)
			{
				return;
			}
			for (int j = 0; j < iconShadowTexts.Length; j++)
			{
				if ((Object)(object)iconShadowTexts[j] != (Object)null)
				{
					iconShadowTexts[j].color = shadowColor;
				}
			}
		}

		private string FormatTime(float seconds)
		{
			if (seconds >= 3f)
			{
				return seconds.ToString("F0", CultureInfo.InvariantCulture);
			}
			return seconds.ToString("F1", CultureInfo.InvariantCulture);
		}

		private void SetVisible(bool visible)
		{
			if (isCurrentlyVisible != visible)
			{
				isCurrentlyVisible = visible;
				((Component)this).gameObject.SetActive(visible);
				if (visible)
				{
					lastParentScale = 0f;
					UpdateScaleCompensation();
				}
				RecalculateVisiblePositions(registeredTarget);
			}
		}

		private void UpdateIconVisibility()
		{
			if ((Object)(object)iconObject != (Object)null)
			{
				bool active = !string.IsNullOrEmpty(currentIcon) && ((Component)this).gameObject.activeSelf;
				iconObject.SetActive(active);
			}
		}

		private void SetShadowText(string text)
		{
			if (shadowTexts == null)
			{
				return;
			}
			for (int i = 0; i < shadowTexts.Length; i++)
			{
				if ((Object)(object)shadowTexts[i] != (Object)null)
				{
					shadowTexts[i].text = text;
				}
			}
		}

		public static void ClearAllRegistrations()
		{
			activeUIsByTarget.Clear();
		}

		public static int GetActiveUICount(Transform target)
		{
			if ((Object)(object)target == (Object)null)
			{
				return 0;
			}
			if (!activeUIsByTarget.ContainsKey(target))
			{
				return 0;
			}
			return activeUIsByTarget[target].Count;
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.rounds.cooldownui", "CooldownUI", "1.0.0")]
	[BepInProcess("Rounds.exe")]
	public class CooldownUIPlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <ClearRegistrations>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public CooldownUIPlugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ClearRegistrations>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				CooldownUI.ClearAllRegistrations();
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string ModId = "com.rounds.cooldownui";

		public const string ModName = "CooldownUI";

		public const string Version = "1.0.0";

		private static CooldownUIPlugin instance;

		public static CooldownUIPlugin Instance => instance;

		private void Awake()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			instance = this;
			Harmony val = new Harmony("com.rounds.cooldownui");
			val.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"CooldownUI v1.0.0 loaded!");
		}

		private void Start()
		{
			GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)((IGameModeHandler gm) => ClearRegistrations()));
			GameModeManager.AddHook("GameEnd", (Func<IGameModeHandler, IEnumerator>)((IGameModeHandler gm) => ClearRegistrations()));
			GameModeManager.AddHook("PointEnd", (Func<IGameModeHandler, IEnumerator>)((IGameModeHandler gm) => ClearRegistrations()));
		}

		[IteratorStateMachine(typeof(<ClearRegistrations>d__8))]
		private IEnumerator ClearRegistrations()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ClearRegistrations>d__8(0)
			{
				<>4__this = this
			};
		}
	}
}