Decompiled source of Bleeding v0.1.1

BepInEx\plugins\BleedingMod\BleedingMod.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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("BleedingMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1")]
[assembly: AssemblyProduct("BleedingMod")]
[assembly: AssemblyTitle("BleedingMod")]
[assembly: AssemblyVersion("0.1.1.0")]
[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 BleedingMod
{
	[BepInPlugin("com.tambistudios.bleeding", "Bleeding", "0.1.1")]
	public class BleedingPlugin : BaseUnityPlugin
	{
		public const string MOD_GUID = "com.tambistudios.bleeding";

		public const string MOD_NAME = "Bleeding";

		public const string MOD_VERSION = "0.1.1";

		public static BleedingPlugin Instance;

		public static ManualLogSource Logger;

		public const float THRESHOLD_NORMAL = 20f;

		public const float THRESHOLD_LOW = 30f;

		public const float THRESHOLD_HIGH = 10f;

		public const float DURATION_NORMAL = 30f;

		public const float DURATION_LOW = 20f;

		public const float DURATION_HIGH = 60f;

		private Texture2D _guiTex;

		private Texture2D _dropTex;

		private float _pulseTimer;

		private float _flashTimer;

		private static readonly MethodInfo _addIllegalStatus = typeof(Character).GetMethod("AddIllegalStatus", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			new Harmony("com.tambistudios.bleeding").PatchAll();
			Logger.LogInfo((object)"[Bleeding 0.1.1] Loaded.");
		}

		public static float GetFallThreshold()
		{
			try
			{
				float fallDamageMultiplier = Ascents.fallDamageMultiplier;
				if (fallDamageMultiplier <= 0.001f)
				{
					return -1f;
				}
				if (fallDamageMultiplier <= 0.6f)
				{
					return 30f;
				}
				if (fallDamageMultiplier <= 1.5f)
				{
					return 20f;
				}
				return 10f;
			}
			catch
			{
				return 20f;
			}
		}

		public static float GetBleedDuration()
		{
			try
			{
				float fallDamageMultiplier = Ascents.fallDamageMultiplier;
				if (fallDamageMultiplier <= 0.001f)
				{
					return 30f;
				}
				if (fallDamageMultiplier <= 0.6f)
				{
					return 20f;
				}
				if (fallDamageMultiplier <= 1.5f)
				{
					return 30f;
				}
				return 60f;
			}
			catch
			{
				return 30f;
			}
		}

		private void Update()
		{
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter != (Object)null && (Object)(object)((Component)localCharacter).GetComponent<BleedingTracker>() == (Object)null)
			{
				((Component)localCharacter).gameObject.AddComponent<BleedingTracker>();
			}
			BleedingTracker localInstance = BleedingTracker.LocalInstance;
			if ((Object)(object)localInstance != (Object)null && localInstance.isBleeding)
			{
				_pulseTimer += Time.deltaTime * (0.8f + localInstance.severity * 0.35f);
			}
			else
			{
				_pulseTimer = 0f;
			}
			if (_flashTimer > 0f)
			{
				_flashTimer = Mathf.Max(0f, _flashTimer - Time.deltaTime);
			}
		}

		internal void TriggerHurtEffect(Character local)
		{
			_flashTimer = 1f;
			try
			{
				_addIllegalStatus?.Invoke(local, new object[2] { "Injury", 1f });
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("[Bleeding] HurtEffect: " + ex.Message));
			}
		}

		private static Texture2D LoadDropTexture()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			try
			{
				string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "assets", "blood.png");
				if (File.Exists(path))
				{
					Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
					((Texture)val).filterMode = (FilterMode)1;
					if (ImageConversion.LoadImage(val, File.ReadAllBytes(path)))
					{
						return val;
					}
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("[Bleeding] LoadDropTexture: " + ex.Message));
			}
			return MakeDropTexture(64);
		}

		private static Texture2D MakeDropTexture(int size)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0130: 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)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			float num = (float)size * 0.5f;
			float num2 = (float)size * 0.42f;
			float num3 = (float)size * 0.3f;
			float num4 = (float)size * 0.94f;
			Color32[] array = (Color32[])(object)new Color32[size * size];
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num5 = (float)j + 0.5f;
					float num6 = (float)i + 0.5f;
					float num7 = num5 - num;
					float num8 = num6 - num2;
					bool flag = num7 * num7 + num8 * num8 <= num3 * num3;
					float num9 = ((num6 >= num2 && num6 <= num4) ? ((num4 - num6) / (num4 - num2) * num3) : 0f);
					bool num10 = num6 > num2 && num6 <= num4 && Mathf.Abs(num5 - num) <= num9;
					float num11 = Mathf.Clamp01(1f - (Mathf.Sqrt(num7 * num7 + num8 * num8) - num3 + 1.5f) / 1.5f);
					byte b = (num10 ? byte.MaxValue : (flag ? byte.MaxValue : ((byte)(num11 * 255f))));
					array[i * size + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b);
				}
			}
			val.SetPixels32(array);
			val.Apply();
			return val;
		}

		private void OnGUI()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_0046: 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_0029: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: 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)
			if ((int)Event.current.type != 7)
			{
				return;
			}
			if ((Object)(object)_guiTex == (Object)null)
			{
				_guiTex = new Texture2D(1, 1);
				_guiTex.SetPixel(0, 0, Color.white);
				_guiTex.Apply();
			}
			Color color = GUI.color;
			BleedingTracker localInstance = BleedingTracker.LocalInstance;
			bool num = (Object)(object)localInstance != (Object)null && localInstance.isBleeding;
			float num2 = _pulseTimer % 1f;
			float num3 = ((num2 < 0.2f) ? (num2 / 0.2f) : (1f - (num2 - 0.2f) / 0.8f));
			if (num)
			{
				float num4 = 0.2f + Mathf.Min(localInstance.severity, 5f) * 0.03f;
				GUI.color = new Color(0.6f, 0f, 0f, num4 + num3 * 0.04f);
				GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)_guiTex);
			}
			if (_flashTimer > 0f)
			{
				GUI.color = new Color(0.55f, 0f, 0f, _flashTimer * 0.5f);
				GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)_guiTex);
			}
			if (num)
			{
				if ((Object)(object)_dropTex == (Object)null)
				{
					_dropTex = LoadDropTexture();
				}
				if ((Object)(object)_dropTex != (Object)null)
				{
					GUI.color = Color.white;
					GUI.DrawTexture(new Rect((float)Screen.width - 112f, 16f, 96f, 96f), (Texture)(object)_dropTex);
				}
			}
			GUI.color = color;
		}
	}
	public class BleedingTracker : MonoBehaviour
	{
		public static BleedingTracker LocalInstance;

		public static bool s_isBleeding = false;

		public static float s_severity = 0f;

		public static float s_bleedStart = -999f;

		private float _peakFallSpeed;

		private bool _wasFalling;

		private Character _char;

		private Rigidbody _rb;

		public bool isBleeding
		{
			get
			{
				return s_isBleeding;
			}
			set
			{
				s_isBleeding = value;
			}
		}

		public float severity
		{
			get
			{
				return s_severity;
			}
			set
			{
				s_severity = value;
			}
		}

		public float bleedStart
		{
			get
			{
				return s_bleedStart;
			}
			set
			{
				s_bleedStart = value;
			}
		}

		private void Awake()
		{
			_char = ((Component)this).GetComponent<Character>();
			_rb = ((Component)this).GetComponentInChildren<Rigidbody>();
		}

		private void Update()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_char == (Object)null || (Object)(object)Character.localCharacter != (Object)(object)_char)
			{
				return;
			}
			LocalInstance = this;
			if (s_isBleeding && Time.time - s_bleedStart >= BleedingPlugin.GetBleedDuration())
			{
				s_isBleeding = false;
				s_severity = 0f;
				s_bleedStart = -999f;
			}
			if ((Object)(object)_rb == (Object)null)
			{
				return;
			}
			float y = _rb.linearVelocity.y;
			if (y < -4f)
			{
				_wasFalling = true;
				_peakFallSpeed = Mathf.Max(_peakFallSpeed, 0f - y);
			}
			else
			{
				if (!_wasFalling || !(y > -2f))
				{
					return;
				}
				float num = _peakFallSpeed * _peakFallSpeed / 19.62f;
				float fallThreshold = BleedingPlugin.GetFallThreshold();
				if (fallThreshold > 0f && num >= fallThreshold)
				{
					float num2 = Mathf.Min(num / fallThreshold, 5f);
					if (!s_isBleeding)
					{
						s_bleedStart = Time.time;
					}
					s_isBleeding = true;
					s_severity = Mathf.Max(s_severity, num2);
					BleedingPlugin.Instance?.TriggerHurtEffect(_char);
				}
				_wasFalling = false;
				_peakFallSpeed = 0f;
			}
		}

		public void CureBleeding()
		{
			if (s_isBleeding)
			{
				s_isBleeding = false;
				s_severity = 0f;
				s_bleedStart = -999f;
			}
		}
	}
	[HarmonyPatch(typeof(Character), "Awake")]
	internal static class Patch_Character_Awake
	{
		[HarmonyPostfix]
		private static void Postfix(Character __instance)
		{
			if ((Object)(object)((Component)__instance).GetComponent<BleedingTracker>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<BleedingTracker>();
			}
		}
	}
	[HarmonyPatch(typeof(Character), "CanRegenStamina")]
	internal static class Patch_CanRegenStamina
	{
		[HarmonyPostfix]
		private static void Postfix(Character __instance, ref bool __result)
		{
			if (__instance.IsLocal)
			{
				BleedingTracker component = ((Component)__instance).GetComponent<BleedingTracker>();
				if ((Object)(object)component != (Object)null && component.isBleeding)
				{
					__result = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Action_ClearAllStatus), "RunAction")]
	internal static class Patch_ClearAllStatus
	{
		private static readonly FieldInfo _itemField = AccessTools.Field(typeof(Action_ClearAllStatus), "item");

		[HarmonyPostfix]
		private static void Postfix(Action_ClearAllStatus __instance)
		{
			try
			{
				object? obj = _itemField?.GetValue(__instance);
				object? obj2 = ((obj is Item) ? obj : null);
				Character val = ((obj2 != null) ? ((Item)obj2).holderCharacter : null);
				if (!((Object)(object)val == (Object)null) && val.IsLocal)
				{
					((Component)val).GetComponent<BleedingTracker>()?.CureBleeding();
				}
			}
			catch (Exception ex)
			{
				BleedingPlugin.Logger.LogWarning((object)("[Bleeding] ClearAllStatus: " + ex.Message));
			}
		}
	}
}