Decompiled source of PersonalBalancePatch v1.0.0

plugins/PersonalBalancePatch.dll

Decompiled 7 hours ago
using System;
using System.Collections;
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.Bootstrap;
using BepInEx.Logging;
using EntityStates;
using EntityStates.Commando;
using HarmonyLib;
using IL.RoR2;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.EntityStates.Commando;
using On.RoR2;
using On.RoR2.Projectile;
using PersonalBalancePatch.Changes.Economy;
using PersonalBalancePatch.Changes.Global;
using PersonalBalancePatch.Changes.Items.DefiantGouge;
using PersonalBalancePatch.Changes.Items.SingularityBand;
using PersonalBalancePatch.Changes.Items.Transcendence;
using PersonalBalancePatch.Changes.Survivors.Commando;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.Projectile;
using UnityEngine;
using UnityEngine.Networking;

[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("PersonalBalancePatch")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b8fb4a62b83754b875004e579b68ec4cd446b9c0")]
[assembly: AssemblyProduct("PersonalBalancePatch")]
[assembly: AssemblyTitle("PersonalBalancePatch")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 PersonalBalancePatch
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("SSF.PersonalBalancePatch", "PersonalBalancePatch", "1.0.0")]
	public class PersonalBalancePatchPlugin : BaseUnityPlugin
	{
		public const string PluginAuthor = "SSF";

		public const string PluginName = "PersonalBalancePatch";

		public const string PluginGUID = "SSF.PersonalBalancePatch";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			LunarCoinChanges.Init();
			VoidBand.Init();
			KillBounty.Init();
			DefiantGougeChanges.Init();
			TranscendenceChanges.Init();
			GlobalChanges.Init();
			CommandoChanges.Init();
		}

		private void Update()
		{
			TranscendenceChanges.Tick();
			if (!((Object)(object)Run.instance == (Object)null))
			{
				Object.op_Implicit((Object)(object)((PlayerCharacterMasterController.instances.Count > 0) ? PlayerCharacterMasterController.instances[0].master.GetBody() : null));
			}
		}

		private void OnDestroy()
		{
			LunarCoinChanges.Destroy();
			VoidBand.Destroy();
			KillBounty.Destroy();
			DefiantGougeChanges.Destroy();
			TranscendenceChanges.Destroy();
			GlobalChanges.Destroy();
			CommandoChanges.Destroy();
		}
	}
}
namespace PersonalBalancePatch.Changes.Survivors.Commando
{
	public class CommandoChanges
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_OnEnter <0>__DodgeState_OnEnter;
		}

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__DodgeState_OnEnter;
			if (obj == null)
			{
				hook_OnEnter val = DodgeState_OnEnter;
				<>O.<0>__DodgeState_OnEnter = val;
				obj = (object)val;
			}
			DodgeState.OnEnter += (hook_OnEnter)obj;
			LanguageAPI.Add("COMMANDO_UTILITY_DESCRIPTION", "<style=cIsUtility>Roll</style> a short distance. <style=cIsUtility>Refreshes the cooldowns</style> of your other skills.", "en");
		}

		public static void Destroy()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__DodgeState_OnEnter;
			if (obj == null)
			{
				hook_OnEnter val = DodgeState_OnEnter;
				<>O.<0>__DodgeState_OnEnter = val;
				obj = (object)val;
			}
			DodgeState.OnEnter -= (hook_OnEnter)obj;
		}

		private static void DodgeState_OnEnter(orig_OnEnter orig, DodgeState self)
		{
			orig.Invoke(self);
			if (!((EntityState)self).isAuthority)
			{
				return;
			}
			SkillLocator component = ((Component)((EntityState)self).outer).GetComponent<SkillLocator>();
			if (Object.op_Implicit((Object)(object)component))
			{
				if (Object.op_Implicit((Object)(object)component.secondary))
				{
					component.secondary.Reset();
				}
				if (Object.op_Implicit((Object)(object)component.special))
				{
					component.special.Reset();
				}
			}
		}
	}
}
namespace PersonalBalancePatch.Changes.Items.Transcendence
{
	public class TranscendenceChanges
	{
		private struct PendingSound
		{
			public CharacterBody body;

			public float playAt;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__ServerFixedUpdate_IL;

			public static hook_OnOutOfDangerChanged <1>__CharacterBody_OnOutOfDangerChanged;

			public static Action <2>__PatchLookingGlass;

			public static Func<bool, HealthComponent, bool> <3>__ShieldMayRecharge;

			public static Func<HealthComponent, float> <4>__RefillRate;
		}

		private const float VanillaDelay = 7f;

		private const float VanillaRefill = 2f;

		private const float VanillaRate = 0.5f;

