Decompiled source of NoMoreMath v2.1.1

plugins/NoMoreMath/NoMoreMath.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.ShrineHalcyonite;
using HG;
using HG.Reflection;
using IL.RoR2;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using NoMoreMath.Config;
using NoMoreMath.EffectiveCost;
using NoMoreMath.EffectiveHealth;
using NoMoreMath.HalcyonBeacon;
using NoMoreMath.HalcyonShrine;
using NoMoreMath.HoldoutZone;
using NoMoreMath.MiscPatches;
using NoMoreMath.ModCompatibility;
using NoMoreMath.ShrineBlood;
using NoMoreMath.ShrineChance;
using NoMoreMath.Utils;
using On.RoR2;
using On.RoR2.UI;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.UI;
using TMPro;
using Unity;
using UnityEngine;
using UnityEngine.Networking;

[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCompany("NoMoreMath")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyTitle("NoMoreMath")]
[assembly: AssemblyProduct("NoMoreMath")]
[assembly: AssemblyInformationalVersion("1.0.0+6f6aeda2cabe6ff0ac83defcd739ce7c9bf1e5da")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[Microsoft.CodeAnalysis.Embedded]
	[CompilerGenerated]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[Microsoft.CodeAnalysis.Embedded]
	[CompilerGenerated]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace NoMoreMath
{
	internal static class Log
	{
		private static readonly StringBuilder _sharedStringBuilder;

		private static readonly int _cachedCallerPathPrefixLength;

		private static ManualLogSource _logSource;

		static Log()
		{
			_sharedStringBuilder = new StringBuilder(256);
			_cachedCallerPathPrefixLength = getCallerPathPrefixLength("X:\\Git\\RoR2\\NoMoreMath\\NoMoreMath\\Log.cs");
			static int getCallerPathPrefixLength([CallerFilePath] string callerPath = null)
			{
				int num = callerPath.LastIndexOf("NoMoreMath\\");
				if (num >= 0)
				{
					return num + "NoMoreMath\\".Length;
				}
				Debug.LogError((object)"[NoMoreMath] Logger failed to determine caller path prefix length");
				return 0;
			}
		}

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

		private static StringBuilder appendCallerPrefix(this StringBuilder stringBuilder, string callerPath, string callerMemberName, int callerLineNumber)
		{
			return stringBuilder.Append(callerPath, _cachedCallerPathPrefixLength, callerPath.Length - _cachedCallerPathPrefixLength).Append(':').Append(callerLineNumber)
				.Append(" (")
				.Append(callerMemberName)
				.Append("): ");
		}

		private static StringBuilder buildCallerLogString(string callerPath, string callerMemberName, int callerLineNumber, object data)
		{
			return _sharedStringBuilder.Clear().appendCallerPrefix(callerPath, callerMemberName, callerLineNumber).Append(data);
		}

		internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogError((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Error_NoCallerPrefix(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogFatal((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Fatal_NoCallerPrefix(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogInfo((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Info_NoCallerPrefix(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogMessage((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Message_NoCallerPrefix(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogWarning((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Warning_NoCallerPrefix(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	[BepInPlugin("Gorakh.NoMoreMath", "NoMoreMath", "2.1.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class NoMoreMathPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "Gorakh.NoMoreMath";

		public const string PluginAuthor = "Gorakh";

		public const string PluginName = "NoMoreMath";

		public const string PluginVersion = "2.1.1";

		internal static NoMoreMathPlugin Instance { get; private set; }

		private void Awake()
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			Instance = SingletonHelper.Assign<NoMoreMathPlugin>(Instance, this);
			Log.Init(((BaseUnityPlugin)this).Logger);
			Configs.Init(((BaseUnityPlugin)this).Config);
			if (RiskOfOptionsCompat.Enabled)
			{
				RiskOfOptionsCompat.Init();
			}
			stopwatch.Stop();
			Log.Message_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalMilliseconds:F0}ms");
		}

		private void OnDestroy()
		{
			Instance = SingletonHelper.Unassign<NoMoreMathPlugin>(Instance, this);
		}
	}
}
namespace NoMoreMath.Utils
{
	public interface ICachableComponent
	{
		int? DictionaryKey { get; set; }
	}
	public class ObjectComponentCache<THostComponent, TCachedComponent> where THostComponent : Component where TCachedComponent : MonoBehaviour, ICachableComponent
	{
		private readonly Dictionary<int, TCachedComponent> _componentDictionary = new Dictionary<int, TCachedComponent>();

		private int getDictionaryKey(THostComponent host)
		{
			return ((Object)(object)host).GetInstanceID();
		}

		public bool TryGetComponent(THostComponent host, out TCachedComponent component)
		{
			if (!Object.op_Implicit((Object)(object)host))
			{
				component = default(TCachedComponent);
				return false;
			}
			return _componentDictionary.TryGetValue(getDictionaryKey(host), out component);
		}

		public TCachedComponent GetOrAddComponent(THostComponent host)
		{
			if (!Object.op_Implicit((Object)(object)host))
			{
				return default(TCachedComponent);
			}
			int dictionaryKey = getDictionaryKey(host);
			if (_componentDictionary.TryGetValue(dictionaryKey, out var value))
			{
				return value;
			}
			value = ((Component)host).GetComponent<TCachedComponent>();
			if (!Object.op_Implicit((Object)(object)value))
			{
				value = ((Component)host).gameObject.AddComponent<TCachedComponent>();
			}
			value.DictionaryKey = dictionaryKey;
			_componentDictionary.Add(dictionaryKey, value);
			return value;
		}

		public void OnDestroyed(TCachedComponent component)
		{
			if (component.DictionaryKey.HasValue)
			{
				_componentDictionary.Remove(component.DictionaryKey.Value);
			}
		}
	}
	public class TrackedValue<T>
	{
		public delegate void ValueChangedDelegate(T oldValue, T newValue);

		private T _value;

		public IEqualityComparer<T> EqualityComparer { get; set; }

		public T Value
		{
			get
			{
				return _value;
			}
			set
			{
				if (!EqualityComparer.Equals(_value, value))
				{
					T value2 = _value;
					_value = value;
					this.OnValueChanged?.Invoke(value2, _value);
				}
			}
		}

		public event ValueChangedDelegate OnValueChanged;

		public TrackedValue(T value)
			: this(value, (IEqualityComparer<T>)EqualityComparer<T>.Default)
		{
		}

		public TrackedValue(T value, IEqualityComparer<T> equalityComparer)
		{
			_value = value;
			EqualityComparer = equalityComparer ?? throw new ArgumentNullException("equalityComparer");
		}

		public bool Push(T value)
		{
			if (EqualityComparer.Equals(_value, value))
			{
				return false;
			}
			Value = value;
			return true;
		}
	}
	public sealed class UnityObjectComparer : IEqualityComparer<Object>
	{
		public static readonly UnityObjectComparer Instance = new UnityObjectComparer();

		private UnityObjectComparer()
		{
		}

		public bool Equals(Object x, Object y)
		{
			return x == y;
		}

		public int GetHashCode(Object obj)
		{
			return ((object)obj).GetHashCode();
		}
	}
}
namespace NoMoreMath.ShrineChance
{
	internal static class ShrineChanceActivationCountDisplay
	{
		private static bool _eventListenerActive;

		private static bool eventListenerActive
		{
			get
			{
				return _eventListenerActive;
			}
			set
			{
				if (_eventListenerActive != value)
				{
					_eventListenerActive = value;
					if (_eventListenerActive)
					{
						PurchaseInteractionHooks.ModifyName += PurchaseInteractionHooks_ModifyName;
					}
					else
					{
						PurchaseInteractionHooks.ModifyName -= PurchaseInteractionHooks_ModifyName;
					}
				}
			}
		}

		private static void refreshEventListenerActive()
		{
			eventListenerActive = Configs.ShrineChance.EnableActivationCountDisplay.Value;
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			Configs.ShrineChance.EnableActivationCountDisplay.SettingChanged += DisplayActivationCountEnabled_SettingChanged;
			refreshEventListenerActive();
		}

		private static void DisplayActivationCountEnabled_SettingChanged(object sender, EventArgs e)
		{
			refreshEventListenerActive();
		}

		private static void PurchaseInteractionHooks_ModifyName(PurchaseInteraction purchaseInteraction, CharacterMaster viewer, StringBuilder nameBuilder)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			ShrineChanceBehavior val = default(ShrineChanceBehavior);
			if (!Object.op_Implicit((Object)(object)purchaseInteraction) || !Object.op_Implicit((Object)(object)viewer) || purchaseInteraction.cost <= 0 || (int)purchaseInteraction.costType != 1 || !((Component)purchaseInteraction).TryGetComponent<ShrineChanceBehavior>(ref val))
			{
				return;
			}
			ShrineChanceConfig shrineChance = Configs.ShrineChance;
			CostTypeDef costTypeDef = CostTypeCatalog.GetCostTypeDef(purchaseInteraction.costType);
			int num = purchaseInteraction.cost;
			int num2 = TeamManager.LongstandingSolitudesInParty();
			if (num2 > 0)
			{
				num *= 1 + num2;
			}
			byte b = 0;
			uint num3 = viewer.money;
			if (num3 >= num)
			{
				for (b = 0; b <= 10; b++)
				{
					uint effectiveCost = (uint)EffectiveCostUtils.GetEffectiveCost(costTypeDef, num, viewer);
					if (num3 < effectiveCost)
					{
						break;
					}
					num3 -= effectiveCost;
					num = (int)((float)num * val.costMultiplierPerPurchase);
				}
			}
			string text = ((b <= 10) ? b.ToString() : "10+");
			nameBuilder.EnsureCapacity(nameBuilder.Length + shrineChance.ActivationCountDisplayFormatter.StrippedLength + text.Length + 1);
			nameBuilder.Append(' ');
			shrineChance.ActivationCountDisplayFormatter.AppendToStringBuilder(nameBuilder, new TagReplacementStringConfig.ReplacementInfo("{activations}", text));
		}
	}
	public class ShrineChanceConfig
	{
		public readonly ConfigEntry<bool> EnableActivationCountDisplay;

		public const string ACTIVATION_COUNT_DISPLAY_COUNT_TAG = "{activations}";

		public readonly TagReplacementStringConfig ActivationCountDisplayFormatter;

		public ShrineChanceConfig(in ConfigContext context)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			EnableActivationCountDisplay = context.Bind("Display Activation Count", defaultValue: true, new ConfigDescription("Displays how many activations of a shrine you can afford.", (AcceptableValueBase)null, Array.Empty<object>()));
			ConfigEntry<string> configEntry = context.Bind("Shrine Activation Count Display Format", "<size=80%><nobr>({activations} activation(s))</nobr></size>", new ConfigDescription("The format that will be used to display the affordable activations remaining.\r\n\r\nAll instances of '{activations}' (braces included!) will be replaced with the number of times you can purchase the shrine before running out of money.", (AcceptableValueBase)null, Array.Empty<object>()));
			ActivationCountDisplayFormatter = new TagReplacementStringConfig(configEntry, new string[1] { "{activations}" });
		}
	}
}
namespace NoMoreMath.ShrineBlood
{
	public class ShrineBloodConfig
	{
		public readonly ConfigEntry<bool> EnableGoldGainedDisplay;

		public const string GOLD_GAINED_DISPLAY_AMOUNT_TAG = "{amount}";

		public readonly TagReplacementStringConfig GoldGainedDisplayFormatter;

		public ShrineBloodConfig(in ConfigContext context)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			EnableGoldGainedDisplay = context.Bind("Display Gold Amount", defaultValue: true, new ConfigDescription("If the amount of money that will be granted from a Blood Shrine is displayed", (AcceptableValueBase)null, Array.Empty<object>()));
			ConfigEntry<string> configEntry = context.Bind("Gold Amount Display Format", "(+<style=cShrine>${amount}</style>)", new ConfigDescription("The format that will be used to display the amount of money gained.\r\n\r\nAll instances of '{amount}' (braces included!) will be replaced with the amount of money gained.", (AcceptableValueBase)null, Array.Empty<object>()));
			GoldGainedDisplayFormatter = new TagReplacementStringConfig(configEntry, new string[1] { "{amount}" });
		}
	}
	internal static class ShrineBloodGoldGainDisplay
	{
		private static bool _eventListenerActive;

		private static bool eventListenerActive
		{
			get
			{
				return _eventListenerActive;
			}
			set
			{
				if (_eventListenerActive != value)
				{
					_eventListenerActive = value;
					if (_eventListenerActive)
					{
						PurchaseInteractionHooks.ModifyName += PurchaseInteractionHooks_ModifyName;
					}
					else
					{
						PurchaseInteractionHooks.ModifyName -= PurchaseInteractionHooks_ModifyName;
					}
				}
			}
		}

		private static void refreshEventListenerActive()
		{
			eventListenerActive = Configs.ShrineBlood.EnableGoldGainedDisplay.Value;
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			Configs.ShrineBlood.EnableGoldGainedDisplay.SettingChanged += EnableGoldGainedDisplay_SettingChanged;
			refreshEventListenerActive();
		}

		private static void EnableGoldGainedDisplay_SettingChanged(object sender, EventArgs e)
		{
			refreshEventListenerActive();
		}

		private static void PurchaseInteractionHooks_ModifyName(PurchaseInteraction purchaseInteraction, CharacterMaster viewer, StringBuilder nameBuilder)
		{
			if (!Object.op_Implicit((Object)(object)purchaseInteraction) || !Object.op_Implicit((Object)(object)viewer))
			{
				return;
			}
			CharacterBody body = viewer.GetBody();
			if (Object.op_Implicit((Object)(object)body))
			{
				HealthComponent healthComponent = body.healthComponent;
				ShrineBloodBehavior val = default(ShrineBloodBehavior);
				if (Object.op_Implicit((Object)(object)healthComponent) && ((Component)purchaseInteraction).TryGetComponent<ShrineBloodBehavior>(ref val))
				{
					ShrineBloodConfig shrineBlood = Configs.ShrineBlood;
					string text = ((uint)(healthComponent.fullCombinedHealth * (float)purchaseInteraction.cost / 100f * val.goldToPaidHpRatio)).ToString();
					nameBuilder.EnsureCapacity(nameBuilder.Length + shrineBlood.GoldGainedDisplayFormatter.StrippedLength + text.Length + 1);
					nameBuilder.Append(' ');
					shrineBlood.GoldGainedDisplayFormatter.AppendToStringBuilder(nameBuilder, new TagReplacementStringConfig.ReplacementInfo("{amount}", text));
				}
			}
		}
	}
}
namespace NoMoreMath.ModCompatibility
{
	internal static class RiskOfOptionsCompat
	{
		private const string MOD_GUID = "Gorakh.NoMoreMath";

		private const string MOD_NAME = "NoMoreMath";

		private static Sprite _iconSprite;

		public static bool Enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");

		private static void findIconSprite()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			Sprite val = null;
			FileInfo fileInfo = null;
			DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(((BaseUnityPlugin)NoMoreMathPlugin.Instance).Info.Location));
			do
			{
				FileInfo[] files = directoryInfo.GetFiles("icon.png", SearchOption.TopDirectoryOnly);
				if (files != null && files.Length != 0)
				{
					fileInfo = files[0];
					break;
				}
				directoryInfo = directoryInfo.Parent;
			}
			while (directoryInfo != null && !string.Equals(directoryInfo.Name, "plugins", StringComparison.OrdinalIgnoreCase));
			if (fileInfo != null)
			{
				Texture2D val2 = new Texture2D(256, 256);
				((Object)val2).name = "texNoMoreMathIcon";
				if (ImageConversion.LoadImage(val2, File.ReadAllBytes(fileInfo.FullName)))
				{
					val = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f));
					((Object)val).name = "NoMoreMathIcon";
				}
			}
			_iconSprite = val;
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void Init()
		{
			if (!Object.op_Implicit((Object)(object)_iconSprite))
			{
				findIconSprite();
			}
			addEffectiveHealthOptions(Configs.EffectiveHealth);
			addEffectiveCostOptions(Configs.EffectiveCost);
			addHoldoutZoneOptions(Configs.HoldoutZone);
			addHalcyonShrineOptions(Configs.HalcyonShrine);
			addHalcyonBeaconOptions(Configs.HalcyonBeacon);
			addShrineChanceOptions(Configs.ShrineChance);
			addShrineBloodOptions(Configs.ShrineBlood);
			ModSettingsManager.SetModDescription("Options for NoMoreMath", "Gorakh.NoMoreMath", "NoMoreMath");
			if (Object.op_Implicit((Object)(object)_iconSprite))
			{
				ModSettingsManager.SetModIcon(_iconSprite, "Gorakh.NoMoreMath", "NoMoreMath");
			}
		}

		private static void addOption(BaseOption option)
		{
			ModSettingsManager.AddOption(option, "Gorakh.NoMoreMath", "NoMoreMath");
		}

		private static void addEffectiveHealthOptions(EffectiveHealthConfig effectiveHealthConfig)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			addOption((BaseOption)new CheckBoxOption(effectiveHealthConfig.Enabled));
			IsDisabledDelegate isDisabled = new IsDisabledDelegate(isDisabledImpl);
			addOption((BaseOption)new StringInputFieldOption(effectiveHealthConfig.EffectiveHealthDisplayFormat.ConfigEntry, new InputFieldConfig
			{
				lineType = (LineType)0,
				richText = false,
				submitOn = (SubmitEnum)4,
				checkIfDisabled = isDisabled
			}));
			addDisplayOptions(effectiveHealthConfig.CurrentHealthDisplay);
			addDisplayOptions(effectiveHealthConfig.MaxHealthDisplay);
			void addDisplayOptions(EffectiveHealthDisplayConfig displayConfig)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Expected O, but got Unknown
				addOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)displayConfig.HealthDisplayPosition, new ChoiceConfig
				{
					checkIfDisabled = isDisabled
				}));
			}
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			bool isDisabledImpl()
			{
				return !effectiveHealthConfig.Enabled.Value;
			}
		}

		private static void addEffectiveCostOptions(EffectiveCostConfig effectiveCostConfig)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			addOption((BaseOption)new CheckBoxOption(effectiveCostConfig.Enabled));
			IsDisabledDelegate checkIfDisabled = new IsDisabledDelegate(isDisabledImpl);
			addOption((BaseOption)new StringInputFieldOption(effectiveCostConfig.CostDisplayFormat.ConfigEntry, new InputFieldConfig
			{
				lineType = (LineType)0,
				richText = false,
				submitOn = (SubmitEnum)4,
				checkIfDisabled = checkIfDisabled
			}));
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			bool isDisabledImpl()
			{
				return !effectiveCostConfig.Enabled.Value;
			}
		}

		private static void addHoldoutZoneOptions(HoldoutZoneConfig holdoutZoneConfig)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			addOption((BaseOption)new CheckBoxOption(holdoutZoneConfig.EnableChargeTimeDisplay));
			IsDisabledDelegate checkIfDisabled = new IsDisabledDelegate(chargeTimeIsDisabledImpl);
			addOption((BaseOption)new StringInputFieldOption(holdoutZoneConfig.TimeRemainingDisplayFormat.ConfigEntry, new InputFieldConfig
			{
				lineType = (LineType)0,
				richText = false,
				submitOn = (SubmitEnum)4,
				checkIfDisabled = checkIfDisabled
			}));
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			bool chargeTimeIsDisabledImpl()
			{
				return !holdoutZoneConfig.EnableChargeTimeDisplay.Value;
			}
		}

		private static void addHalcyonShrineOptions(HalcyonShrineConfig halcyonShrineConfig)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			addOption((BaseOption)new CheckBoxOption(halcyonShrineConfig.EnableProgressObjective));
			IsDisabledDelegate checkIfDisabled = new IsDisabledDelegate(progressObjectiveIsDisabledImpl);
			addOption((BaseOption)new StringInputFieldOption(halcyonShrineConfig.ChargeProgressDisplayFormat.ConfigEntry, new InputFieldConfig
			{
				lineType = (LineType)0,
				richText = false,
				submitOn = (SubmitEnum)4,
				checkIfDisabled = checkIfDisabled
			}));
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			bool progressObjectiveIsDisabledImpl()
			{
				return !halcyonShrineConfig.EnableProgressObjective.Value;
			}
		}

		private static void addHalcyonBeaconOptions(HalcyonBeaconConfig halcyonBeaconConfig)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0051: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0074: 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)
			//IL_0085: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_0094: 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_00a5: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			addOption((BaseOption)new CheckBoxOption(halcyonBeaconConfig.EnableTotalCostDisplay));
			IsDisabledDelegate checkIfDisabled = new IsDisabledDelegate(totalCostDisplayIsDisabledImpl);
			addOption((BaseOption)new StringInputFieldOption(halcyonBeaconConfig.TotalCostDisplayFormatter.ConfigEntry, new InputFieldConfig
			{
				lineType = (LineType)0,
				richText = false,
				submitOn = (SubmitEnum)4,
				checkIfDisabled = checkIfDisabled
			}));
			addOption((BaseOption)new ColorOption(halcyonBeaconConfig.TotalCostAffordableColor, new ColorOptionConfig
			{
				checkIfDisabled = checkIfDisabled
			}));
			addOption((BaseOption)new ColorOption(halcyonBeaconConfig.TotalCostNotAffordableColor, new ColorOptionConfig
			{
				checkIfDisabled = checkIfDisabled
			}));
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			bool totalCostDisplayIsDisabledImpl()
			{
				return !halcyonBeaconConfig.EnableTotalCostDisplay.Value;
			}
		}

		private static void addShrineChanceOptions(ShrineChanceConfig shrineChanceConfig)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			addOption((BaseOption)new CheckBoxOption(shrineChanceConfig.EnableActivationCountDisplay));
			IsDisabledDelegate checkIfDisabled = new IsDisabledDelegate(activationCountDisplayIsDisabledImpl);
			addOption((BaseOption)new StringInputFieldOption(shrineChanceConfig.ActivationCountDisplayFormatter.ConfigEntry, new InputFieldConfig
			{
				lineType = (LineType)0,
				richText = false,
				submitOn = (SubmitEnum)4,
				checkIfDisabled = checkIfDisabled
			}));
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			bool activationCountDisplayIsDisabledImpl()
			{
				return !shrineChanceConfig.EnableActivationCountDisplay.Value;
			}
		}

		private static void addShrineBloodOptions(ShrineBloodConfig shrineBloodConfig)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			addOption((BaseOption)new CheckBoxOption(shrineBloodConfig.EnableGoldGainedDisplay));
			IsDisabledDelegate checkIfDisabled = new IsDisabledDelegate(goldGainedDisplayIsDisabledImpl);
			addOption((BaseOption)new StringInputFieldOption(shrineBloodConfig.GoldGainedDisplayFormatter.ConfigEntry, new InputFieldConfig
			{
				lineType = (LineType)0,
				richText = false,
				submitOn = (SubmitEnum)4,
				checkIfDisabled = checkIfDisabled
			}));
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			bool goldGainedDisplayIsDisabledImpl()
			{
				return !shrineBloodConfig.EnableGoldGainedDisplay.Value;
			}
		}
	}
}
namespace NoMoreMath.MiscPatches
{
	internal static class PurchaseInteractionHooks
	{
		public delegate void ModifyNameDelegate(PurchaseInteraction purchaseInteraction, CharacterMaster viewer, StringBuilder nameBuilder);

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_GetDisplayName <0>__PurchaseInteraction_GetDisplayName;

