Decompiled source of AtlyssPoise v1.0.1

plugins/AtlyssPoise.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("Decadence666")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3f93cafa48f76a440655e69f03a0db6b232a8f21")]
[assembly: AssemblyProduct("AtlyssPoise")]
[assembly: AssemblyTitle("AtlyssPoise")]
[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.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]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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;
		}
	}
}
internal static class LCMPluginInfo
{
	public const string PLUGIN_GUID = "AtlyssPoise";

	public const string PLUGIN_NAME = "AtlyssPoise";

	public const string PLUGIN_VERSION = "1.0.0";
}
namespace AtlyssPoise
{
	[BepInPlugin("AtlyssPoise", "AtlyssPoise", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Harmony val = new Harmony("com.decadence666.atlysspoise");
			val.PatchAll();
			Log.LogInfo((object)"Plugin AtlyssPoise version 1.0.0 is loaded!");
		}
	}
	[HarmonyPatch(typeof(StatusEntity), "Start")]
	public class LocalPlayerInitPatch
	{
		[CompilerGenerated]
		private sealed class <WaitForDefenseAndInit>d__2 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public StatusEntity __instance;

			public Player player;

			public PoiseBarBuilder barBuilder;

			private float <poise>5__1;

			private float <defense>5__2;

			private int <attempts>5__3;

			private PoiseManager <poiseManager>5__4;

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

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

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

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