		private const float ExtraDelayPerStack = 1f;

		private const float ExtraRefillPerStack = 1f;

		private const string LookingGlassGuid = "droppod.lookingglass";

		private static readonly List<PendingSound> pendingSounds = new List<PendingSound>();

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			object obj = <>O.<0>__ServerFixedUpdate_IL;
			if (obj == null)
			{
				Manipulator val = ServerFixedUpdate_IL;
				<>O.<0>__ServerFixedUpdate_IL = val;
				obj = (object)val;
			}
			HealthComponent.ServerFixedUpdate += (Manipulator)obj;
			object obj2 = <>O.<1>__CharacterBody_OnOutOfDangerChanged;
			if (obj2 == null)
			{
				hook_OnOutOfDangerChanged val2 = CharacterBody_OnOutOfDangerChanged;
				<>O.<1>__CharacterBody_OnOutOfDangerChanged = val2;
				obj2 = (object)val2;
			}
			CharacterBody.OnOutOfDangerChanged += (hook_OnOutOfDangerChanged)obj2;
			LanguageAPI.Add("ITEM_SHIELDONLY_PICKUP", BuildPickup(), "en");
			LanguageAPI.Add("ITEM_SHIELDONLY_DESC", BuildDescription(), "en");
			if (Chainloader.PluginInfos.ContainsKey("droppod.lookingglass"))
			{
				((ResourceAvailability)(ref ItemCatalog.availability)).CallWhenAvailable((Action)PatchLookingGlass);
			}
		}

