Decompiled source of items from itsschwer v1.1.0

plugins/itsschwer.Items/itsschwer.Items.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using R2API;
using R2API.Utils;
using RoR2;
using UnityEngine;
using UnityEngine.AddressableAssets;
using itsschwer.Items.Helpers;

[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("itsschwer.Items")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+8f54b236291b87a4c46452df9754d54fd5af77e0")]
[assembly: AssemblyProduct("itsschwer.Items")]
[assembly: AssemblyTitle("itsschwer.Items")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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 itsschwer.Items
{
	internal static class MendConsumed
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<Instruction, bool> <>9__3_2;

			public static Func<Instruction, bool> <>9__3_3;

			public static Func<Instruction, bool> <>9__3_4;

			public static Func<Instruction, bool> <>9__3_6;

			public static Func<Instruction, bool> <>9__3_7;

			public static Func<Instruction, bool> <>9__3_9;

			public static Manipulator <>9__3_0;

			internal void <ApplyIL>b__3_0(ILContext il)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected O, but got Unknown
				//IL_013d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0154: Unknown result type (might be due to invalid IL or missing references)
				//IL_0171: Unknown result type (might be due to invalid IL or missing references)
				//IL_0193: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_0200: Unknown result type (might be due to invalid IL or missing references)
				<>c__DisplayClass3_0 CS$<>8__locals0 = new <>c__DisplayClass3_0();
				ILCursor val = new ILCursor(il);
				CS$<>8__locals0.funcInvoke = null;
				CS$<>8__locals0.nextElseIf = null;
				CS$<>8__locals0.ctorFunc = null;
				FieldReference val3 = default(FieldReference);
				MethodReference val2 = default(MethodReference);
				Func<Instruction, bool>[] array = new Func<Instruction, bool>[9]
				{
					(Instruction x) => ILPatternMatchingExt.MatchBr(x, ref CS$<>8__locals0.funcInvoke),
					(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1),
					(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, ref val3),
					(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Object>(x, "op_Equality"),
					(Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref CS$<>8__locals0.nextElseIf),
					(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
					(Instruction x) => ILPatternMatchingExt.MatchLdftn(x, ref val2),
					(Instruction x) => ILPatternMatchingExt.MatchNewobj(x, ref CS$<>8__locals0.ctorFunc),
					(Instruction x) => ILPatternMatchingExt.MatchStloc(x, 0)
				};
				if (val.TryGotoNext((MoveType)2, array))
				{
					Instruction target = CS$<>8__locals0.nextElseIf.Target;
					try
					{
						val.Emit(OpCodes.Br, CS$<>8__locals0.funcInvoke.Target);
						val.Emit(OpCodes.Ldarg_1);
						CS$<>8__locals0.nextElseIf.Target = val.Previous;
						val.Emit(OpCodes.Ldsfld, typeof(MendConsumed).GetField("equipmentDef", BindingFlags.Static | BindingFlags.Public));
						val.Emit(OpCodes.Call, (MethodBase)typeof(Object).GetMethod("op_Equality"));
						val.Emit(OpCodes.Brfalse, target);
						val.Emit(OpCodes.Ldarg_0);
						val.Emit(OpCodes.Ldftn, (MethodBase)typeof(MendConsumed).GetMethod("Execute", BindingFlags.Static | BindingFlags.NonPublic));
						val.Emit(OpCodes.Newobj, CS$<>8__locals0.ctorFunc);
						val.Emit(OpCodes.Stloc_0);
						return;
					}
					catch (Exception ex)
					{
						Plugin.Logger.LogError((object)ex);
						return;
					}
				}
				Plugin.Logger.LogError((object)"MendConsumed> Cannot hook: failed to match IL instructions.");
			}

			internal bool <ApplyIL>b__3_2(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdarg(x, 1);
			}

			internal bool <ApplyIL>b__3_3(Instruction x)
			{
				FieldReference val = default(FieldReference);
				return ILPatternMatchingExt.MatchLdsfld(x, ref val);
			}

			internal bool <ApplyIL>b__3_4(Instruction x)
			{
				return ILPatternMatchingExt.MatchCallOrCallvirt<Object>(x, "op_Equality");
			}

			internal bool <ApplyIL>b__3_6(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdarg(x, 0);
			}

			internal bool <ApplyIL>b__3_7(Instruction x)
			{
				MethodReference val = default(MethodReference);
				return ILPatternMatchingExt.MatchLdftn(x, ref val);
			}

			internal bool <ApplyIL>b__3_9(Instruction x)
			{
				return ILPatternMatchingExt.MatchStloc(x, 0);
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass3_0
		{
			public ILLabel funcInvoke;

			public ILLabel nextElseIf;

			public MethodReference ctorFunc;

			internal bool <ApplyIL>b__1(Instruction x)
			{
				return ILPatternMatchingExt.MatchBr(x, ref funcInvoke);
			}

			internal bool <ApplyIL>b__5(Instruction x)
			{
				return ILPatternMatchingExt.MatchBrfalse(x, ref nextElseIf);
			}

			internal bool <ApplyIL>b__8(Instruction x)
			{
				return ILPatternMatchingExt.MatchNewobj(x, ref ctorFunc);
			}
		}

		public static readonly EquipmentDef equipmentDef;

		internal static void Init()
		{
			Plugin.Logger.LogDebug((object)("Added equipment " + ((Object)equipmentDef).name + " (" + Language.GetString(equipmentDef.nameToken) + ")"));
		}

		static MendConsumed()
		{
			//IL_0005: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			equipmentDef = Object.Instantiate<EquipmentDef>(Addressables.LoadAssetAsync<EquipmentDef>((object)"RoR2/DLC1/BossHunter/BossHunter.asset").WaitForCompletion());
			((Object)equipmentDef).name = "itsschwer_MendConsumed";
			string text = "itsschwer".ToUpperInvariant() + "_" + "MendConsumed".ToUpperInvariant();
			equipmentDef.nameToken = text + "_NAME";
			equipmentDef.pickupToken = text + "_PICKUP";
			equipmentDef.descriptionToken = text + "_DESC";
			equipmentDef.loreToken = "- no lore -";
			equipmentDef.pickupIconSprite = Addressables.LoadAssetAsync<Sprite>((object)"RoR2/DLC1/LunarWings/texLunarWingsIcon.png").WaitForCompletion();
			equipmentDef.pickupModelPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/DLC1/LunarWings/PickupLunarWings.prefab").WaitForCompletion();
			equipmentDef.equipmentIndex = (EquipmentIndex)(-1);
			equipmentDef.requiredExpansion = null;
			equipmentDef.unlockableDef = null;
			equipmentDef.cooldown = 15f;
			ItemAPI.Add(new CustomEquipment(equipmentDef, (ItemDisplayRule[])null));
			LanguageAPI.Add(equipmentDef.nameToken, "Replenisher");
			LanguageAPI.Add(equipmentDef.pickupToken, "Restores broken, consumed, and empty items. Transforms on use.");
			LanguageAPI.Add(equipmentDef.descriptionToken, "<style=cIsUtility>Restores</style> broken, consumed, and empty items back into their <style=cIsDamage>original forms</style>. Does not affect items that can regenerate. Equipment <style=cIsUtility>transforms</style> into a <style=cIsDamage>random equipment</style> when depleted.");
			ApplyIL();
		}

		private static void ApplyIL()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			MethodInfo? method = typeof(EquipmentSlot).GetMethod("PerformEquipmentAction", BindingFlags.Instance | BindingFlags.NonPublic);
			object obj = <>c.<>9__3_0;
			if (obj == null)
			{
				Manipulator val = delegate(ILContext il)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_000d: Expected O, but got Unknown
					//IL_013d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0154: Unknown result type (might be due to invalid IL or missing references)
					//IL_0171: Unknown result type (might be due to invalid IL or missing references)
					//IL_0193: Unknown result type (might be due to invalid IL or missing references)
					//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
					//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
					//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
					//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
					//IL_0200: Unknown result type (might be due to invalid IL or missing references)
					ILCursor val2 = new ILCursor(il);
					ILLabel funcInvoke = null;
					ILLabel nextElseIf = null;
					MethodReference ctorFunc = null;
					FieldReference val4 = default(FieldReference);
					MethodReference val3 = default(MethodReference);
					Func<Instruction, bool>[] array = new Func<Instruction, bool>[9]
					{
						(Instruction x) => ILPatternMatchingExt.MatchBr(x, ref funcInvoke),
						(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1),
						(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, ref val4),
						(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Object>(x, "op_Equality"),
						(Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref nextElseIf),
						(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
						(Instruction x) => ILPatternMatchingExt.MatchLdftn(x, ref val3),
						(Instruction x) => ILPatternMatchingExt.MatchNewobj(x, ref ctorFunc),
						(Instruction x) => ILPatternMatchingExt.MatchStloc(x, 0)
					};
					if (val2.TryGotoNext((MoveType)2, array))
					{
						Instruction target = nextElseIf.Target;
						try
						{
							val2.Emit(OpCodes.Br, funcInvoke.Target);
							val2.Emit(OpCodes.Ldarg_1);
							nextElseIf.Target = val2.Previous;
							val2.Emit(OpCodes.Ldsfld, typeof(MendConsumed).GetField("equipmentDef", BindingFlags.Static | BindingFlags.Public));
							val2.Emit(OpCodes.Call, (MethodBase)typeof(Object).GetMethod("op_Equality"));
							val2.Emit(OpCodes.Brfalse, target);
							val2.Emit(OpCodes.Ldarg_0);
							val2.Emit(OpCodes.Ldftn, (MethodBase)typeof(MendConsumed).GetMethod("Execute", BindingFlags.Static | BindingFlags.NonPublic));
							val2.Emit(OpCodes.Newobj, ctorFunc);
							val2.Emit(OpCodes.Stloc_0);
							return;
						}
						catch (Exception ex)
						{
							Plugin.Logger.LogError((object)ex);
							return;
						}
					}
					Plugin.Logger.LogError((object)"MendConsumed> Cannot hook: failed to match IL instructions.");
				};
				<>c.<>9__3_0 = val;
				obj = (object)val;
			}
			new ILHook((MethodBase)method, (Manipulator)obj);
		}

		private static bool Execute(this EquipmentSlot equipmentSlot)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody characterBody = equipmentSlot.characterBody;
			Inventory val = ((characterBody != null) ? characterBody.inventory : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return false;
			}
			if (equipmentSlot.stock <= 1)
			{
				PickupDef pickupDef = PickupCatalog.GetPickupDef(Run.instance.availableEquipmentDropList[Random.Range(0, Run.instance.availableEquipmentDropList.Count)]);
				EquipmentIndex val2 = (EquipmentIndex)((pickupDef == null) ? (-1) : ((int)pickupDef.equipmentIndex));
				CharacterMasterNotificationQueue.SendTransformNotification(equipmentSlot.characterBody.master, equipmentSlot.characterBody.inventory.currentEquipmentIndex, val2, (TransformationType)0);
				equipmentSlot.characterBody.inventory.SetEquipmentIndex(val2);
			}
			RestoreConsumedItems(val, equipmentSlot.characterBody.master);
			EffectData val3 = new EffectData
			{
				origin = equipmentSlot.characterBody.transform.position
			};
			val3.SetNetworkedObjectReference(((Component)equipmentSlot.characterBody).gameObject);
			EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/HealingPotionEffect"), val3, true);
			EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ImpactEffects/DelicateWatchProcEffect"), val3, true);
			return true;
		}

		private static void RestoreConsumedItems(Inventory inventory, CharacterMaster notificationTarget)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			(ItemDef, ItemDef)[] transformations = MendConsumedTransformations.GetTransformations(inventory);
			for (int i = 0; i < transformations.Length; i++)
			{
				int itemCount = inventory.GetItemCount(transformations[i].Item1);
				inventory.RemoveItem(transformations[i].Item1, itemCount);
				if (Object.op_Implicit((Object)(object)transformations[i].Item2))
				{
					inventory.GiveItem(transformations[i].Item2, itemCount);
					if (itemCount > 0)
					{
						CharacterMasterNotificationQueue.SendTransformNotification(notificationTarget, transformations[i].Item1.itemIndex, transformations[i].Item2.itemIndex, (TransformationType)0);
					}
				}
			}
		}
	}
	public static class MendConsumedTransformations
	{
		private static List<IReplenishTransformation> transformations = new List<IReplenishTransformation>();

		internal static void Init()
		{
			List<IReplenishTransformation> list = new List<IReplenishTransformation>(5);
			list.Add(new ReplenishTransformation(Items.ExtraLifeConsumed, Items.ExtraLife));
			list.Add(new ConditionalReplenishTransformation(Items.ExtraLifeVoidConsumed, Items.ExtraLifeVoid, Items.ExtraLife, (Inventory inventory) => inventory.GetItemCount(Items.ExtraLifeConsumed) > 0));
			list.Add(new ReplenishTransformation(Items.FragileDamageBonusConsumed, Items.FragileDamageBonus));
			list.Add(new ReplenishTransformation(Items.HealingPotionConsumed, Items.HealingPotion));
			list.Add(new ReplenishTransformation(Items.TonicAffliction, null));
			list.AddRange(transformations);
			transformations = list;
		}

		public static (ItemDef consumed, ItemDef original)[] GetTransformations(Inventory inventory)
		{
			(ItemDef, ItemDef)[] array = new(ItemDef, ItemDef)[transformations.Count];
			for (int i = 0; i < transformations.Count; i++)
			{
				array[i] = (transformations[i].Consumed, transformations[i].GetTransformation(inventory));
			}
			return array;
		}

		public static bool Register(IReplenishTransformation transformation)
		{
			if (transformation == null || (Object)(object)transformation.Consumed == (Object)null)
			{
				return false;
			}
			for (int i = 0; i < transformations.Count; i++)
			{
				if ((Object)(object)transformations[i].Consumed == (Object)(object)transformation.Consumed)
				{
					Plugin.Logger.LogWarning((object)(transformation.Consumed.nameToken + " already has an IReplenishTransformation, skipping transformation from " + GetExecutingMethod()));
					return false;
				}
			}
			transformations.Add(transformation);
			return true;
		}

		private static string GetExecutingMethod(int index = 0)
		{
			MethodBase method = new StackTrace().GetFrame(index + 3).GetMethod();
			return $"{method.DeclaringType}::{method.Name}";
		}
	}
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("itsschwer.Items", "itsschwer.Items", "1.1.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string GUID = "itsschwer.Items";

		public const string Author = "itsschwer";

		public const string Name = "items_from_itsschwer";

		public const string Version = "1.1.0";

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			MendConsumed.Init();
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(MendConsumedTransformations.Init));
			Logger.LogMessage((object)"~awake.");
		}
	}
}
namespace itsschwer.Items.Helpers
{
	public class ConditionalReplenishTransformation : IReplenishTransformation
	{
		private readonly ItemDef consumed;

		private readonly ItemDef original;

		private readonly ItemDef conditional;

		private readonly Func<Inventory, bool> condition;

		public ItemDef Consumed => consumed;

		public ConditionalReplenishTransformation(ItemDef consumed, ItemDef original, ItemDef conditional, Func<Inventory, bool> condition)
		{
			this.consumed = consumed;
			this.original = original;
			this.conditional = conditional;
			this.condition = condition;
		}

		public ItemDef GetTransformation(Inventory inventory)
		{
			if (!condition(inventory))
			{
				return original;
			}
			return conditional;
		}
	}
	public interface IReplenishTransformation
	{
		ItemDef Consumed { get; }

		ItemDef GetTransformation(Inventory inventory);
	}
	public class ReplenishTransformation : IReplenishTransformation
	{
		private readonly ItemDef consumed;

		private readonly ItemDef original;

		public ItemDef Consumed => consumed;

		public ReplenishTransformation(ItemDef consumed, ItemDef original)
		{
			this.consumed = consumed;
			this.original = original;
		}

		public ItemDef GetTransformation(Inventory inventory)
		{
			return original;
		}
	}
}