			public static hook_GetContextString <1>__PurchaseInteraction_GetContextString;
		}

		private static readonly StringBuilder _sharedStringBuilder = new StringBuilder();

		public static event ModifyNameDelegate ModifyName;

		[SystemInitializer(new Type[] { })]
		private 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>__PurchaseInteraction_GetDisplayName;
			if (obj == null)
			{
				hook_GetDisplayName val = PurchaseInteraction_GetDisplayName;
				<>O.<0>__PurchaseInteraction_GetDisplayName = val;
				obj = (object)val;
			}
			PurchaseInteraction.GetDisplayName += (hook_GetDisplayName)obj;
			object obj2 = <>O.<1>__PurchaseInteraction_GetContextString;
			if (obj2 == null)
			{
				hook_GetContextString val2 = PurchaseInteraction_GetContextString;
				<>O.<1>__PurchaseInteraction_GetContextString = val2;
				obj2 = (object)val2;
			}
			PurchaseInteraction.GetContextString += (hook_GetContextString)obj2;
		}

		private static string tryModifyName(string name, PurchaseInteraction instance, CharacterMaster viewer)
		{
			if (PurchaseInteractionHooks.ModifyName == null)
			{
				return name;
			}
			try
			{
				_sharedStringBuilder.Clear();
				_sharedStringBuilder.Append(name);
				PurchaseInteractionHooks.ModifyName(instance, viewer, _sharedStringBuilder);
				return _sharedStringBuilder.ToString();
			}
			catch (Exception data)
			{
				Log.Error_NoCallerPrefix(data);
				return name;
			}
		}

		private static string PurchaseInteraction_GetDisplayName(orig_GetDisplayName orig, PurchaseInteraction self)
		{
			CharacterMaster viewer = null;
			LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
			if (firstLocalUser != null)
			{
				viewer = firstLocalUser.cachedMaster;
			}
			return tryModifyName(orig.Invoke(self), self, viewer);
		}

		private static string PurchaseInteraction_GetContextString(orig_GetContextString orig, PurchaseInteraction self, Interactor activator)
		{
			CharacterMaster viewer = null;
			CharacterBody val = default(CharacterBody);
			if (Object.op_Implicit((Object)(object)activator) && ((Component)activator).TryGetComponent<CharacterBody>(ref val))
			{
				viewer = val.master;
			}
			return tryModifyName(orig.Invoke(self, activator), self, viewer);
		}
	}
}
namespace NoMoreMath.HoldoutZone
{
	public class HoldoutZoneChargeRateProvider : NetworkBehaviour, ICachableComponent
	{
		public static readonly ObjectComponentCache<HoldoutZoneController, HoldoutZoneChargeRateProvider> ComponentCache = new ObjectComponentCache<HoldoutZoneController, HoldoutZoneChargeRateProvider>();