		public static void Destroy()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			object obj = <>O.<0>__ServerFixedUpdate_IL;
			if (obj == null)
			{
				Manipulator val = ServerFixedUpdate_IL;
				<>O.<0>__ServerFixedUpdate_IL = val;
				obj = (object)val;
			}
			HealthComponent.ServerFixedUpdate -= (Manipulator)obj;
			object obj2 = <>O.<1>__CharacterBody_OnOutOfDangerChanged;
			if (obj2 == null)
			{
				hook_OnOutOfDangerChanged val2 = CharacterBody_OnOutOfDangerChanged;
				<>O.<1>__CharacterBody_OnOutOfDangerChanged = val2;
				obj2 = (object)val2;
			}
			CharacterBody.OnOutOfDangerChanged -= (hook_OnOutOfDangerChanged)obj2;
			pendingSounds.Clear();
		}

		private static int Stacks(HealthComponent hc)
		{
			CharacterBody val = (Object.op_Implicit((Object)(object)hc) ? hc.body : null);
			if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.inventory))
			{
				return val.inventory.GetItemCountEffective(Items.ShieldOnly);
			}
			return 0;
		}

		private static float DelaySeconds(int stacks)
		{
			return 7f + 1f * (float)stacks;
		}

		private static float RefillSeconds(int stacks)
		{
			return 2f + 1f * (float)stacks;
		}

		private static void ServerFixedUpdate_IL(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterBody>(x, "get_outOfDanger")
			}))
			{
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Func<bool, HealthComponent, bool>>((Func<bool, HealthComponent, bool>)ShieldMayRecharge);
			}
			else
			{
				PersonalBalancePatchPlugin.Log.LogError((object)"Transcendence: could not find get_outOfDanger in ServerFixedUpdate; recharge delay NOT changed.");
			}
			val.Index = 0;
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterBody>(x, "get_maxShield"),
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 0.5f)
			}))
			{
				val.Emit(OpCodes.Pop);
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Func<HealthComponent, float>>((Func<HealthComponent, float>)RefillRate);
			}
			else
			{
				PersonalBalancePatchPlugin.Log.LogError((object)"Transcendence: could not find the shield refill rate in ServerFixedUpdate; refill time NOT changed.");
			}
		}

		private static void CharacterBody_OnOutOfDangerChanged(orig_OnOutOfDangerChanged orig, CharacterBody self)
		{
			int num = ((Object.op_Implicit((Object)(object)self) && Object.op_Implicit((Object)(object)self.inventory)) ? self.inventory.GetItemCountEffective(Items.ShieldOnly) : 0);
			if (num <= 0 || !self.outOfDanger)
			{
				orig.Invoke(self);
				return;
			}
			HealthComponent healthComponent = self.healthComponent;
			if (Object.op_Implicit((Object)(object)healthComponent) && healthComponent.shield != healthComponent.fullShield)
			{
				pendingSounds.Add(new PendingSound
				{
					body = self,
					playAt = Time.time + 1f * (float)num
				});
			}
			self.MarkAllStatsDirty();
		}

		public static void Tick()
		{
			for (int num = pendingSounds.Count - 1; num >= 0; num--)
			{
				PendingSound pendingSound = pendingSounds[num];
				if (!Object.op_Implicit((Object)(object)pendingSound.body))
				{
					pendingSounds.RemoveAt(num);
				}
				else if (!(Time.time < pendingSound.playAt))
				{
					pendingSounds.RemoveAt(num);
					HealthComponent healthComponent = pendingSound.body.healthComponent;
					if (pendingSound.body.outOfDanger && Object.op_Implicit((Object)(object)healthComponent) && healthComponent.shield < healthComponent.fullShield)
					{
						if (Object.op_Implicit((Object)(object)pendingSound.body.inventory) && pendingSound.body.inventory.GetItemCountEffective(Items.ShieldBooster) > 0)
						{
							Util.PlaySound("Play_item_use_shieldBooster_regen", ((Component)pendingSound.body).gameObject);
						}
						Util.PlaySound("Play_item_proc_personal_shield_recharge", ((Component)pendingSound.body).gameObject);
					}
				}
			}
		}

		private static bool ShieldMayRecharge(bool outOfDanger, HealthComponent hc)
		{
			if (!outOfDanger)
			{
				return false;
			}
			int num = Stacks(hc);
			if (num <= 0)
			{
				return true;
			}
			return hc.body.outOfDangerStopwatch >= DelaySeconds(num);
		}

		private static float RefillRate(HealthComponent hc)
		{
			int num = Stacks(hc);
			if (num <= 0)
			{
				return 0.5f;
			}
			return 1f / RefillSeconds(num);
		}

		private static string BuildPickup()
		{
			return "Convert all your health into shield. Increase maximum health. Shields recharge more slowly.";
		}

		private static string BuildDescription()
		{
			return "<style=cIsHealing>Convert</style> all but <style=cIsHealing>1 health</style> into <style=cIsHealing>regenerating shields</style>. <style=cIsHealing>Gain 50% <style=cStack>(+25% per stack)</style> maximum health</style>. " + $"Shields start recharging <style=cIsDamage>{1f:0.#}</style> <style=cStack>(+{1f:0.#} per stack)</style> seconds later " + $"and take <style=cIsDamage>{1f:0.#}</style> <style=cStack>(+{1f:0.#} per stack)</style> seconds longer to refill.";
		}

		private static void PatchLookingGlass()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected I4, but got Unknown
			object obj = ((IDictionary)((object)Chainloader.PluginInfos["droppod.lookingglass"].Instance).GetType().Assembly.GetType("LookingGlass.ItemStatsNameSpace.ItemDefinitions").GetField("allItemDefinitions").GetValue(null))[(int)Items.ShieldOnly.itemIndex];
			if (obj == null)
			{
				PersonalBalancePatchPlugin.Log.LogWarning((object)"LookingGlass has no Transcendence entry.");
				return;
			}
			Type type = obj.GetType();
			IList list = (IList)type.GetField("descriptions").GetValue(obj);
			if (!list.Contains("Shield Recharge Delay: "))
			{
				IList list2 = (IList)type.GetField("valueTypes").GetValue(obj);
				IList list3 = (IList)type.GetField("measurementUnits").GetValue(obj);
				object value = Enum.Parse(type.GetNestedType("ValueType"), "Utility");
				object value2 = Enum.Parse(type.GetNestedType("MeasurementUnits"), "Seconds");
				list.Add("Shield Recharge Delay: ");
				list2.Add(value);
				list3.Add(value2);
				list.Add("Shield Refill Time: ");
				list2.Add(value);
				list3.Add(value2);
				FieldInfo field = type.GetField("calculateValuesFlat");
				Func<int, List<float>> original = (Func<int, List<float>>)field.GetValue(obj);
				Func<int, List<float>> value3 = delegate(int stack)
				{
					List<float> list4 = original(stack);
					list4.Add(DelaySeconds(stack));
					list4.Add(RefillSeconds(stack));
					return list4;
				};
				field.SetValue(obj, value3);
				PersonalBalancePatchPlugin.Log.LogInfo((object)"Patched LookingGlass stats for Transcendence.");
			}
		}
	}
}
namespace PersonalBalancePatch.Changes.Items.SingularityBand
{
	public class VoidBand
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_FireProjectile_FireProjectileInfo <0>__FireProjectile_FireProjectileInfo;

			public static hook_AddTimedBuff_BuffDef_float <1>__CharacterBody_AddTimedBuff_BuffDef_float;