			private bool MoveNext()
			{
				//IL_012d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0137: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<poise>5__1 = 0f;
					<defense>5__2 = __instance._pStats._statStruct._defense;
					<attempts>5__3 = 0;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<attempts>5__3 < 400)
				{
					if ((Object)(object)__instance._pStats != (Object)null)
					{
						<defense>5__2 = __instance._pStats._statStruct._defense;
						if (<defense>5__2 > 0f)
						{
							<poise>5__1 = <defense>5__2 * _poiseMulti;
							goto IL_015e;
						}
						if (<attempts>5__3 % 50 == 0)
						{
							Plugin.Log.LogInfo((object)$"[Poise] Attempt {<attempts>5__3}: Defense = {<defense>5__2}");
						}
					}
					else
					{
						Plugin.Log.LogInfo((object)$"[Poise] Attempt {<attempts>5__3}: _pStats is null.");
					}
					<attempts>5__3++;
					<>2__current = (object)new WaitForSeconds(0.05f);
					<>1__state = 1;
					return true;
				}
				goto IL_015e;
				IL_015e:
				Plugin.Log.LogInfo((object)$"[Poise] Defense = {<defense>5__2}");
				if (<poise>5__1 == 0f)
				{
					Plugin.Log.LogWarning((object)"[Poise] Defense never initialized — using fallback.");
				}
				<poiseManager>5__4 = ((Component)__instance).gameObject.AddComponent<PoiseManager>();
				<poiseManager>5__4.Initialize(<poise>5__1, barBuilder);
				barBuilder.SetPoisePercent(1f);
				Plugin.Log.LogInfo((object)$"[Poise] Initialized after wait: {<poiseManager>5__4.currentPoise}/{<poiseManager>5__4.maxPoise}");
				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();
			}
		}

		private static float _poiseMulti = 1.2f;

		private static void Postfix(StatusEntity __instance)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			if (!((Object)(object)__instance == (Object)null))
			{
				NetworkBehaviour component = ((Component)__instance).GetComponent<NetworkBehaviour>();
				if (Object.op_Implicit((Object)(object)__instance._isPlayer) && !((Object)(object)component == (Object)null) && component.isLocalPlayer && !((Object)(object)((Component)__instance).GetComponent<PoiseManager>() != (Object)null))
				{
					Plugin.Log.LogInfo((object)"[Poise] Patching from Start() — init coroutine starting.");
					GameObject val = new GameObject("PoiseBarUI");
					PoiseBarBuilder barBuilder = val.AddComponent<PoiseBarBuilder>();
					((MonoBehaviour)__instance).StartCoroutine(WaitForDefenseAndInit(__instance, __instance._isPlayer, barBuilder));
				}
			}
		}

		[IteratorStateMachine(typeof(<WaitForDefenseAndInit>d__2))]
		private static IEnumerator WaitForDefenseAndInit(StatusEntity __instance, Player player, PoiseBarBuilder barBuilder)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForDefenseAndInit>d__2(0)
			{
				__instance = __instance,
				player = player,
				barBuilder = barBuilder
			};
		}
	}
	public class PoiseBarBuilder : MonoBehaviour
	{
		public Sprite barSprite;

		private Slider poiseSlider;

		private CanvasGroup canvasGroup;

		private float visibleTimer = 0f;

		private float visibleDuration = 3f;

		private void Start()
		{
			barSprite = SpriteLoader.LoadSpriteFromFile("Bar.png");
			if ((Object)(object)barSprite == (Object)null)
			{
				Debug.LogWarning((object)"[Poise] Bar sprite failed to load!");
			}
			CreatePoiseBarUI();
		}

		private void Update()
		{
			if (visibleTimer > 0f)
			{
				visibleTimer -= Time.deltaTime;
				if (visibleTimer <= 0f)
				{
					canvasGroup.alpha = 0f;
				}
			}
		}

		public void ShowTemporarily()
		{
			visibleTimer = visibleDuration;
			canvasGroup.alpha = 1f;
		}

		private void CreatePoiseBarUI()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_007f: 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_00b5: Expected O, but got Unknown
			//IL_00dc: 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_010a: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			//IL_01cc: 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_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: 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_02a0: Expected O, but got Unknown
			//IL_02c9: 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_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Canvas", new Type[3]
			{
				typeof(Canvas),
				typeof(CanvasScaler),
				typeof(GraphicRaycaster)
			});
			Canvas component = val.GetComponent<Canvas>();
			component.renderMode = (RenderMode)0;
			canvasGroup = val.AddComponent<CanvasGroup>();
			canvasGroup.alpha = 0f;
			CanvasScaler component2 = val.GetComponent<CanvasScaler>();
			component2.uiScaleMode = (ScaleMode)1;
			component2.referenceResolution = new Vector2(1920f, 1080f);
			GameObject val2 = new GameObject("HealthBar", new Type[2]
			{
				typeof(RectTransform),
				typeof(Slider)
			});
			val2.transform.SetParent(val.transform, false);
			RectTransform component3 = val2.GetComponent<RectTransform>();
			component3.sizeDelta = new Vector2(40f, 200f);
			component3.anchorMin = new Vector2(0.275f, 0.01f);
			component3.anchorMax = new Vector2(0.275f, 0.01f);
			component3.pivot = new Vector2(0.5f, 0f);
			component3.anchoredPosition = Vector2.zero;
			Slider component4 = val2.GetComponent<Slider>();
			component4.direction = (Direction)2;
			((Selectable)component4).transition = (Transition)0;
			((Selectable)component4).interactable = false;
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)component4).navigation = navigation;
			GameObject val3 = new GameObject("Fill", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val3.transform.SetParent(val2.transform, false);
			RectTransform component5 = val3.GetComponent<RectTransform>();
			component5.anchorMin = new Vector2(0f, 0f);
			component5.anchorMax = new Vector2(1f, 1f);
			component5.offsetMin = Vector2.zero;
			component5.offsetMax = Vector2.zero;
			Image component6 = val3.GetComponent<Image>();
			((Graphic)component6).color = new Color(1f, 0.5f, 0f, 0.8f);
			Texture2D whiteTexture = Texture2D.whiteTexture;
			Sprite sprite = Sprite.Create(whiteTexture, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f));
			component6.sprite = sprite;
			GameObject val4 = new GameObject("Border", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val4.transform.SetParent(val2.transform, false);
			RectTransform component7 = val4.GetComponent<RectTransform>();
			component7.anchorMin = new Vector2(0f, 0f);
			component7.anchorMax = new Vector2(1f, 1f);
			component7.offsetMin = Vector2.zero;
			component7.offsetMax = Vector2.zero;
			Image component8 = val4.GetComponent<Image>();
			component8.sprite = barSprite;
			component8.type = (Type)1;
			component4.fillRect = component5;
			((Selectable)component4).targetGraphic = (Graphic)(object)component6;
			component4.minValue = 0f;
			component4.maxValue = 100f;
			component4.value = 100f;
			poiseSlider = component4;
		}

		public void SetPoisePercent(float value01)
		{
			if ((Object)(object)poiseSlider != (Object)null)
			{
				poiseSlider.value = Mathf.Clamp01(value01) * poiseSlider.maxValue;
			}
		}
	}
	public class PoiseManager : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <DelayedHalfReset>d__16 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PoiseManager <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>4__this.HalfResetPoise();
					Plugin.Log.LogInfo((object)"[Poise] Poise half reset in 0.5 seconds...");
					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 float maxPoise;

		public float currentPoise;

		public bool isBroken = false;

		private float _timeSinceDamaged = 0f;

		private float _regenRate;

		private float _regenDelay = 10f;

		private float _regenPercentage = 0.1f;

		private float _logTimer = 0f;

		private float _logInterval = 1f;

		private PoiseBarBuilder _poiseBarBuilder;

		private Coroutine _recoveryCoroutine;

		public void Initialize(float poise, PoiseBarBuilder poiseBarBuilder)
		{
			maxPoise = poise;
			currentPoise = maxPoise;
			_regenRate = maxPoise * _regenPercentage;
			_poiseBarBuilder = poiseBarBuilder;
		}

		public void ApplyPoiseDamage(float damage)
		{
			if (isBroken)
			{
				return;
			}
			currentPoise -= damage;
			_timeSinceDamaged = 0f;
			_poiseBarBuilder?.ShowTemporarily();
			if (currentPoise <= 0f)
			{
				currentPoise = 0f;
				isBroken = true;
				if (_recoveryCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(_recoveryCoroutine);
				}
				_recoveryCoroutine = ((MonoBehaviour)this).StartCoroutine(DelayedHalfReset());
			}
		}

		public void ResetPoise()
		{
			currentPoise = maxPoise;
			isBroken = false;
		}

		public void HalfResetPoise()
		{
			currentPoise = maxPoise / 2f;
			isBroken = false;
			if (_recoveryCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_recoveryCoroutine);
				_recoveryCoroutine = null;
			}
		}

		private void Update()
		{
			if (currentPoise >= maxPoise || isBroken)
			{
				return;
			}
			_timeSinceDamaged += Time.deltaTime;
			if (_timeSinceDamaged >= _regenDelay)
			{
				currentPoise += _regenRate * Time.deltaTime;
				if (currentPoise > maxPoise)
				{
					currentPoise = maxPoise;
				}
			}
			_poiseBarBuilder?.SetPoisePercent(currentPoise / maxPoise);
			_logTimer += Time.deltaTime;
			if (_logTimer >= _logInterval && currentPoise < maxPoise)
			{
				Plugin.Log.LogInfo((object)$"[Poise Regen] {currentPoise:F1}/{maxPoise}");
				_logTimer = 0f;
			}
		}

		[IteratorStateMachine(typeof(<DelayedHalfReset>d__16))]
		private IEnumerator DelayedHalfReset()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedHalfReset>d__16(0)
			{
				<>4__this = this
			};
		}
	}
	[HarmonyPatch(typeof(StatusEntity), "Replenish_All")]
	public class PoiseOnRespawn
	{
		private static void Prefix(StatusEntity __instance)
		{
			NetworkBehaviour component = ((Component)__instance).GetComponent<NetworkBehaviour>();
			if (Object.op_Implicit((Object)(object)__instance._isPlayer) && component.isLocalPlayer && !((Object)(object)component == (Object)null))
			{
				PoiseManager component2 = ((Component)__instance).GetComponent<PoiseManager>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.ResetPoise();
					Plugin.Log.LogInfo((object)$"[Poise] Reset on respawn: {component2.currentPoise}/{component2.maxPoise}");
				}
			}
		}
	}
	[HarmonyPatch(typeof(StatusEntity), "Take_Damage")]
	public class PoisePatch
	{
		private static void Prefix(StatusEntity __instance, ref DamageStruct _dmgStruct)
		{
			if ((Object)(object)__instance == (Object)null || _dmgStruct._damageValue <= 0)
			{
				return;
			}
			NetworkBehaviour component = ((Component)__instance).GetComponent<NetworkBehaviour>();
			if (!Object.op_Implicit((Object)(object)__instance._isPlayer) || !component.isLocalPlayer || (Object)(object)component == (Object)null)
			{
				return;
			}
			PoiseManager component2 = ((Component)__instance).GetComponent<PoiseManager>();
			if ((Object)(object)component2 == (Object)null)
			{
				return;
			}
			Player isPlayer = __instance._isPlayer;
			if (Object.op_Implicit((Object)(object)isPlayer._pCombat) && (isPlayer._pCombat._isBlocking || isPlayer._pCombat._parryChanceBuffer > 0f))
			{
				Plugin.Log.LogInfo((object)"[Poise] Blocking or parrying - no poise damage");
				return;
			}
			component2.ApplyPoiseDamage(_dmgStruct._damageValue);
			Plugin.Log.LogInfo((object)$"[Poise] after damage: {component2.currentPoise}/{component2.maxPoise}");
			if (!component2.isBroken)
			{
				_dmgStruct._appliedForce = 0f;
				Plugin.Log.LogInfo((object)"[Poise] Suppressing knockback (poise intact).");
			}
			else
			{
				Plugin.Log.LogInfo((object)"[Poise] Poise broken! Knockback allowed");
			}
		}
	}
	public static class SpriteLoader
	{
		public static Sprite LoadSpriteFromFile(string filename, int pixelsPerUnit = 100)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0082: 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)
			string directoryName = Path.GetDirectoryName(typeof(SpriteLoader).Assembly.Location);
			string text = Path.Combine(directoryName, filename);
			if (!File.Exists(text))
			{
				Debug.LogError((object)("[Poise] Sprite not found at path: " + text));
				return null;
			}
			byte[] array = File.ReadAllBytes(text);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)5, false);
			ImageConversion.LoadImage(val, array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), (float)pixelsPerUnit);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}