		private HoldoutZoneController _holdoutZoneController;

		[SyncVar(hook = "syncChargeRate")]
		public float ChargeRate;

		int? ICachableComponent.DictionaryKey { get; set; }

		public float LastPositiveChargeRate { get; private set; }

		public float NetworkChargeRate
		{
			get
			{
				return ChargeRate;
			}
			[param: In]
			set
			{
				ref float chargeRate = ref ChargeRate;
				if (NetworkServer.localClientActive && !((NetworkBehaviour)this).syncVarHookGuard)
				{
					((NetworkBehaviour)this).syncVarHookGuard = true;
					syncChargeRate(value);
					((NetworkBehaviour)this).syncVarHookGuard = false;
				}
				((NetworkBehaviour)this).SetSyncVar<float>(value, ref chargeRate, 1u);
			}
		}

		private void Awake()
		{
			_holdoutZoneController = ((Component)this).GetComponent<HoldoutZoneController>();
		}

		public override void OnStartClient()
		{
			((NetworkBehaviour)this).OnStartClient();
			syncChargeRate(ChargeRate);
		}

		private void OnDestroy()
		{
			ComponentCache.OnDestroyed(this);
		}

		private void syncChargeRate(float chargeRate)
		{
			NetworkChargeRate = chargeRate;
			if (chargeRate > 0f)
			{
				LastPositiveChargeRate = chargeRate;
			}
		}

		private void UNetVersion()
		{
		}

		public override bool OnSerialize(NetworkWriter writer, bool forceAll)
		{
			if (forceAll)
			{
				writer.Write(ChargeRate);
				return true;
			}
			bool flag = false;
			if ((((NetworkBehaviour)this).syncVarDirtyBits & (true ? 1u : 0u)) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(ChargeRate);
			}
			if (!flag)
			{
				writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
			}
			return flag;
		}

		public override void OnDeserialize(NetworkReader reader, bool initialState)
		{
			if (initialState)
			{
				ChargeRate = reader.ReadSingle();
				return;
			}
			int num = (int)reader.ReadPackedUInt32();
			if (((uint)num & (true ? 1u : 0u)) != 0)
			{
				syncChargeRate(reader.ReadSingle());
			}
		}
	}
	internal static class HoldoutZoneChargeRateProviderHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__HoldoutZoneController_Awake;

			public static Manipulator <1>__HoldoutZoneController_DoUpdate;

			public static Action<HoldoutZoneController, float> <2>__recordChargeRate;
		}

		[SystemInitializer(new Type[] { })]
		private 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>__HoldoutZoneController_Awake;
			if (obj == null)
			{
				hook_Awake val = HoldoutZoneController_Awake;
				<>O.<0>__HoldoutZoneController_Awake = val;
				obj = (object)val;
			}
			HoldoutZoneController.Awake += (hook_Awake)obj;
			object obj2 = <>O.<1>__HoldoutZoneController_DoUpdate;
			if (obj2 == null)
			{
				Manipulator val2 = HoldoutZoneController_DoUpdate;
				<>O.<1>__HoldoutZoneController_DoUpdate = val2;
				obj2 = (object)val2;
			}
			HoldoutZoneController.DoUpdate += (Manipulator)obj2;
		}

		private static void HoldoutZoneController_Awake(orig_Awake orig, HoldoutZoneController self)
		{
			orig.Invoke(self);
			HoldoutZoneChargeRateProvider.ComponentCache.GetOrAddComponent(self);
		}

		private static void HoldoutZoneController_DoUpdate(ILContext il)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			ILCursor[] array = null;
			if (!val.TryFindNext(ref array, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<HoldoutZoneController>(x, "calcChargeRate"),
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<CalcChargeRateDelegate>(x, "Invoke")
			}))
			{
				Log.Error("Failed to find calcChargeRate invoke", "X:\\Git\\RoR2\\NoMoreMath\\NoMoreMath\\HoldoutZone\\HoldoutZoneChargeRateProviderHooks.cs", "HoldoutZoneController_DoUpdate", 33);
				return;
			}
			val.Goto(array[1].Next, (MoveType)0, false);
			int chargeRateLocalIndex = -1;
			if (!val.Clone().TryGotoPrev(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloca(x, ref chargeRateLocalIndex)
			}))
			{
				Log.Error("Failed to find chargeRate local", "X:\\Git\\RoR2\\NoMoreMath\\NoMoreMath\\HoldoutZone\\HoldoutZoneChargeRateProviderHooks.cs", "HoldoutZoneController_DoUpdate", 42);
				return;
			}
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<HoldoutZoneController>(x, "set_charge")
			}))
			{
				int index = val.Index;
				val.Index = index + 1;
				Log.Warning("Failed to find set_charge call, using current position", "X:\\Git\\RoR2\\NoMoreMath\\NoMoreMath\\HoldoutZone\\HoldoutZoneChargeRateProviderHooks.cs", "HoldoutZoneController_DoUpdate", 50);
			}
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldloc, chargeRateLocalIndex);
			val.EmitDelegate<Action<HoldoutZoneController, float>>((Action<HoldoutZoneController, float>)recordChargeRate);
			static void recordChargeRate(HoldoutZoneController holdoutZoneController, float chargeRate)
			{
				if (NetworkServer.active)
				{
					HoldoutZoneChargeRateProvider.ComponentCache.GetOrAddComponent(holdoutZoneController).NetworkChargeRate = chargeRate;
				}
			}
		}
	}
	internal static class HoldoutZoneChargeTimeDisplayHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_GenerateString <0>__ChargeHoldoutZoneObjectiveTracker_GenerateString;
		}

		[SystemInitializer(new Type[] { })]
		private 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>__ChargeHoldoutZoneObjectiveTracker_GenerateString;
			if (obj == null)
			{
				hook_GenerateString val = ChargeHoldoutZoneObjectiveTracker_GenerateString;
				<>O.<0>__ChargeHoldoutZoneObjectiveTracker_GenerateString = val;
				obj = (object)val;
			}
			ChargeHoldoutZoneObjectiveTracker.GenerateString += (hook_GenerateString)obj;
		}

		private static string ChargeHoldoutZoneObjectiveTracker_GenerateString(orig_GenerateString orig, ObjectiveTracker _self)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ChargeHoldoutZoneObjectiveTracker val = (ChargeHoldoutZoneObjectiveTracker)_self;
			string text = orig.Invoke((ObjectiveTracker)(object)val);
			HoldoutZoneConfig holdoutZone = Configs.HoldoutZone;
			if (holdoutZone.EnableChargeTimeDisplay.Value)
			{
				HoldoutZoneController holdoutZoneController = val.holdoutZoneController;
				float num = 0f;
				if (HoldoutZoneChargeRateProvider.ComponentCache.TryGetComponent(holdoutZoneController, out var component))
				{
					num = component.LastPositiveChargeRate;
				}
				StringBuilder stringBuilder = StringBuilderPool.RentStringBuilder();
				string text2 = "N/A";
				if (num > 0f)
				{
					text2 = ((1f - holdoutZoneController.charge) / num).ToString("F1", CultureInfo.InvariantCulture);
				}
				stringBuilder.EnsureCapacity(text.Length + holdoutZone.TimeRemainingDisplayFormat.StrippedLength + text2.Length + 1);
				stringBuilder.Append(text);
				stringBuilder.Append(' ');
				holdoutZone.TimeRemainingDisplayFormat.AppendToStringBuilder(stringBuilder, new TagReplacementStringConfig.ReplacementInfo("{sec}", text2));
				text = stringBuilder.ToString();
				stringBuilder = StringBuilderPool.ReturnStringBuilder(stringBuilder);
			}
			return text;
		}
	}
	public class HoldoutZoneConfig
	{
		public readonly ConfigEntry<bool> EnableChargeTimeDisplay;

		public const string TIME_REMAINING_DISPLAY_SECONDS_TAG = "{sec}";

		public readonly TagReplacementStringConfig TimeRemainingDisplayFormat;

		public HoldoutZoneConfig(in ConfigContext context)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			EnableChargeTimeDisplay = context.Bind("Display Estimated Charge Time", defaultValue: true, new ConfigDescription("If the estimated time remaining to fully charge a holdout zone should be displayed in the Objective panel", (AcceptableValueBase)null, Array.Empty<object>()));
			ConfigEntry<string> configEntry = context.Bind("Charge Time Display Format", "<nobr>({sec} s)</nobr>", new ConfigDescription("The format that will be used to display the time remaining.\r\n\r\nAll instances of '{sec}' (braces included!) will be replaced with the time remaining (in seconds)", (AcceptableValueBase)null, Array.Empty<object>()));
			TimeRemainingDisplayFormat = new TagReplacementStringConfig(configEntry, new string[1] { "{sec}" });
		}
	}
}
namespace NoMoreMath.HalcyonShrine
{
	public class HalcyonShrineConfig
	{
		public readonly ConfigEntry<bool> EnableProgressObjective;

