Decompiled source of Reconsume v1.0.4

Reconsume.dll

Decompiled a week 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.Configuration;
using BepInEx.Logging;
using IL.RoR2;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using RoR2;
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("Reconsume")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Reconsume")]
[assembly: AssemblyTitle("Reconsume")]
[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 Reconsume
{
	public sealed class CommonConfigData
	{
		public bool RefillOnStage;

		public bool CanScrap;

		public CommonConfigData(bool RefillOnStage, bool CanScrap)
		{
			this.RefillOnStage = RefillOnStage;
			this.CanScrap = CanScrap;
		}

		public CommonConfigData(ConfigEntry<bool> RefillOnStageEntry, ConfigEntry<bool> CanScrapEntry)
		{
			RefillOnStage = RefillOnStageEntry.Value;
			CanScrap = CanScrapEntry.Value;
		}
	}
	internal static class Log
	{
		internal static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void LogDebug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void LogError(object data)
		{
			_logSource.LogError(data);
		}

		internal static void LogFatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void LogInfo(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void LogMessage(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void LogWarning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.jiejasonliu.Reconsume", "Reconsume", "1.0.4")]
	public class Reconsume : BaseUnityPlugin
	{
		protected Dictionary<ItemDef, ItemDef> candidateItems;

		protected Dictionary<ItemDef, CommonConfigData> candidateItemsConfigData;

		protected static ConfigEntry<float> RefillConsumedPercent;

		protected static ConfigEntry<bool> RefillPowerElixir;

		protected static ConfigEntry<bool> ScrapConsumedPowerElixir;

		protected static ConfigEntry<float> HealingStrengthPowerElixir;

		protected static ConfigEntry<bool> RefillDelicateWatch;

		protected static ConfigEntry<bool> ScrapConsumedDelicateWatch;

		protected static ConfigEntry<bool> RefillDiosBestFriend;

		protected static ConfigEntry<bool> ScrapConsumedDiosBestFriend;

		public void Awake()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			Log.Init(((BaseUnityPlugin)this).Logger);
			SetupConfiguration();
			Run.Start += new hook_Start(Init_CandidateItems);
			SceneDirector.PopulateScene += new hook_PopulateScene(StageRestore_CandidateItems);
			ScrapperController.BeginScrapping_UniquePickup += new Manipulator(IL_FixItemTier_CandidateItems);
			PickupPickerController.SetOptionsFromInteractor += new Manipulator(IL_ScrapperWhiteList_CandidateItems);
			HealthComponent.UpdateLastHitTime += new Manipulator(IL_AlterHealStrength_PowerElixir);
			Log.LogInfo("Reconsume::Awake() done.");
		}

		private void SetupConfiguration()
		{
			RefillConsumedPercent = ((BaseUnityPlugin)this).Config.Bind<float>("_General", "RefillConsumedPercent", 0.33f, "Percentage of consumed items to restore each stage (0.0 - 1.0; 0.33 being 33%)");
			RefillPowerElixir = ((BaseUnityPlugin)this).Config.Bind<bool>("PowerElixir", "RefillPowerElixir", true, "Restore power elixir at the beginning of each stage");
			ScrapConsumedPowerElixir = ((BaseUnityPlugin)this).Config.Bind<bool>("PowerElixir", "ScrapConsumedPowerElixir", true, "Allow scrapping consumed power elixirs");
			HealingStrengthPowerElixir = ((BaseUnityPlugin)this).Config.Bind<float>("PowerElixir", "HealingStrengthPowerElixir", 0.75f, "Healing strength of power elixir (vanilla default is 0.75)");
			RefillDelicateWatch = ((BaseUnityPlugin)this).Config.Bind<bool>("DelicateWatch", "RefillDelicateWatch", true, "Restore delicate watch at the beginning of each stage");
			ScrapConsumedDelicateWatch = ((BaseUnityPlugin)this).Config.Bind<bool>("DelicateWatch", "ScrapConsumedDelicateWatch", true, "Allow scrapping consumed delicate watches");
			RefillDiosBestFriend = ((BaseUnityPlugin)this).Config.Bind<bool>("DiosBestFriend", "RefillDiosBestFriend", false, "Restore dio's best friend at the beginning of each stage");
			ScrapConsumedDiosBestFriend = ((BaseUnityPlugin)this).Config.Bind<bool>("DiosBestFriend", "ScrapConsumedDiosBestFriend", false, "Allow scrapping consumed dio's best friend");
		}

		private void Init_CandidateItems(orig_Start orig, Run self)
		{
			orig.Invoke(self);
			candidateItems = new Dictionary<ItemDef, ItemDef>
			{
				{
					Items.HealingPotionConsumed,
					Items.HealingPotion
				},
				{
					Items.FragileDamageBonusConsumed,
					Items.FragileDamageBonus
				},
				{
					Items.ExtraLifeConsumed,
					Items.ExtraLife
				}
			};
			candidateItemsConfigData = new Dictionary<ItemDef, CommonConfigData>
			{
				{
					Items.HealingPotionConsumed,
					new CommonConfigData(RefillPowerElixir, ScrapConsumedPowerElixir)
				},
				{
					Items.FragileDamageBonusConsumed,
					new CommonConfigData(RefillDelicateWatch, ScrapConsumedDelicateWatch)
				},
				{
					Items.ExtraLifeConsumed,
					new CommonConfigData(RefillDiosBestFriend, ScrapConsumedDiosBestFriend)
				}
			};
		}

		private void StageRestore_CandidateItems(orig_PopulateScene orig, SceneDirector self)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self);
			float num = Math.Clamp(RefillConsumedPercent.Value, 0f, 1f);
			foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
			{
				Inventory inventory = instance.master.inventory;
				foreach (ItemIndex item in new List<ItemIndex>(inventory.itemAcquisitionOrder))
				{
					ItemDef itemDef = ItemCatalog.GetItemDef(item);
					if (candidateItems.TryGetValue(itemDef, out var value) && candidateItemsConfigData[itemDef].RefillOnStage)
					{
						int itemCountPermanent = inventory.GetItemCountPermanent(itemDef);
						int num2 = ((itemCountPermanent >= 1) ? Convert.ToInt32(Math.Ceiling((float)itemCountPermanent * num)) : 0);
						inventory.RemoveItemPermanent(itemDef, num2);
						inventory.GiveItemPermanent(value, num2);
					}
				}
			}
		}

		private void IL_FixItemTier_CandidateItems(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			val.GotoNext((MoveType)0, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, typeof(ItemDef), "get_tier"),
				(Instruction x) => ILPatternMatchingExt.MatchCall(x, typeof(PickupCatalog), "FindScrapIndexForItemTier")
			});
			val.Index += 1;
			val.Emit(OpCodes.Ldarg_1);
			val.EmitDelegate<Func<ItemTier, UniquePickup, ItemTier>>((Func<ItemTier, UniquePickup, ItemTier>)delegate(ItemTier pickupToTakeItemTier, UniquePickup pickupToTake)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Invalid comparison between Unknown and I4
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: 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_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: 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)
				if ((int)pickupToTakeItemTier == 5)
				{
					PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupToTake.pickupIndex);
					ItemIndex val2 = (ItemIndex)((pickupDef == null) ? (-1) : ((int)pickupDef.itemIndex));
					foreach (var (val5, val6) in candidateItems)
					{
						if (val2 == val5.itemIndex)
						{
							return val6.tier;
						}
					}
				}
				return pickupToTakeItemTier;
			});
		}

		private void IL_ScrapperWhiteList_CandidateItems(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			val.GotoNext((MoveType)0, new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 0),
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, "System.Collections.Generic.List`1<RoR2.PickupPickerController/Option>", "ToArray")
			});
			val.Emit(OpCodes.Ldarg_1);
			val.Emit(OpCodes.Ldloc_0);
			val.EmitDelegate<Action<Interactor, List<Option>>>((Action<Interactor, List<Option>>)delegate(Interactor activator, List<Option> optionList)
			{
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: 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_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: 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_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: 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)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				object obj;
				if (activator == null)
				{
					obj = null;
				}
				else
				{
					CharacterBody component = ((Component)activator).GetComponent<CharacterBody>();
					obj = ((component != null) ? component.inventory : null);
				}
				Inventory val2 = (Inventory)obj;
				if (!Object.op_Implicit((Object)(object)val2))
				{
					return;
				}
				foreach (ItemIndex item in new List<ItemIndex>(val2.itemAcquisitionOrder))
				{
					ItemDef itemDef = ItemCatalog.GetItemDef(item);
					if (candidateItems.TryGetValue(itemDef, out var _) && candidateItemsConfigData[itemDef].CanScrap)
					{
						PickupIndex val3 = PickupCatalog.FindPickupIndex(item);
						optionList.Add(new Option
						{
							available = true,
							pickup = new UniquePickup(val3)
							{
								decayValue = 0f
							}
						});
					}
				}
			});
		}

		private void IL_AlterHealStrength_PowerElixir(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int num = default(int);
			val.GotoNext((MoveType)0, new Func<Instruction, bool>[4]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 0.75f),
				(Instruction x) => ILPatternMatchingExt.MatchLdloca(x, ref num),
				(Instruction x) => ILPatternMatchingExt.MatchInitobj(x, "RoR2.ProcChainMask")
			});
			val.Index += 1;
			val.Remove();
			float value = HealingStrengthPowerElixir.Value;
			val.Emit(OpCodes.Ldc_R4, value);
		}
	}
}