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;
}
}
}