		public const string CHARGE_PROGRESS_DISPLAY_PROGRESS_TAG = "{percent_complete}";

		public const string CHARGE_PROGRESS_DISPLAY_GOLD_DRAINED_TAG = "{money_spent}";

		public const string CHARGE_PROGRESS_DISPLAY_GOLD_REQUIRED_TAG = "{money_required}";

		public readonly TagReplacementStringConfig ChargeProgressDisplayFormat;

		public HalcyonShrineConfig(in ConfigContext context)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			EnableProgressObjective = context.Bind("Display Charge Progress", defaultValue: true, new ConfigDescription("If the charge progress of Halcyon Shrines should be displayed in the Objectives panel", (AcceptableValueBase)null, Array.Empty<object>()));
			ConfigEntry<string> configEntry = context.Bind("Charge Progress Display Format", "Charge the <style=cHumanObjective>Halcyon Shrine</style> (<style=cShrine>${money_spent}/{money_required}</style>)", new ConfigDescription("The format that will be used to display the charge progress.\r\n\r\nAll instances of '{money_spent}' (braces included!) will be replaced with the amount of money spent on the shrine\r\n\r\nAll instances of '{money_required}' (braces included!) will be replaced with the amount of money required to complete the shrine\r\n\r\nAll instances of '{percent_complete}' (braces included!) will be replaced with the charge percentage (0-100)", (AcceptableValueBase)null, Array.Empty<object>()));
			ChargeProgressDisplayFormat = new TagReplacementStringConfig(configEntry, new string[3] { "{percent_complete}", "{money_spent}", "{money_required}" });
		}
	}
	[DisallowMultipleComponent]
	public class HalcyonShrineObjectiveProvider : NetworkBehaviour
	{
		private HalcyoniteShrineInteractable _shrine;

		[SyncVar]
		public bool IsActive;

		[SyncVar]
		public int TotalGoldDrained = -1;

		[SyncVar]
		public int RequiredGoldDrain = -1;

		public bool NetworkIsActive
		{
			get
			{
				return IsActive;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<bool>(value, ref IsActive, 1u);
			}
		}

		public int NetworkTotalGoldDrained
		{
			get
			{
				return TotalGoldDrained;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref TotalGoldDrained, 2u);
			}
		}

		public int NetworkRequiredGoldDrain
		{
			get
			{
				return RequiredGoldDrain;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref RequiredGoldDrain, 4u);
			}
		}

		private void Awake()
		{
			_shrine = ((Component)this).GetComponent<HalcyoniteShrineInteractable>();
			if (NetworkServer.active)
			{
				updateServerVars();
			}
		}

		private void OnEnable()
		{
			ObjectivePanelController.collectObjectiveSources += ObjectivePanelController_collectObjectiveSources;
		}

		private void OnDisable()
		{
			ObjectivePanelController.collectObjectiveSources -= ObjectivePanelController_collectObjectiveSources;
		}

		private void Update()
		{
			if (NetworkServer.active)
			{
				updateServerVars();
			}
		}

		[Server]
		private void updateServerVars()
		{
			if (!NetworkServer.active)
			{
				Debug.LogWarning((object)"[Server] function 'System.Void NoMoreMath.HalcyonShrine.HalcyonShrineObjectiveProvider::updateServerVars()' called on client");
				return;
			}
			bool networkIsActive = false;
			int networkTotalGoldDrained = -1;
			int networkRequiredGoldDrain = -1;
			if (Object.op_Implicit((Object)(object)_shrine))
			{
				int num;
				if (_shrine.interactions > 0 && Object.op_Implicit((Object)(object)_shrine.stateMachine))
				{
					EntityState state = _shrine.stateMachine.state;
					num = ((!(state is ShrineHalcyoniteMaxQuality) && !(state is ShrineHalcyoniteFinished)) ? 1 : 0);
				}
				else
				{
					num = 0;
				}
				networkIsActive = (byte)num != 0;
				networkTotalGoldDrained = _shrine.goldDrained;
				networkRequiredGoldDrain = _shrine.maxGoldCost;
			}
			NetworkIsActive = networkIsActive;
			NetworkTotalGoldDrained = networkTotalGoldDrained;
			NetworkRequiredGoldDrain = networkRequiredGoldDrain;
		}

		private void ObjectivePanelController_collectObjectiveSources(CharacterMaster viewer, List<ObjectiveSourceDescriptor> objectiveSources)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (IsActive && Configs.HalcyonShrine.EnableProgressObjective.Value)
			{
				objectiveSources.Add(new ObjectiveSourceDescriptor
				{
					master = viewer,
					objectiveType = typeof(HalcyonShrineObjectiveTracker),
					source = (Object)(object)this
				});
			}
		}

		private void UNetVersion()
		{
		}

		public override bool OnSerialize(NetworkWriter writer, bool forceAll)
		{
			if (forceAll)
			{
				writer.Write(IsActive);
				writer.WritePackedUInt32((uint)TotalGoldDrained);
				writer.WritePackedUInt32((uint)RequiredGoldDrain);
				return true;
			}
			bool flag = false;
			if ((((NetworkBehaviour)this).syncVarDirtyBits & (true ? 1u : 0u)) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(IsActive);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 2u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)TotalGoldDrained);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 4u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)RequiredGoldDrain);
			}
			if (!flag)
			{
				writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
			}
			return flag;
		}

		public override void OnDeserialize(NetworkReader reader, bool initialState)
		{
			if (initialState)
			{
				IsActive = reader.ReadBoolean();
				TotalGoldDrained = (int)reader.ReadPackedUInt32();
				RequiredGoldDrain = (int)reader.ReadPackedUInt32();
				return;
			}
			int num = (int)reader.ReadPackedUInt32();
			if (((uint)num & (true ? 1u : 0u)) != 0)
			{
				IsActive = reader.ReadBoolean();
			}
			if (((uint)num & 2u) != 0)
			{
				TotalGoldDrained = (int)reader.ReadPackedUInt32();
			}
			if (((uint)num & 4u) != 0)
			{
				RequiredGoldDrain = (int)reader.ReadPackedUInt32();
			}
		}
	}
	internal static class HalcyonShrineObjectiveProviderHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__HalcyoniteShrineInteractable_Awake;
		}

		[SystemInitializer(new Type[] { })]
		private 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>__HalcyoniteShrineInteractable_Awake;
			if (obj == null)
			{
				hook_Awake val = HalcyoniteShrineInteractable_Awake;
				<>O.<0>__HalcyoniteShrineInteractable_Awake = val;
				obj = (object)val;
			}
			HalcyoniteShrineInteractable.Awake += (hook_Awake)obj;
		}

		private static void HalcyoniteShrineInteractable_Awake(orig_Awake orig, HalcyoniteShrineInteractable self)
		{
			orig.Invoke(self);
			((Component)self).gameObject.AddComponent<HalcyonShrineObjectiveProvider>();
		}
	}
	public class HalcyonShrineObjectiveTracker : ObjectiveTracker
	{
		private bool _displayFormatDirty;

		private int _displayedChargePercent = -1;

		private int _displayedGoldDrain = -1;

		private int _displayedRequiredGoldDrain = -1;

		private HalcyonShrineObjectiveProvider halcyoniteShrine => (HalcyonShrineObjectiveProvider)(object)base.sourceDescriptor.source;

		public HalcyonShrineObjectiveTracker()
		{
			Configs.HalcyonShrine.ChargeProgressDisplayFormat.OnValueChanged += onDisplayFormatChanged;
		}

		public override void OnRetired()
		{
			((ObjectiveTracker)this).OnRetired();
			Configs.HalcyonShrine.ChargeProgressDisplayFormat.OnValueChanged -= onDisplayFormatChanged;
		}

		private void onDisplayFormatChanged()
		{
			_displayFormatDirty = true;
		}

		private int getChargeDisplayPercent()
		{
			return Mathf.Clamp(Mathf.FloorToInt((float)halcyoniteShrine.TotalGoldDrained / (float)halcyoniteShrine.RequiredGoldDrain * 100f), 0, 100);
		}

		public override bool IsDirty()
		{
			if (!((ObjectiveTracker)this).IsDirty())
			{
				if (Object.op_Implicit((Object)(object)halcyoniteShrine))
				{
					if (!_displayFormatDirty && halcyoniteShrine.TotalGoldDrained == _displayedGoldDrain && halcyoniteShrine.RequiredGoldDrain == _displayedRequiredGoldDrain)
					{
						return _displayedChargePercent != getChargeDisplayPercent();
					}
					return true;
				}
				return false;
			}
			return true;
		}

		public override string GenerateString()
		{
			_displayedChargePercent = getChargeDisplayPercent();
			_displayedGoldDrain = halcyoniteShrine.TotalGoldDrained;
			_displayedRequiredGoldDrain = halcyoniteShrine.RequiredGoldDrain;
			_displayFormatDirty = false;
			string text = _displayedChargePercent.ToString();
			string text2 = _displayedGoldDrain.ToString();
			string text3 = _displayedRequiredGoldDrain.ToString();
			HalcyonShrineConfig halcyonShrine = Configs.HalcyonShrine;
			StringBuilder stringBuilder = StringBuilderPool.RentStringBuilder();
			stringBuilder.EnsureCapacity(halcyonShrine.ChargeProgressDisplayFormat.StrippedLength + text.Length + text2.Length + text3.Length);
			halcyonShrine.ChargeProgressDisplayFormat.AppendToStringBuilder(stringBuilder, new TagReplacementStringConfig.ReplacementInfo("{percent_complete}", text), new TagReplacementStringConfig.ReplacementInfo("{money_spent}", text2), new TagReplacementStringConfig.ReplacementInfo("{money_required}", text3));
			string result = stringBuilder.ToString();
			StringBuilderPool.ReturnStringBuilder(stringBuilder);
			return result;
		}
	}
}
namespace NoMoreMath.HalcyonBeacon
{
	internal struct GoldshoresBeaconCollection : IEquatable<GoldshoresBeaconCollection>
	{
		public GameObject[] BeaconObjects;