			public static Action <2>__PatchLookingGlass;
		}

		public static void Init()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			LanguageAPI.Add("ITEM_ELEMENTALRINGVOID_DESC", BuildDescription(), "en");
			object obj = <>O.<0>__FireProjectile_FireProjectileInfo;
			if (obj == null)
			{
				hook_FireProjectile_FireProjectileInfo val = FireProjectile_FireProjectileInfo;
				<>O.<0>__FireProjectile_FireProjectileInfo = val;
				obj = (object)val;
			}
			ProjectileManager.FireProjectile_FireProjectileInfo += (hook_FireProjectile_FireProjectileInfo)obj;
			object obj2 = <>O.<1>__CharacterBody_AddTimedBuff_BuffDef_float;
			if (obj2 == null)
			{
				hook_AddTimedBuff_BuffDef_float val2 = CharacterBody_AddTimedBuff_BuffDef_float;
				<>O.<1>__CharacterBody_AddTimedBuff_BuffDef_float = val2;
				obj2 = (object)val2;
			}
			CharacterBody.AddTimedBuff_BuffDef_float += (hook_AddTimedBuff_BuffDef_float)obj2;
			if (Chainloader.PluginInfos.ContainsKey("droppod.lookingglass"))
			{
				((ResourceAvailability)(ref ItemCatalog.availability)).CallWhenAvailable((Action)PatchLookingGlass);
			}
		}

		public static void Destroy()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			object obj = <>O.<0>__FireProjectile_FireProjectileInfo;
			if (obj == null)
			{
				hook_FireProjectile_FireProjectileInfo val = FireProjectile_FireProjectileInfo;
				<>O.<0>__FireProjectile_FireProjectileInfo = val;
				obj = (object)val;
			}
			ProjectileManager.FireProjectile_FireProjectileInfo -= (hook_FireProjectile_FireProjectileInfo)obj;
			object obj2 = <>O.<1>__CharacterBody_AddTimedBuff_BuffDef_float;
			if (obj2 == null)
			{
				hook_AddTimedBuff_BuffDef_float val2 = CharacterBody_AddTimedBuff_BuffDef_float;
				<>O.<1>__CharacterBody_AddTimedBuff_BuffDef_float = val2;
				obj2 = (object)val2;
			}
			CharacterBody.AddTimedBuff_BuffDef_float -= (hook_AddTimedBuff_BuffDef_float)obj2;
		}

		private static void FireProjectile_FireProjectileInfo(orig_FireProjectile_FireProjectileInfo orig, ProjectileManager self, FireProjectileInfo info)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)info.projectilePrefab) && ((Object)info.projectilePrefab).name == "ElementalRingVoidBlackHole")
			{
				info.damage *= 1.5f;
			}
			orig.Invoke(self, info);
		}

		private static void CharacterBody_AddTimedBuff_BuffDef_float(orig_AddTimedBuff_BuffDef_float orig, CharacterBody self, BuffDef buffDef, float duration)
		{
			if (!((Object)(object)buffDef == (Object)(object)Buffs.ElementalRingVoidCooldown) || !(duration > 13f))
			{
				orig.Invoke(self, buffDef, duration);
			}
		}

		private static string BuildDescription()
		{
			return "Hits that deal <style=cIsDamage>more than 400% damage</style> also fire a black hole that <style=cIsUtility>draws enemies within 15m into its center</style>. Lasts <style=cIsUtility>5</style> seconds before collapsing, dealing " + $"<style=cIsDamage>{150}%</style> <style=cStack>(+{150}% per stack)</style> TOTAL damage. " + $"Recharges every <style=cIsUtility>{13}</style> seconds. " + "<style=cIsVoid>Corrupts all Runald's and Kjaro's Bands</style>.";
		}

		private static void PatchLookingGlass()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected I4, but got Unknown
			object obj = ((IDictionary)((object)Chainloader.PluginInfos["droppod.lookingglass"].Instance).GetType().Assembly.GetType("LookingGlass.ItemStatsNameSpace.ItemDefinitions").GetField("allItemDefinitions").GetValue(null))[(int)Items.ElementalRingVoid.itemIndex];
			if (obj == null)
			{
				PersonalBalancePatchPlugin.Log.LogWarning((object)"LookingGlass has no Singularity Band entry.");
				return;
			}
			Type type = obj.GetType();
			IList list = (IList)type.GetField("descriptions").GetValue(obj);
			if (!list.Contains("Recharge Time: "))
			{
				list.Add("Recharge Time: ");
				((IList)type.GetField("valueTypes").GetValue(obj)).Add(Enum.Parse(type.GetNestedType("ValueType"), "Utility"));
				((IList)type.GetField("measurementUnits").GetValue(obj)).Add(Enum.Parse(type.GetNestedType("MeasurementUnits"), "Seconds"));
			}
			Func<int, List<float>> value = (int stack) => new List<float>
			{
				(float)stack * 1.5f,
				1f,
				13f
			};
			type.GetField("calculateValuesFlat").SetValue(obj, value);
			PersonalBalancePatchPlugin.Log.LogInfo((object)"Patched LookingGlass stats for Singularity Band.");
		}
	}
}
namespace PersonalBalancePatch.Changes.Items.DefiantGouge
{
	public class DefiantGougeChanges
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__DisableVanillaTrigger;

