Decompiled source of MultiTrinket v1.0.1

MultiTrinket.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.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 MaxAdrenalineTrinkets
{
	[BepInPlugin("hasib.MaxAdrenalineTrinkets", "Max Adrenaline Trinkets", "1.0.2")]
	public class MaxAdrenalineTrinkets : BaseUnityPlugin
	{
		internal static class Patches
		{
			private static bool _inTrigger;

			private static readonly FieldInfo FI_PlayerAdrenaline = AccessTools.Field(typeof(Player), "m_adrenaline");

			private static readonly FieldInfo FI_SharedMaxAdrenaline = AccessTools.Field(typeof(SharedData), "m_maxAdrenaline");

			private static readonly FieldInfo FI_SharedFullAdrenalineSE = AccessTools.Field(typeof(SharedData), "m_fullAdrenalineSE");

			private static readonly MethodInfo MI_GetSEMan = AccessTools.Method(typeof(Character), "GetSEMan", (Type[])null, (Type[])null);

			private static MethodInfo _miAddSE;

			private static MethodInfo _miInternalAddSE;

			private static MethodInfo _miRpcAddSE;

			[HarmonyPatch(typeof(Player), "GetEquipmentMaxAdrenaline")]
			[HarmonyPrefix]
			private static bool GetEquipmentMaxAdrenaline_Prefix(Player __instance, ref float __result)
			{
				List<ItemData> equippedTrinkets = GetEquippedTrinkets(__instance);
				if (equippedTrinkets.Count == 0)
				{
					return true;
				}
				float num = equippedTrinkets.Select(GetTrinketMaxAdrenaline).DefaultIfEmpty(0f).Max();
				__result = num;
				return false;
			}

			[HarmonyPatch(typeof(Player), "GetMaxAdrenaline")]
			[HarmonyPrefix]
			private static bool GetMaxAdrenaline_Prefix(Player __instance, ref float __result)
			{
				List<ItemData> equippedTrinkets = GetEquippedTrinkets(__instance);
				if (equippedTrinkets.Count == 0)
				{
					return true;
				}
				float num = equippedTrinkets.Select(GetTrinketMaxAdrenaline).DefaultIfEmpty(0f).Max();
				__result = num;
				return false;
			}

			[HarmonyPatch(typeof(Player), "AddAdrenaline")]
			[HarmonyPostfix]
			private static void AddAdrenaline_Postfix(Player __instance, float v)
			{
				if (_inTrigger)
				{
					return;
				}
				List<ItemData> equippedTrinkets = GetEquippedTrinkets(__instance);
				if (equippedTrinkets.Count == 0)
				{
					return;
				}
				float num = equippedTrinkets.Select(GetTrinketMaxAdrenaline).DefaultIfEmpty(0f).Max();
				if (num <= 0.001f || GetPlayerAdrenaline(__instance) < num - 0.001f)
				{
					return;
				}
				try
				{
					_inTrigger = true;
					foreach (ItemData item in equippedTrinkets)
					{
						TryActivateTrinket(__instance, item);
					}
					SetPlayerAdrenaline(__instance, 0f);
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"Full-adrenaline trigger failed: {arg}");
				}
				finally
				{
					_inTrigger = false;
				}
			}

			private static List<ItemData> GetEquippedTrinkets(Player p)
			{
				Inventory val = ((p != null) ? ((Humanoid)p).GetInventory() : null);
				if (val == null)
				{
					return new List<ItemData>();
				}
				return (from i in val.GetAllItems()
					where i != null && i.m_equipped && IsTrinket(i)
					select i).ToList();
			}

			private static bool IsTrinket(ItemData item)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Invalid comparison between Unknown and I4
				if (item?.m_shared != null)
				{
					return (int)item.m_shared.m_itemType == 24;
				}
				return false;
			}

			private static float GetTrinketMaxAdrenaline(ItemData item)
			{
				if (item?.m_shared == null || FI_SharedMaxAdrenaline == null)
				{
					return 0f;
				}
				try
				{
					return (FI_SharedMaxAdrenaline.GetValue(item.m_shared) is float num) ? num : 0f;
				}
				catch
				{
					return 0f;
				}
			}

			private static float GetPlayerAdrenaline(Player p)
			{
				if (FI_PlayerAdrenaline == null)
				{
					return 0f;
				}
				object value = FI_PlayerAdrenaline.GetValue(p);
				if (value is float)
				{
					return (float)value;
				}
				return 0f;
			}

			private static void SetPlayerAdrenaline(Player p, float value)
			{
				FI_PlayerAdrenaline?.SetValue(p, value);
			}

			private static void TryActivateTrinket(Player p, ItemData trinket)
			{
				if (trinket?.m_shared == null || FI_SharedFullAdrenalineSE == null)
				{
					return;
				}
				object value;
				try
				{
					value = FI_SharedFullAdrenalineSE.GetValue(trinket.m_shared);
				}
				catch
				{
					return;
				}
				if (value == null)
				{
					return;
				}
				object sEManInstance = GetSEManInstance(p);
				if (sEManInstance == null)
				{
					return;
				}
				EnsureSEMethodsResolved(sEManInstance.GetType());
				try
				{
					if (_miAddSE != null)
					{
						ParameterInfo[] parameters = _miAddSE.GetParameters();
						if (parameters.Length == 2)
						{
							_miAddSE.Invoke(sEManInstance, new object[2] { value, true });
						}
						else if (parameters.Length == 1)
						{
							_miAddSE.Invoke(sEManInstance, new object[1] { value });
						}
					}
					else if (_miInternalAddSE != null)
					{
						ParameterInfo[] parameters2 = _miInternalAddSE.GetParameters();
						if (parameters2.Length == 2)
						{
							_miInternalAddSE.Invoke(sEManInstance, new object[2] { value, true });
						}
						else if (parameters2.Length == 1)
						{
							_miInternalAddSE.Invoke(sEManInstance, new object[1] { value });
						}
					}
					else if (_miRpcAddSE != null)
					{
						int statusEffectHash = GetStatusEffectHash(value);
						_miRpcAddSE.Invoke(sEManInstance, new object[2] { statusEffectHash, true });
					}
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("Failed to apply trinket SE for '" + trinket.m_shared.m_name + "': " + ex.Message));
				}
			}

			private static object GetSEManInstance(Player p)
			{
				if (MI_GetSEMan == null)
				{
					return null;
				}
				try
				{
					return MI_GetSEMan.Invoke(p, Array.Empty<object>());
				}
				catch
				{
					return null;
				}
			}

			private static void EnsureSEMethodsResolved(Type seManType)
			{
				if (!(seManType == null) && !(_miAddSE != null) && !(_miInternalAddSE != null) && !(_miRpcAddSE != null))
				{
					_miAddSE = AccessTools.Method(seManType, "AddStatusEffect", (Type[])null, (Type[])null);
					_miInternalAddSE = AccessTools.Method(seManType, "Internal_AddStatusEffect", (Type[])null, (Type[])null);
					_miRpcAddSE = AccessTools.Method(seManType, "RPC_AddStatusEffect", (Type[])null, (Type[])null);
				}
			}

			private static int GetStatusEffectHash(object seObj)
			{
				try
				{
					Type type = seObj.GetType();
					FieldInfo fieldInfo = AccessTools.Field(type, "m_nameHash");
					if (fieldInfo != null && fieldInfo.GetValue(seObj) is int result)
					{
						return result;
					}
					PropertyInfo propertyInfo = AccessTools.Property(type, "NameHash");
					if (propertyInfo != null && propertyInfo.GetValue(seObj, null) is int result2)
					{
						return result2;
					}
					MethodInfo methodInfo = AccessTools.Method(type, "GetNameHash", (Type[])null, (Type[])null);
					if (methodInfo != null)
					{
						object obj = methodInfo.Invoke(seObj, null);
						if (obj is int)
						{
							return (int)obj;
						}
					}
				}
				catch
				{
				}
				return seObj.GetHashCode();
			}
		}

		public const string ModGuid = "hasib.MaxAdrenalineTrinkets";

		public const string ModName = "Max Adrenaline Trinkets";

		public const string ModVer = "1.0.2";

		internal static ManualLogSource Log;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Harmony.CreateAndPatchAll(typeof(Patches), "hasib.MaxAdrenalineTrinkets");
			Log.LogInfo((object)"Max Adrenaline Trinkets 1.0.2 loaded.");
		}
	}
}