		public GoldshoresBeaconCollection(GameObject[] beaconObjects)
		{
			BeaconObjects = beaconObjects;
		}

		public readonly bool Equals(GoldshoresBeaconCollection other)
		{
			return ArrayUtils.SequenceEquals<GameObject, UnityObjectComparer>(BeaconObjects, other.BeaconObjects, UnityObjectComparer.Instance);
		}
	}
	[DisallowMultipleComponent]
	public class GoldshoresMissionControllerBeaconsProvider : NetworkBehaviour
	{
		private GoldshoresMissionController _missionController;

		[SyncVar(hook = "syncBeacons")]
		private GoldshoresBeaconCollection _beaconCollection;

		private readonly List<GameObject> _beaconsList = new List<GameObject>();

		private readonly List<PurchaseInteraction> _beaconPurchaseInteractions = new List<PurchaseInteraction>();

		public static GoldshoresMissionControllerBeaconsProvider Instance { get; private set; }

		public ReadOnlyCollection<GameObject> BeaconObjects { get; private set; }

		public ReadOnlyCollection<PurchaseInteraction> BeaconPurchaseInteractions { get; private set; }

		public GoldshoresBeaconCollection Network_beaconCollection
		{
			get
			{
				return _beaconCollection;
			}
			[param: In]
			set
			{
				ref GoldshoresBeaconCollection beaconCollection = ref _beaconCollection;
				if (NetworkServer.localClientActive && !((NetworkBehaviour)this).syncVarHookGuard)
				{
					((NetworkBehaviour)this).syncVarHookGuard = true;
					syncBeacons(value);
					((NetworkBehaviour)this).syncVarHookGuard = false;
				}
				((NetworkBehaviour)this).SetSyncVar<GoldshoresBeaconCollection>(value, ref beaconCollection, 1u);
			}
		}

		private void Awake()
		{
			_missionController = ((Component)this).GetComponent<GoldshoresMissionController>();
			BeaconObjects = new ReadOnlyCollection<GameObject>(_beaconsList);
			BeaconPurchaseInteractions = new ReadOnlyCollection<PurchaseInteraction>(_beaconPurchaseInteractions);
		}

		private void OnEnable()
		{
			Instance = SingletonHelper.Assign<GoldshoresMissionControllerBeaconsProvider>(Instance, this);
			if (NetworkServer.active)
			{
				updateServerVars();
			}
		}

		private void OnDisable()
		{
			Instance = SingletonHelper.Unassign<GoldshoresMissionControllerBeaconsProvider>(Instance, this);
		}

		public override void OnStartClient()
		{
			((NetworkBehaviour)this).OnStartClient();
			syncBeacons(_beaconCollection);
		}

		private void FixedUpdate()
		{
			if (NetworkServer.active)
			{
				updateServerVars();
			}
		}

		[Server]
		private void updateServerVars()
		{
			if (!NetworkServer.active)
			{
				Debug.LogWarning((object)"[Server] function 'System.Void NoMoreMath.HalcyonBeacon.GoldshoresMissionControllerBeaconsProvider::updateServerVars()' called on client");
				return;
			}
			GameObject[] beaconObjects = (Object.op_Implicit((Object)(object)_missionController) ? _missionController.beaconInstanceList.ToArray() : Array.Empty<GameObject>());
			Network_beaconCollection = new GoldshoresBeaconCollection(beaconObjects);
		}

		private void syncBeacons(GoldshoresBeaconCollection beaconCollection)
		{
			Network_beaconCollection = beaconCollection;
			_beaconsList.Clear();
			_beaconsList.AddRange(beaconCollection.BeaconObjects);
			_beaconPurchaseInteractions.Clear();
			PurchaseInteraction item = default(PurchaseInteraction);
			foreach (GameObject beaconObject in BeaconObjects)
			{
				if (Object.op_Implicit((Object)(object)beaconObject) && beaconObject.TryGetComponent<PurchaseInteraction>(ref item))
				{
					_beaconPurchaseInteractions.Add(item);
				}
			}
		}

		public static void TryAddComponent(GoldshoresMissionController missionController)
		{
			if (!Object.op_Implicit((Object)(object)missionController))
			{
				Log.Error("Null mission controller instance", "X:\\Git\\RoR2\\NoMoreMath\\NoMoreMath\\HalcyonBeacon\\GoldshoresMissionControllerBeaconsProvider.cs", "TryAddComponent", 92);
			}
			else if (!Object.op_Implicit((Object)(object)((Component)missionController).GetComponent<NetworkIdentity>()))
			{
				Log.Error("Mission controller is missing network identity", "X:\\Git\\RoR2\\NoMoreMath\\NoMoreMath\\HalcyonBeacon\\GoldshoresMissionControllerBeaconsProvider.cs", "TryAddComponent", 98);
			}
			else
			{
				((Component)missionController).gameObject.AddComponent<GoldshoresMissionControllerBeaconsProvider>();
			}
		}

		private void UNetVersion()
		{
		}

		public override bool OnSerialize(NetworkWriter writer, bool forceAll)
		{
			if (forceAll)
			{
				GeneratedNetworkCode._WriteGoldshoresBeaconCollection_None(writer, _beaconCollection);
				return true;
			}
			bool flag = false;
			if ((((NetworkBehaviour)this).syncVarDirtyBits & (true ? 1u : 0u)) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				GeneratedNetworkCode._WriteGoldshoresBeaconCollection_None(writer, _beaconCollection);
			}
			if (!flag)
			{
				writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
			}
			return flag;
		}

		public override void OnDeserialize(NetworkReader reader, bool initialState)
		{
			if (initialState)
			{
				_beaconCollection = GeneratedNetworkCode._ReadGoldshoresBeaconCollection_None(reader);
				return;
			}
			int num = (int)reader.ReadPackedUInt32();
			if (((uint)num & (true ? 1u : 0u)) != 0)
			{
				syncBeacons(GeneratedNetworkCode._ReadGoldshoresBeaconCollection_None(reader));
			}
		}
	}
	internal static class GoldshoresMissionControllerBeaconsProviderHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__GoldshoresMissionController_Awake;
		}

		[SystemInitializer(new Type[] { })]
		private 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>__GoldshoresMissionController_Awake;
			if (obj == null)
			{
				hook_Awake val = GoldshoresMissionController_Awake;
				<>O.<0>__GoldshoresMissionController_Awake = val;
				obj = (object)val;
			}
			GoldshoresMissionController.Awake += (hook_Awake)obj;
		}

		private static void GoldshoresMissionController_Awake(orig_Awake orig, GoldshoresMissionController self)
		{
			orig.Invoke(self);
			GoldshoresMissionControllerBeaconsProvider.TryAddComponent(self);
		}
	}
	public class HalcyonBeaconConfig
	{
		public readonly ConfigEntry<bool> EnableTotalCostDisplay;

		public const string TOTAL_COST_DISPLAY_COST_TAG = "{total_cost}";

		public const string TOTAL_COST_DISPLAY_COLOR_TAG = "{color}";

		public readonly TagReplacementStringConfig TotalCostDisplayFormatter;

		public readonly ConfigEntry<Color> TotalCostAffordableColor;

		public readonly ConfigEntry<Color> TotalCostNotAffordableColor;

		public HalcyonBeaconConfig(in ConfigContext context)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			EnableTotalCostDisplay = context.Bind("Display Total Cost", defaultValue: true, new ConfigDescription("If the total cost of all Halcyon Beacons in Gilded Coast should be displayed in the Objective panel", (AcceptableValueBase)null, Array.Empty<object>()));
			ConfigEntry<string> configEntry = context.Bind("Total Cost Display Format", "<nobr>(<color={color}>${total_cost}</color>)</nobr>", new ConfigDescription("The format that will be used to display the total cost.\r\n\r\nAll instances of '{total_cost}' (braces included!) will be replaced with the total cost\r\n\r\nAll instances of '{color}' (braces included!) will be replaced with a color code depending on if the total cost is affordable or not", (AcceptableValueBase)null, Array.Empty<object>()));
			TotalCostDisplayFormatter = new TagReplacementStringConfig(configEntry, new string[2] { "{total_cost}", "{color}" });
			TotalCostAffordableColor = context.Bind<Color>("Total Cost Affordable Color", new Color(0f, 1f, 0f), new ConfigDescription("The color used for the '{color}' tag in the display format if the total price can be afforded.", (AcceptableValueBase)null, Array.Empty<object>()));
			TotalCostNotAffordableColor = context.Bind<Color>("Total Cost Not Affordable Color", new Color(1f, 0f, 0f), new ConfigDescription("The color used for the '{color}' tag in the display format if the total price cannot be afforded.", (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	internal static class HalcyonBeaconTotalCostDisplayHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_IsDirty <0>__ActivateGoldshoreBeaconTracker_IsDirty;

			public static hook_GenerateString <1>__ActivateGoldshoreBeaconTracker_GenerateString;
		}

		[SystemInitializer(new Type[] { })]
		private 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>__ActivateGoldshoreBeaconTracker_IsDirty;
			if (obj == null)
			{
				hook_IsDirty val = ActivateGoldshoreBeaconTracker_IsDirty;
				<>O.<0>__ActivateGoldshoreBeaconTracker_IsDirty = val;
				obj = (object)val;
			}
			ActivateGoldshoreBeaconTracker.IsDirty += (hook_IsDirty)obj;
			object obj2 = <>O.<1>__ActivateGoldshoreBeaconTracker_GenerateString;
			if (obj2 == null)
			{
				hook_GenerateString val2 = ActivateGoldshoreBeaconTracker_GenerateString;
				<>O.<1>__ActivateGoldshoreBeaconTracker_GenerateString = val2;
				obj2 = (object)val2;
			}
			ActivateGoldshoreBeaconTracker.GenerateString += (hook_GenerateString)obj2;
		}

		private static bool ActivateGoldshoreBeaconTracker_IsDirty(orig_IsDirty orig, ObjectiveTracker self)
		{
			orig.Invoke(self);
			return true;
		}

		private static string ActivateGoldshoreBeaconTracker_GenerateString(orig_GenerateString orig, ObjectiveTracker self)
		{
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Invalid comparison between Unknown and I4
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			string text = orig.Invoke(self);
			HalcyonBeaconConfig halcyonBeacon = Configs.HalcyonBeacon;
			CharacterMaster master = self.sourceDescriptor.master;
			if (halcyonBeacon.EnableTotalCostDisplay.Value && Object.op_Implicit((Object)(object)GoldshoresMissionControllerBeaconsProvider.Instance) && Object.op_Implicit((Object)(object)master))
			{
				ReadOnlyCollection<PurchaseInteraction> beaconPurchaseInteractions = GoldshoresMissionControllerBeaconsProvider.Instance.BeaconPurchaseInteractions;
				CostTypeDef costTypeDef = CostTypeCatalog.GetCostTypeDef((CostTypeIndex)1);
				int count = beaconPurchaseInteractions.Count;
				int[] array = new int[count];
				int num = TeamManager.LongstandingSolitudesInParty();
				for (int i = 0; i < count; i++)
				{
					PurchaseInteraction val = beaconPurchaseInteractions[i];
					if (Object.op_Implicit((Object)(object)val) && val.available && (int)val.costType == 1)
					{
						int num2 = val.cost;
						if (num > 0)
						{
							num2 *= 1 + num;
						}
						if (num2 > 0)
						{
							array[i] = num2;
						}
					}
				}
				int totalEffectiveCost = EffectiveCostUtils.GetTotalEffectiveCost(costTypeDef, array, master);
				string text2 = totalEffectiveCost.ToString();
				Color32 val2 = Color32.op_Implicit((master.money >= totalEffectiveCost) ? halcyonBeacon.TotalCostAffordableColor.Value : halcyonBeacon.TotalCostNotAffordableColor.Value);
				string text3 = $"#{val2.r:X2}{val2.g:X2}{val2.b:X2}";
				StringBuilder stringBuilder = StringBuilderPool.RentStringBuilder();
				stringBuilder.EnsureCapacity(text.Length + halcyonBeacon.TotalCostDisplayFormatter.StrippedLength + text3.Length + text2.Length + 1);
				stringBuilder.Append(text).Append(' ');
				halcyonBeacon.TotalCostDisplayFormatter.AppendToStringBuilder(stringBuilder, new TagReplacementStringConfig.ReplacementInfo("{color}", text3), new TagReplacementStringConfig.ReplacementInfo("{total_cost}", text2));
				text = stringBuilder.ToString();
				stringBuilder = StringBuilderPool.ReturnStringBuilder(stringBuilder);
			}
			return text;
		}
	}
}
namespace NoMoreMath.EffectiveHealth
{
	public class EffectiveHealthConfig
	{
		public readonly ConfigEntry<bool> Enabled;