			public static hook_AddShrineStack <1>__ShrineChanceBehavior_AddShrineStack;

			public static Action <2>__PatchLookingGlass;
		}

		private const float FailureAtOneStack = 0.25f;

		private const float FailureMultiplierPerExtraStack = 0.8f;

		private const float CreditPerStack = 80f;

		private const string LookingGlassGuid = "droppod.lookingglass";

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			object obj = <>O.<0>__DisableVanillaTrigger;
			if (obj == null)
			{
				Manipulator val = DisableVanillaTrigger;
				<>O.<0>__DisableVanillaTrigger = val;
				obj = (object)val;
			}
			GlobalEventManager.OnInteractionBegin += (Manipulator)obj;
			object obj2 = <>O.<1>__ShrineChanceBehavior_AddShrineStack;
			if (obj2 == null)
			{
				hook_AddShrineStack val2 = ShrineChanceBehavior_AddShrineStack;
				<>O.<1>__ShrineChanceBehavior_AddShrineStack = val2;
				obj2 = (object)val2;
			}
			ShrineChanceBehavior.AddShrineStack += (hook_AddShrineStack)obj2;
			LanguageAPI.Add("ITEM_MONSTERSONSHRINEUSE_PICKUP", BuildPickup(), "en");
			LanguageAPI.Add("ITEM_MONSTERSONSHRINEUSE_DESC", BuildDescription(), "en");
			LanguageAPI.Add("PERSONALBALANCEPATCH_GOUGE_WRONG_GOD", "<style=cShrine>{0} prayed to the wrong god...</color>", "en");
			LanguageAPI.Add("PERSONALBALANCEPATCH_GOUGE_WRONG_GOD_2P", "<style=cShrine>You prayed to the wrong god...</color>", "en");
			if (Chainloader.PluginInfos.ContainsKey("droppod.lookingglass"))
			{
				((ResourceAvailability)(ref ItemCatalog.availability)).CallWhenAvailable((Action)PatchLookingGlass);
			}
		}

		public static void Destroy()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			object obj = <>O.<0>__DisableVanillaTrigger;
			if (obj == null)
			{
				Manipulator val = DisableVanillaTrigger;
				<>O.<0>__DisableVanillaTrigger = val;
				obj = (object)val;
			}
			GlobalEventManager.OnInteractionBegin -= (Manipulator)obj;
			object obj2 = <>O.<1>__ShrineChanceBehavior_AddShrineStack;
			if (obj2 == null)
			{
				hook_AddShrineStack val2 = ShrineChanceBehavior_AddShrineStack;
				<>O.<1>__ShrineChanceBehavior_AddShrineStack = val2;
				obj2 = (object)val2;
			}
			ShrineChanceBehavior.AddShrineStack -= (hook_AddShrineStack)obj2;
		}

		private static float FailureChance(int stacks)
		{
			return 0.25f * Mathf.Pow(0.8f, (float)(Mathf.Max(1, stacks) - 1));
		}

		private static void DisableVanillaTrigger(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_006b: 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)
			ILCursor val = new ILCursor(il);
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(Items), "MonstersOnShrineUse"),
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt<Inventory>(x, "GetItemCountEffective")
			}))
			{
				PersonalBalancePatchPlugin.Log.LogError((object)"DefiantGouge: could not find the item-count read in OnInteractionBegin; vanilla trigger is NOT disabled.");
				return;
			}
			val.Emit(OpCodes.Pop);
			val.Emit(OpCodes.Ldc_I4_0);
		}

		private static void ShrineChanceBehavior_AddShrineStack(orig_AddShrineStack orig, ShrineChanceBehavior self, Interactor activator)
		{
			int num = 0;
			CharacterBody val = (Object.op_Implicit((Object)(object)activator) ? ((Component)activator).GetComponent<CharacterBody>() : null);
			if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.inventory))
			{
				num = val.inventory.GetItemCountEffective(Items.MonstersOnShrineUse);
			}
			if (!NetworkServer.active || num <= 0)
			{
				orig.Invoke(self, activator);
				return;
			}
			float failureChance = self.failureChance;
			int successfulPurchaseCount = self.successfulPurchaseCount;
			self.failureChance = Mathf.Min(failureChance, FailureChance(num));
			try
			{
				orig.Invoke(self, activator);
			}
			finally
			{
				self.failureChance = failureChance;
			}
			if (self.successfulPurchaseCount == successfulPurchaseCount)
			{
				Punish(self, activator, val, num);
			}
		}

		private static void Punish(ShrineChanceBehavior shrine, Interactor activator, CharacterBody body, int stacks)
		{
			//IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			Chat.SendBroadcastChat((ChatMessageBase)new SubjectFormatChatMessage
			{
				subjectAsCharacterBody = body,
				baseToken = "PERSONALBALANCEPATCH_GOUGE_WRONG_GOD"
			});
			GameObject val = LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/Encounters/MonstersOnShrineUseEncounter");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)Stage.instance))
			{
				return;
			}
			Vector3 position = ((Component)shrine).transform.position;
			GameObject val2 = Object.Instantiate<GameObject>(val, position, Quaternion.identity);
			NetworkServer.Spawn(val2);
			CombatDirector component = val2.GetComponent<CombatDirector>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				NetworkServer.Destroy(val2);
				return;
			}
			float num = 80f * Stage.instance.entryDifficultyCoefficient * (float)stacks;
			DirectorCard val3 = component.SelectMonsterCardForCombatShrine(num);
			if (val3 == null)
			{
				NetworkServer.Destroy(val2);
				return;
			}
			component.CombatShrineActivation(activator, num, val3);
			EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/MonstersOnShrineUse"), new EffectData
			{
				origin = position,
				rotation = Quaternion.identity
			}, true);
		}

		private static string BuildPickup()
		{
			return "Shrines of Chance fail less often, but failing summons enemies nearby.";
		}

		private static string BuildDescription()
		{
			int num = Mathf.RoundToInt(25f);
			int num2 = Mathf.RoundToInt(19.999998f);
			return $"<style=cIsUtility>Shrines of Chance</style> fail much less often: failure chance becomes <style=cIsUtility>{num}%</style> " + $"<style=cStack>(each additional stack reduces it by {num2}%, multiplicatively)</style>. " + "<style=cIsHealth>A failed Shrine of Chance summons enemies</style> nearby. <style=cIsUtility>Scales over time.</style>";
		}

		private static void PatchLookingGlass()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected I4, but got Unknown
			object obj = ((IDictionary)((object)Chainloader.PluginInfos["droppod.lookingglass"].Instance).GetType().Assembly.GetType("LookingGlass.ItemStatsNameSpace.ItemDefinitions").GetField("allItemDefinitions").GetValue(null))[(int)Items.MonstersOnShrineUse.itemIndex];
			if (obj == null)
			{
				PersonalBalancePatchPlugin.Log.LogWarning((object)"LookingGlass has no Defiant Gouge entry.");
				return;
			}
			Type type = obj.GetType();
			IList list = (IList)type.GetField("descriptions").GetValue(obj);
			if (!list.Contains("Shrine of Chance Failure: "))
			{
				list.Add("Shrine of Chance Failure: ");
				((IList)type.GetField("valueTypes").GetValue(obj)).Add(Enum.Parse(type.GetNestedType("ValueType"), "Utility"));
				((IList)type.GetField("measurementUnits").GetValue(obj)).Add(Enum.Parse(type.GetNestedType("MeasurementUnits"), "Percentage"));
				FieldInfo field = type.GetField("calculateValuesFlat");
				Func<int, List<float>> original = (Func<int, List<float>>)field.GetValue(obj);
				Func<int, List<float>> value = delegate(int stack)
				{
					List<float> list2 = original(stack);
					list2.Add(FailureChance(stack));
					return list2;
				};
				field.SetValue(obj, value);
				PersonalBalancePatchPlugin.Log.LogInfo((object)"Patched LookingGlass stats for Defiant Gouge.");
			}
		}
	}
}
namespace PersonalBalancePatch.Changes.Global
{
	public class GlobalChanges
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__HitGround_IL;