		public const string EFFECTIVE_HEALTH_FORMAT_VALUE_TAG = "{value}";

		public readonly TagReplacementStringConfig EffectiveHealthDisplayFormat;

		public readonly EffectiveHealthDisplayConfig CurrentHealthDisplay;

		public readonly EffectiveHealthDisplayConfig MaxHealthDisplay;

		public EffectiveHealthConfig(in ConfigContext context)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			Enabled = context.Bind("Enabled", defaultValue: true, new ConfigDescription("If effective health should be displayed.", (AcceptableValueBase)null, Array.Empty<object>()));
			ConfigEntry<string> configEntry = context.Bind("Display Format", "<size=65%>(Eff. {value})</size>", new ConfigDescription("The format that will be used to display effective health.\r\n\r\nAll instances of '{value}' (braces included!) will be replaced with the effective health value", (AcceptableValueBase)null, Array.Empty<object>()));
			EffectiveHealthDisplayFormat = new TagReplacementStringConfig(configEntry, new string[1] { "{value}" });
			ConfigContext context2 = context;
			context2.NameFormat = "Current Health {0}";
			CurrentHealthDisplay = new EffectiveHealthDisplayConfig(in context2, this, EffectiveHealthDisplayConfig.DisplayPosition.BeforeHealth);
			ConfigContext context3 = context;
			context3.NameFormat = "Max Health {0}";
			MaxHealthDisplay = new EffectiveHealthDisplayConfig(in context3, this, EffectiveHealthDisplayConfig.DisplayPosition.AfterHealth);
		}
	}
	public class EffectiveHealthDisplayConfig
	{
		public enum DisplayPosition
		{
			None,
			BeforeHealth,
			AfterHealth
		}

		public readonly EffectiveHealthConfig EffectiveHealthConfig;

		public readonly ConfigEntry<DisplayPosition> HealthDisplayPosition;

		public EffectiveHealthDisplayConfig(in ConfigContext context, EffectiveHealthConfig effectiveHealthConfig, DisplayPosition defaultDisplayPosition)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			EffectiveHealthConfig = effectiveHealthConfig;
			HealthDisplayPosition = context.Bind("Display Position", defaultDisplayPosition, new ConfigDescription("How this effective health should be displayed.\r\n\r\nNone: Effective health is not displayed.\r\n\r\nBeforeHealth: Effective health is displayed to the left of the health value.\r\n\r\nAfterHealth: Effective health is displayed to the right of the health value.", (AcceptableValueBase)null, Array.Empty<object>()));
		}

		public bool ShouldDisplay()
		{
			if (EffectiveHealthConfig.Enabled.Value)
			{
				return HealthDisplayPosition.Value != DisplayPosition.None;
			}
			return false;
		}

		public string Format(float displayHealth, float displayEffectiveHealth)
		{
			string text = displayHealth.ToString();
			if (float.IsNaN(displayEffectiveHealth) || !ShouldDisplay())
			{
				return text;
			}
			string effectiveHealthString;
			if (float.IsInfinity(displayEffectiveHealth))
			{
				effectiveHealthString = "<color=#555555>INF.</color>";
			}
			else
			{
				effectiveHealthString = displayEffectiveHealth.ToString();
			}
			TagReplacementStringConfig effectiveHealthFormatter = EffectiveHealthConfig.EffectiveHealthDisplayFormat;
			StringBuilder stringBuilder = StringBuilderPool.RentStringBuilder();
			stringBuilder.EnsureCapacity(effectiveHealthFormatter.StrippedLength + effectiveHealthString.Length + text.Length + 1);
			DisplayPosition value = HealthDisplayPosition.Value;
			if (value == DisplayPosition.BeforeHealth)
			{
				appendEffectiveHealth();
				stringBuilder.Append(' ');
			}
			stringBuilder.Append(text);
			if (value == DisplayPosition.AfterHealth)
			{
				stringBuilder.Append(' ');
				appendEffectiveHealth();
			}
			string result = stringBuilder.ToString();
			stringBuilder = StringBuilderPool.ReturnStringBuilder(stringBuilder);
			return result;
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			void appendEffectiveHealth()
			{
				effectiveHealthFormatter.AppendToStringBuilder(stringBuilder, new TagReplacementStringConfig.ReplacementInfo("{value}", effectiveHealthString));
			}
		}
	}
	[DisallowMultipleComponent]
	public class EffectiveHealthDisplayController : MonoBehaviour, ICachableComponent
	{
		public static readonly ObjectComponentCache<HealthBar, EffectiveHealthDisplayController> ComponentCache = new ObjectComponentCache<HealthBar, EffectiveHealthDisplayController>();

		private HealthBar _healthBar;

		private EffectiveHealthProvider _healthProvider;

		public readonly EffectiveHealthDisplayData HealthDisplayData = new EffectiveHealthDisplayData(Configs.EffectiveHealth.CurrentHealthDisplay);

		public readonly EffectiveHealthDisplayData MaxHealthDisplayData = new EffectiveHealthDisplayData(Configs.EffectiveHealth.MaxHealthDisplay);

		int? ICachableComponent.DictionaryKey { get; set; }

		public EffectiveHealthProvider HealthProvider
		{
			get
			{
				HealthComponent val = (Object.op_Implicit((Object)(object)_healthBar) ? _healthBar.source : null);
				if (!Object.op_Implicit((Object)(object)_healthProvider) || (Object)(object)_healthProvider.HealthComponent != (Object)(object)val)
				{
					_healthProvider = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<EffectiveHealthProvider>() : null);
				}
				return _healthProvider;
			}
		}

		public GameObject SlashRoot { get; private set; }

		private void Awake()
		{
			_healthBar = ((Component)this).GetComponent<HealthBar>();
			if (Object.op_Implicit((Object)(object)_healthBar.spriteAsNumberManager))
			{
				Object.Destroy((Object)(object)((Component)_healthBar.spriteAsNumberManager).gameObject);
			}
			Transform val = ((Component)this).transform.Find("Slash");
			if (Object.op_Implicit((Object)(object)val))
			{
				SlashRoot = ((Component)val).gameObject;
			}
			else
			{
				Log.Error("Failed to find healthbar SlashRoot", "X:\\Git\\RoR2\\NoMoreMath\\NoMoreMath\\EffectiveHealth\\EffectiveHealthDisplayController.cs", "Awake", 55);
			}
		}

		private void OnDestroy()
		{
			ComponentCache.OnDestroyed(this);
			HealthDisplayData?.Dispose();
			MaxHealthDisplayData?.Dispose();
		}
	}
	public class EffectiveHealthDisplayData : IDisposable
	{
		public readonly TrackedValue<float> LastDisplayedHealthValue = new TrackedValue<float>(float.NaN);

		public readonly TrackedValue<float> LastDisplayValue = new TrackedValue<float>(float.NaN);

		private readonly EffectiveHealthDisplayConfig _displayConfig;

		public bool IsDirty;

		public EffectiveHealthDisplayData(EffectiveHealthDisplayConfig displayConfig)
		{
			_displayConfig = displayConfig ?? throw new ArgumentNullException("displayConfig");
			_displayConfig.EffectiveHealthConfig.Enabled.SettingChanged += onDisplaySettingChanged;
			_displayConfig.EffectiveHealthConfig.EffectiveHealthDisplayFormat.ConfigEntry.SettingChanged += onDisplaySettingChanged;
			_displayConfig.HealthDisplayPosition.SettingChanged += onDisplaySettingChanged;
		}

		private void onDisplaySettingChanged(object sender, EventArgs e)
		{
			IsDirty = true;
		}

		public void Dispose()
		{
			IsDirty = false;
			_displayConfig.EffectiveHealthConfig.Enabled.SettingChanged -= onDisplaySettingChanged;
			_displayConfig.EffectiveHealthConfig.EffectiveHealthDisplayFormat.ConfigEntry.SettingChanged -= onDisplaySettingChanged;
			_displayConfig.HealthDisplayPosition.SettingChanged -= onDisplaySettingChanged;
		}

		public bool ShouldDisplay()
		{
			return _displayConfig.ShouldDisplay();
		}

		public string Format(float displayHealth, float displayEffectiveHealth)
		{
			return _displayConfig.Format(displayHealth, displayEffectiveHealth);
		}
	}
	internal static class EffectiveHealthDisplayHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_UpdateHealthbar <0>__HealthBar_UpdateHealthbar;
		}

		[SystemInitializer(new Type[] { })]
		private 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>__HealthBar_UpdateHealthbar;
			if (obj == null)
			{
				hook_UpdateHealthbar val = HealthBar_UpdateHealthbar;
				<>O.<0>__HealthBar_UpdateHealthbar = val;
				obj = (object)val;
			}
			HealthBar.UpdateHealthbar += (hook_UpdateHealthbar)obj;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool isValidForEffectiveHealthDisplay(HealthBar healthBar)
		{
			if (!Object.op_Implicit((Object)(object)healthBar.currentHealthText))
			{
				return Object.op_Implicit((Object)(object)healthBar.fullHealthText);
			}
			return true;
		}

		private static void HealthBar_UpdateHealthbar(orig_UpdateHealthbar orig, HealthBar self, float deltaTime)
		{
			orig.Invoke(self, deltaTime);
			if (!isValidForEffectiveHealthDisplay(self))
			{
				return;
			}
			EffectiveHealthDisplayController orAddComponent = EffectiveHealthDisplayController.ComponentCache.GetOrAddComponent(self);
			if (!Object.op_Implicit((Object)(object)orAddComponent))
			{
				return;
			}
			EffectiveHealthProvider healthProvider = orAddComponent.HealthProvider;
			if (Object.op_Implicit((Object)(object)healthProvider))
			{
				if (Object.op_Implicit((Object)(object)orAddComponent.SlashRoot))
				{
					orAddComponent.SlashRoot.SetActive(true);
				}
				updateEffectiveHealthDisplay(self.currentHealthText, self.displayStringCurrentHealth, orAddComponent.HealthDisplayData, healthProvider.EffectiveHealth);
				updateEffectiveHealthDisplay(self.fullHealthText, self.displayStringFullHealth, orAddComponent.MaxHealthDisplayData, healthProvider.EffectiveMaxHealth);
			}
			static void updateEffectiveHealthDisplay(TextMeshProUGUI healthText, float displayHealth, EffectiveHealthDisplayData displayData, float effectiveHealth)
			{
				if (Object.op_Implicit((Object)(object)healthText))
				{
					float num = Mathf.Ceil(effectiveHealth);
					if (num < 0f || num == displayHealth || !displayData.ShouldDisplay())
					{
						num = float.NaN;
					}
					bool num2 = displayData.LastDisplayValue.Push(num);
					bool flag = displayData.LastDisplayedHealthValue.Push(displayHealth);
					if (num2 || flag || displayData.IsDirty)
					{
						((TMP_Text)healthText).text = displayData.Format(displayHealth, num);
						displayData.IsDirty = false;
					}
				}
			}
		}
	}
	[DisallowMultipleComponent]
	public class EffectiveHealthProvider : NetworkBehaviour
	{
		private static BuffIndex[] _invincibilityBuffs = Array.Empty<BuffIndex>();

		[SyncVar]
		private float _adaptiveArmorValue;

		public HealthComponent HealthComponent { get; private set; }

		public float AdaptiveArmorValue => _adaptiveArmorValue;

		public float EffectiveHealth => GetEffectiveHealth(HealthComponent.combinedHealth);

		public float EffectiveMaxHealth => GetEffectiveHealth(HealthComponent.fullHealth);

		public float Network_adaptiveArmorValue
		{
			get
			{
				return _adaptiveArmorValue;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<float>(value, ref _adaptiveArmorValue, 1u);
			}
		}

		[SystemInitializer(new Type[]
		{
			typeof(BuffCatalog),
			typeof(BodyCatalog)
		})]
		private static void Init()
		{
			List<BuffIndex> invincibilityBuffIndices = new List<BuffIndex>();
			addInvincibilityBuffDef(Buffs.BearVoidReady, 45);
			addInvincibilityBuffDef(Buffs.HiddenInvincibility, 46);
			addInvincibilityBuffDef(Buffs.SojournVehicle, 47);
			addInvincibilityBuffDef(Buffs.Immune, 48);
			addInvincibilityBuffDef(Buffs.BodyArmor, 49);
			addInvincibilityBuffDef(Buffs.HiddenRejectAllDamage, 50);
			_invincibilityBuffs = invincibilityBuffIndices.ToArray();
			Array.Sort(_invincibilityBuffs);
			foreach (GameObject allBodyPrefab in BodyCatalog.allBodyPrefabs)
			{
				if (Object.op_Implicit((Object)(object)allBodyPrefab.GetComponent<HealthComponent>()))
				{
					allBodyPrefab.AddComponent<EffectiveHealthProvider>();
				}
			}
			void addInvincibilityBuffDef(BuffDef buffDef, [CallerLineNumber] int lineNumber = -1)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				if (Object.op_Implicit((Object)(object)buffDef))
				{
					invincibilityBuffIndices.Add(buffDef.buffIndex);
				}
				else
				{
					Log.Warning($"Null BuffDef at call {lineNumber}", "X:\\Git\\RoR2\\NoMoreMath\\NoMoreMath\\EffectiveHealth\\EffectiveHealthProvider.cs", "Init", 41);
				}
			}
		}

		private void Awake()
		{
			HealthComponent = ((Component)this).GetComponent<HealthComponent>();
		}

		private void Update()
		{
			if (NetworkServer.active)
			{
				updateAdaptiveArmorServer();
			}
		}

		[Server]
		private void updateAdaptiveArmorServer()
		{
			if (!NetworkServer.active)
			{
				Debug.LogWarning((object)"[Server] function 'System.Void NoMoreMath.EffectiveHealth.EffectiveHealthProvider::updateAdaptiveArmorServer()' called on client");
			}
			else
			{
				Network_adaptiveArmorValue = (Object.op_Implicit((Object)(object)HealthComponent) ? HealthComponent.adaptiveArmorValue : 0f);
			}
		}

		public float GetEffectiveHealth(float health)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (health < 0f || !Object.op_Implicit((Object)(object)HealthComponent) || !Object.op_Implicit((Object)(object)HealthComponent.body))
			{
				return health;
			}
			if (HealthComponent.godMode)
			{
				return float.PositiveInfinity;
			}
			CharacterBody body = HealthComponent.body;
			BuffIndex[] invincibilityBuffs = _invincibilityBuffs;
			foreach (BuffIndex val in invincibilityBuffs)
			{
				if (body.HasBuff(val))
				{
					return float.PositiveInfinity;
				}
			}
			float num = 1f;
			if (body.HasBuff(Buffs.lunarruin))
			{
				num *= 1f + 0.1f * (float)body.GetBuffCount(Buffs.lunarruin);
			}
			if (body.HasBuff(Buffs.DeathMark))
			{
				num *= 1.5f;
			}
			float num2 = body.armor + _adaptiveArmorValue;
			float num3 = ((num2 >= 0f) ? (1f - num2 / (num2 + 100f)) : (2f - 100f / (100f - num2)));
			num *= num3;
			return health / num;
		}

		private void UNetVersion()
		{
		}

		public override bool OnSerialize(NetworkWriter writer, bool forceAll)
		{
			if (forceAll)
			{
				writer.Write(_adaptiveArmorValue);
				return true;
			}
			bool flag = false;
			if ((((NetworkBehaviour)this).syncVarDirtyBits & (true ? 1u : 0u)) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(_adaptiveArmorValue);
			}
			if (!flag)
			{
				writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
			}
			return flag;
		}

		public override void OnDeserialize(NetworkReader reader, bool initialState)
		{
			if (initialState)
			{
				_adaptiveArmorValue = reader.ReadSingle();
				return;
			}
			int num = (int)reader.ReadPackedUInt32();
			if (((uint)num & (true ? 1u : 0u)) != 0)
			{
				_adaptiveArmorValue = reader.ReadSingle();
			}
		}
	}
}
namespace NoMoreMath.EffectiveCost
{
	public class EffectiveCostConfig
	{
		public readonly ConfigEntry<bool> Enabled;

		public const string EFFECTIVE_COST_FORMAT_VALUE_TAG = "{value}";

		public readonly TagReplacementStringConfig CostDisplayFormat;

		public EffectiveCostConfig(in ConfigContext context)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			Enabled = context.Bind("Enabled", defaultValue: true, new ConfigDescription("If effective cost should be shown on interactables", (AcceptableValueBase)null, Array.Empty<object>()));
			ConfigEntry<string> configEntry = context.Bind("Display Format", "<size=75%>(Eff. {value})</size>", new ConfigDescription("The format that will be used to display the effective cost.\r\n\r\nAll instances of '{value}' (braces included!) will be replaced with the effective cost value", (AcceptableValueBase)null, Array.Empty<object>()));
			CostDisplayFormat = new TagReplacementStringConfig(configEntry, new string[1] { "{value}" });
		}
	}
	internal static class EffectiveCostDisplayHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__MoneyCostTypeDef_BuildCostString_Manipulator;

			public static <>A{00000018}<CostTypeDef, BuildCostStringContext> <1>__postfix;
		}

		[SystemInitializer(new Type[] { typeof(CostTypeCatalog) })]
		private static void Init()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			MethodInfo method = ((Delegate)(object)CostTypeCatalog.GetCostTypeDef((CostTypeIndex)1).buildCostString).Method;
			object obj = <>O.<0>__MoneyCostTypeDef_BuildCostString_Manipulator;
			if (obj == null)
			{
				Manipulator val = MoneyCostTypeDef_BuildCostString_Manipulator;
				<>O.<0>__MoneyCostTypeDef_BuildCostString_Manipulator = val;
				obj = (object)val;
			}
			new ILHook((MethodBase)method, (Manipulator)obj);
		}

		private static void MoneyCostTypeDef_BuildCostString_Manipulator(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			ParameterDefinition val2 = null;
			ParameterDefinition val3 = null;
			Enumerator<ParameterDefinition> enumerator = ((MethodReference)il.Method).Parameters.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ParameterDefinition current = enumerator.Current;
					if (Extensions.Is((MemberReference)(object)((ParameterReference)current).ParameterType, (MemberInfo)typeof(CostTypeDef)))
					{
						if (val2 == null)
						{
							val2 = current;
						}
					}
					else if (Extensions.Is((MemberReference)(object)((ParameterReference)current).ParameterType, (MemberInfo)typeof(BuildCostStringContext)) && val3 == null)
					{
						val3 = current;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			if (val2 == null)
			{
				Log.Error("Failed to find CostTypeDef parameter", "X:\\Git\\RoR2\\NoMoreMath\\NoMoreMath\\EffectiveCost\\EffectiveCostDisplayHooks.cs", "MoneyCostTypeDef_BuildCostString_Manipulator", 42);
				return;
			}
			if (val3 == null)
			{
				Log.Error("Failed to find context parameter", "X:\\Git\\RoR2\\NoMoreMath\\NoMoreMath\\EffectiveCost\\EffectiveCostDisplayHooks.cs", "MoneyCostTypeDef_BuildCostString_Manipulator", 48);
				return;
			}
			while (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchRet(x)
			}))
			{
				val.Emit(OpCodes.Ldarg, val2);
				val.Emit(OpCodes.Ldarga, val3);
				val.EmitDelegate<<>A{00000018}<CostTypeDef, BuildCostStringContext>>((<>A{00000018}<CostTypeDef, BuildCostStringContext>)postfix);
				val.SearchTarget = (SearchTarget)1;
			}
			static void postfix(CostTypeDef costTypeDef, in BuildCostStringContext context)
			{
				if (costTypeDef != null)
				{
					EffectiveCostConfig effectiveCost = Configs.EffectiveCost;
					if (effectiveCost.Enabled.Value)
					{
						LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
						if (firstLocalUser != null)
						{
							CharacterMaster cachedMaster = firstLocalUser.cachedMaster;
							if (Object.op_Implicit((Object)(object)cachedMaster))
							{
								int effectiveCost2 = EffectiveCostUtils.GetEffectiveCost(costTypeDef, context.cost, cachedMaster);
								if (effectiveCost2 != context.cost)
								{
									string stringFormatted = Language.GetStringFormatted(costTypeDef.costStringFormatToken, new object[1] { effectiveCost2 });
									context.stringBuilder.EnsureCapacity(context.stringBuilder.Length + effectiveCost.CostDisplayFormat.StrippedLength + stringFormatted.Length + 1);
									context.stringBuilder.Append(' ');
									effectiveCost.CostDisplayFormat.AppendToStringBuilder(context.stringBuilder, new TagReplacementStringConfig.ReplacementInfo("{value}", stringFormatted));
								}
							}
						}
					}
				}
			}
		}
	}
	public static class EffectiveCostUtils
	{
		public static int GetEffectiveCost(CostTypeDef costType, int cost, CharacterMaster master)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (costType == CostTypeCatalog.GetCostTypeDef((CostTypeIndex)1) && Object.op_Implicit((Object)(object)master))
			{
				int num = 0;
				CharacterBody body = master.GetBody();
				if (Object.op_Implicit((Object)(object)body))
				{
					EquipmentSlot equipmentSlot = body.equipmentSlot;
					if (Object.op_Implicit((Object)(object)equipmentSlot))
					{
						num = equipmentSlot.stock;
					}
				}
				Inventory inventory = master.inventory;
				if (Object.op_Implicit((Object)(object)inventory) && inventory.currentEquipmentIndex == Equipment.MultiShopCard.equipmentIndex && num > 0 && cost > 0)
				{
					int num2 = (int)(0.1f * (float)cost);
					if (num2 > 0)
					{
						cost -= num2;
					}
				}
			}
			return cost;
		}

		public static int GetTotalEffectiveCost(CostTypeDef costType, int[] costs, CharacterMaster master)
		{
			if (costs.Length == 0)
			{
				return 0;
			}
			if (costs.Length == 1)
			{
				return GetEffectiveCost(costType, costs[0], master);
			}
			int num = int.MinValue;
			int num2 = -1;
			for (int i = 0; i < costs.Length; i++)
			{
				if (costs[i] > num)
				{
					num = costs[i];
					num2 = i;
				}
			}
			int num3 = 0;
			if (num2 >= 0)
			{
				num3 += num;
			}
			for (int j = 0; j < costs.Length; j++)
			{
				if (j != num2)
				{
					num3 += GetEffectiveCost(costType, costs[j], master);
				}
			}
			return num3;
		}
	}
}
namespace NoMoreMath.Config
{
	public struct ConfigContext
	{
		public ConfigFile File;