			public static Func<float, CharacterBody, float> <1>__FallDamagePool;
		}

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__HitGround_IL;
			if (obj == null)
			{
				Manipulator val = HitGround_IL;
				<>O.<0>__HitGround_IL = val;
				obj = (object)val;
			}
			GlobalEventManager.OnCharacterHitGroundServer += (Manipulator)obj;
		}

		public static void Destroy()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__HitGround_IL;
			if (obj == null)
			{
				Manipulator val = HitGround_IL;
				<>O.<0>__HitGround_IL = val;
				obj = (object)val;
			}
			GlobalEventManager.OnCharacterHitGroundServer -= (Manipulator)obj;
		}

		private static void HitGround_IL(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1),
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterBody>(x, "get_maxHealth")
			}))
			{
				val.Emit(OpCodes.Ldarg_1);
				val.EmitDelegate<Func<float, CharacterBody, float>>((Func<float, CharacterBody, float>)FallDamagePool);
			}
			else
			{
				PersonalBalancePatchPlugin.Log.LogError((object)"Global: could not find maxHealth in OnCharacterHitGroundServer; fall damage NOT changed.");
			}
		}

		private static float FallDamagePool(float maxHealth, CharacterBody body)
		{
			if (!Object.op_Implicit((Object)(object)body))
			{
				return maxHealth;
			}
			return maxHealth + body.maxShield;
		}
	}
}
namespace PersonalBalancePatch.Changes.Economy
{
	public class KillBounty
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_OnKilledServer <0>__DeathRewards_OnKilledServer;
		}

		private const float VanillaMultiplier = 2f;

		private const float StartMultiplier = 2.25f;

		private const float FloorMultiplier = 0.75f;

		private const float StartCoeff = 1f;

		private const float Decay = 4f;

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__DeathRewards_OnKilledServer;
			if (obj == null)
			{
				hook_OnKilledServer val = DeathRewards_OnKilledServer;
				<>O.<0>__DeathRewards_OnKilledServer = val;
				obj = (object)val;
			}
			DeathRewards.OnKilledServer += (hook_OnKilledServer)obj;
		}

		public static void Destroy()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__DeathRewards_OnKilledServer;
			if (obj == null)
			{
				hook_OnKilledServer val = DeathRewards_OnKilledServer;
				<>O.<0>__DeathRewards_OnKilledServer = val;
				obj = (object)val;
			}
			DeathRewards.OnKilledServer -= (hook_OnKilledServer)obj;
		}

		private static void DeathRewards_OnKilledServer(orig_OnKilledServer orig, DeathRewards self, DamageReport damagereport)
		{
			if (self.goldReward != 0)
			{
				uint goldReward = self.goldReward;
				float compensatedDifficultyCoefficient = Run.instance.compensatedDifficultyCoefficient;
				float num = Multiplier(compensatedDifficultyCoefficient);
				float num2 = (float)goldReward * (num / 2f);
				uint num3 = (self.goldReward = (uint)Mathf.Max(1f, Mathf.Round(num2)));
				PersonalBalancePatchPlugin.Log.LogInfo((object)($"[KillBounty] stage={Run.instance.stageClearCount + 1} t={Run.instance.GetRunStopwatch() / 60f:F1}m " + $"coeff={compensatedDifficultyCoefficient:F2} mult={num:F2} chest(25)={Run.instance.GetDifficultyScaledCost(25)} gold={goldReward}->{num3}"));
			}
			orig.Invoke(self, damagereport);
		}

		private static float Multiplier(float coeff)
		{
			float num = Mathf.Max(0f, coeff - 1f);
			return 0.75f + 1.5f * Mathf.Exp((0f - num) / 4f);
		}
	}
	public class LunarCoinChanges
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__PlayerCharacterMasterController_Awake;

			public static Action<DamageReport> <1>__OnDeathProcServerOverride;

			public static hook_SyncLunarCoinsToServer <2>__NetworkUser_SyncLunarCoinsToServer;

			public static Action<Run> <3>__OnRunStartGlobal;

			public static hook_RpcAwardLunarCoins <4>__NetworkUser_RpcAwardLunarCoins;

			public static hook_RpcDeductLunarCoins <5>__NetworkUser_RpcDeductLunarCoins;
		}

		private static Harmony harmony;

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			object obj = <>O.<0>__PlayerCharacterMasterController_Awake;
			if (obj == null)
			{
				hook_Awake val = PlayerCharacterMasterController_Awake;
				<>O.<0>__PlayerCharacterMasterController_Awake = val;
				obj = (object)val;
			}
			PlayerCharacterMasterController.Awake += (hook_Awake)obj;
			GlobalEventManager.onDeathProcServer += OnDeathProcServerOverride;
			object obj2 = <>O.<2>__NetworkUser_SyncLunarCoinsToServer;
			if (obj2 == null)
			{
				hook_SyncLunarCoinsToServer val2 = NetworkUser_SyncLunarCoinsToServer;
				<>O.<2>__NetworkUser_SyncLunarCoinsToServer = val2;
				obj2 = (object)val2;
			}
			NetworkUser.SyncLunarCoinsToServer += (hook_SyncLunarCoinsToServer)obj2;
			Run.onRunStartGlobal += OnRunStartGlobal;
			object obj3 = <>O.<4>__NetworkUser_RpcAwardLunarCoins;
			if (obj3 == null)
			{
				hook_RpcAwardLunarCoins val3 = NetworkUser_RpcAwardLunarCoins;
				<>O.<4>__NetworkUser_RpcAwardLunarCoins = val3;
				obj3 = (object)val3;
			}
			NetworkUser.RpcAwardLunarCoins += (hook_RpcAwardLunarCoins)obj3;
			object obj4 = <>O.<5>__NetworkUser_RpcDeductLunarCoins;
			if (obj4 == null)
			{
				hook_RpcDeductLunarCoins val4 = NetworkUser_RpcDeductLunarCoins;
				<>O.<5>__NetworkUser_RpcDeductLunarCoins = val4;
				obj4 = (object)val4;
			}
			NetworkUser.RpcDeductLunarCoins += (hook_RpcDeductLunarCoins)obj4;
			harmony = Harmony.CreateAndPatchAll(typeof(LunarCoinsGetterPatch), (string)null);
		}

		public static void Destroy()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			object obj = <>O.<0>__PlayerCharacterMasterController_Awake;
			if (obj == null)
			{
				hook_Awake val = PlayerCharacterMasterController_Awake;
				<>O.<0>__PlayerCharacterMasterController_Awake = val;
				obj = (object)val;
			}
			PlayerCharacterMasterController.Awake -= (hook_Awake)obj;
			GlobalEventManager.onDeathProcServer -= OnDeathProcServerOverride;
			object obj2 = <>O.<2>__NetworkUser_SyncLunarCoinsToServer;
			if (obj2 == null)
			{
				hook_SyncLunarCoinsToServer val2 = NetworkUser_SyncLunarCoinsToServer;
				<>O.<2>__NetworkUser_SyncLunarCoinsToServer = val2;
				obj2 = (object)val2;
			}
			NetworkUser.SyncLunarCoinsToServer -= (hook_SyncLunarCoinsToServer)obj2;
			Run.onRunStartGlobal -= OnRunStartGlobal;
			object obj3 = <>O.<4>__NetworkUser_RpcAwardLunarCoins;
			if (obj3 == null)
			{
				hook_RpcAwardLunarCoins val3 = NetworkUser_RpcAwardLunarCoins;
				<>O.<4>__NetworkUser_RpcAwardLunarCoins = val3;
				obj3 = (object)val3;
			}
			NetworkUser.RpcAwardLunarCoins -= (hook_RpcAwardLunarCoins)obj3;
			object obj4 = <>O.<5>__NetworkUser_RpcDeductLunarCoins;
			if (obj4 == null)
			{
				hook_RpcDeductLunarCoins val4 = NetworkUser_RpcDeductLunarCoins;
				<>O.<5>__NetworkUser_RpcDeductLunarCoins = val4;
				obj4 = (object)val4;
			}
			NetworkUser.RpcDeductLunarCoins -= (hook_RpcDeductLunarCoins)obj4;
			Harmony obj5 = harmony;
			if (obj5 != null)
			{
				obj5.UnpatchSelf();
			}
		}

		private static void PlayerCharacterMasterController_Awake(orig_Awake orig, PlayerCharacterMasterController self)
		{
			orig.Invoke(self);
			self.lunarCoinChanceMultiplier = 0f;
		}

		private static void NetworkUser_SyncLunarCoinsToServer(orig_SyncLunarCoinsToServer orig, NetworkUser self)
		{
		}

		private static void NetworkUser_RpcAwardLunarCoins(orig_RpcAwardLunarCoins orig, NetworkUser self, uint count)
		{
		}

		private static void NetworkUser_RpcDeductLunarCoins(orig_RpcDeductLunarCoins orig, NetworkUser self, uint count)
		{
		}

		private static void OnDeathProcServerOverride(DamageReport damageReport)
		{
			//IL_0051: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			CharacterMaster val = damageReport.attackerMaster;
			if (Object.op_Implicit((Object)(object)val))
			{
				if (Object.op_Implicit((Object)(object)val.minionOwnership.ownerMaster))
				{
					val = val.minionOwnership.ownerMaster;
				}
				if (Object.op_Implicit((Object)(object)((Component)val).GetComponent<PlayerCharacterMasterController>()) && Util.CheckRoll(2f, 0f, (CharacterMaster)null))
				{
					PickupDropletController.CreatePickupDroplet(PickupCatalog.FindPickupIndex(MiscPickups.LunarCoin.miscPickupIndex), ((Component)damageReport.victim).transform.position, Vector3.up * 10f);
				}
			}
		}

		private static void OnRunStartGlobal(Run _)
		{
			if (!NetworkServer.active)
			{
				return;
			}
			foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList)
			{
				readOnlyInstances.NetworknetLunarCoins = 0u;
			}
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static class LunarCoinsGetterPatch
	{
		[HarmonyPostfix]
		private static void Postfix(NetworkUser __instance, ref uint __result)
		{
			__result = __instance.NetworknetLunarCoins;
		}
	}
}