		public string SectionName;

		public string NameFormat;

		public readonly string GetFormattedName(string name)
		{
			if (!string.IsNullOrEmpty(NameFormat))
			{
				return string.Format(NameFormat, name);
			}
			return name;
		}

		public readonly ConfigEntry<T> Bind<T>(string name, T defaultValue, ConfigDescription description)
		{
			if (File == null)
			{
				throw new InvalidOperationException("ConfigFile not set");
			}
			if (string.IsNullOrEmpty(SectionName))
			{
				throw new InvalidOperationException("SectionName not set");
			}
			return File.Bind<T>(SectionName, GetFormattedName(name), defaultValue, description);
		}
	}
	public static class Configs
	{
		public static EffectiveHealthConfig EffectiveHealth { get; private set; }

		public static EffectiveCostConfig EffectiveCost { get; private set; }

		public static HoldoutZoneConfig HoldoutZone { get; private set; }

		public static HalcyonShrineConfig HalcyonShrine { get; private set; }

		public static HalcyonBeaconConfig HalcyonBeacon { get; private set; }

		public static ShrineChanceConfig ShrineChance { get; private set; }

		public static ShrineBloodConfig ShrineBlood { get; private set; }

		internal static void Init(ConfigFile file)
		{
			ConfigContext configContext = default(ConfigContext);
			configContext.File = file;
			ConfigContext context;
			ConfigContext configContext2 = (context = configContext);
			context.SectionName = "Effective Health";
			EffectiveHealth = new EffectiveHealthConfig(in context);
			ConfigContext context2 = configContext2;
			context2.SectionName = "Effective Cost";
			EffectiveCost = new EffectiveCostConfig(in context2);
			ConfigContext context3 = configContext2;
			context3.SectionName = "Holdout Zone";
			HoldoutZone = new HoldoutZoneConfig(in context3);
			ConfigContext context4 = configContext2;
			context4.SectionName = "Halcyon Shrine";
			HalcyonShrine = new HalcyonShrineConfig(in context4);
			ConfigContext context5 = configContext2;
			context5.SectionName = "Halcyon Beacon";
			HalcyonBeacon = new HalcyonBeaconConfig(in context5);
			ConfigContext context6 = configContext2;
			context6.SectionName = "Chance Shrine";
			ShrineChance = new ShrineChanceConfig(in context6);
			ConfigContext context7 = configContext2;
			context7.SectionName = "Blood Shrine";
			ShrineBlood = new ShrineBloodConfig(in context7);
		}
	}
	public class TagReplacementStringConfig : IDisposable
	{
		private readonly struct TagInfo
		{
			public readonly string Tag;

			public readonly int StartIndex;

			public TagInfo(string tag, int startIndex)
			{
				Tag = tag;
				StartIndex = startIndex;
			}
		}

		public readonly struct ReplacementInfo
		{
			public readonly string Tag;

			public readonly string Value;

			public ReplacementInfo(string tag, string value)
			{
				Tag = tag;
				Value = value;
			}
		}

		public readonly ConfigEntry<string> ConfigEntry;

		private readonly string[] _validTags;

		private TagInfo[] _cachedTagInfos = Array.Empty<TagInfo>();

		public int StrippedLength { get; private set; }

		public event Action OnValueChanged;

		public TagReplacementStringConfig(ConfigEntry<string> configEntry, string[] validTags)
		{
			ConfigEntry = configEntry;
			_validTags = validTags;
			ConfigEntry.SettingChanged += ConfigEntry_SettingChanged;
			parseConfigValue();
		}

		public void Dispose()
		{
			ConfigEntry.SettingChanged -= ConfigEntry_SettingChanged;
		}

		private void ConfigEntry_SettingChanged(object sender, EventArgs e)
		{
			parseConfigValue();
			this.OnValueChanged?.Invoke();
		}

		private void parseConfigValue()
		{
			List<TagInfo> list = new List<TagInfo>(_validTags.Length);
			string value = ConfigEntry.Value;
			for (int i = 0; i < value.Length; i++)
			{
				string[] validTags = _validTags;
				foreach (string text in validTags)
				{
					if (i + text.Length <= value.Length && string.Compare(value, i, text, 0, text.Length, CultureInfo.InvariantCulture, CompareOptions.None) == 0)
					{
						list.Add(new TagInfo(text, i));
						i += text.Length - 1;
						break;
					}
				}
			}
			_cachedTagInfos = list.ToArray();
			int num = value.Length;
			TagInfo[] cachedTagInfos = _cachedTagInfos;
			for (int j = 0; j < cachedTagInfos.Length; j++)
			{
				TagInfo tagInfo = cachedTagInfos[j];
				num -= tagInfo.Tag.Length;
			}
			StrippedLength = num;
		}

		public void AppendToStringBuilder(StringBuilder stringBuilder, params ReplacementInfo[] tagReplacements)
		{
			string value = ConfigEntry.Value;
			if (_cachedTagInfos.Length == 0)
			{
				stringBuilder.Append(value);
				return;
			}
			int num = 0;
			TagInfo[] cachedTagInfos = _cachedTagInfos;
			for (int i = 0; i < cachedTagInfos.Length; i++)
			{
				TagInfo tagInfo = cachedTagInfos[i];
				int num2 = tagInfo.StartIndex - num;
				if (num2 > 0)
				{
					stringBuilder.Append(value, num, num2);
				}
				num = tagInfo.StartIndex + tagInfo.Tag.Length;
				for (int j = 0; j < tagReplacements.Length; j++)
				{
					ReplacementInfo replacementInfo = tagReplacements[j];
					if (string.Equals(replacementInfo.Tag, tagInfo.Tag))
					{
						stringBuilder.Append(replacementInfo.Value);
						break;
					}
				}
			}
			int num3 = value.Length - num;
			if (num3 > 0)
			{
				stringBuilder.Append(value, num, num3);
			}
		}
	}
}
namespace Unity
{
	[StructLayout(LayoutKind.Auto, CharSet = CharSet.Auto)]
	public class GeneratedNetworkCode
	{
		public static void _WriteArrayGameObject_None(NetworkWriter writer, GameObject[] value)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			if (value == null)
			{
				writer.Write((ushort)0);
				return;
			}
			ushort num = (ushort)value.Length;
			writer.Write(num);
			for (ushort num2 = 0; num2 < value.Length; num2++)
			{
				writer.Write(value[num2]);
			}
		}

		public static void _WriteGoldshoresBeaconCollection_None(NetworkWriter writer, GoldshoresBeaconCollection value)
		{
			_WriteArrayGameObject_None(writer, value.BeaconObjects);
		}

		public static GameObject[] _ReadArrayGameObject_None(NetworkReader reader)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			int num = reader.ReadUInt16();
			if (num == 0)
			{
				return (GameObject[])(object)new GameObject[0];
			}
			GameObject[] array = (GameObject[])(object)new GameObject[num];
			for (int i = 0; i < num; i++)
			{
				ref GameObject reference = ref array[i];
				reference = reader.ReadGameObject();
			}
			return array;
		}

		public static GoldshoresBeaconCollection _ReadGoldshoresBeaconCollection_None(NetworkReader reader)
		{
			GoldshoresBeaconCollection result = default(GoldshoresBeaconCollection);
			result.BeaconObjects = _ReadArrayGameObject_None(reader);
			return result;
		}
	}
}