Decompiled source of Effect Preview v0.1.0

EffectPreview.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using EffectPreview.Common;
using EffectPreview.Preview;
using EffectPreview.Ui;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak;
using Peak.Afflictions;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("EffectPreview")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+e708358c260e13915cbbfaaac10775de02ed2738")]
[assembly: AssemblyProduct("EffectPreview")]
[assembly: AssemblyTitle("EffectPreview")]
[assembly: AssemblyVersion("0.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EffectPreview
{
	[BepInPlugin("OnlyCook.EffectPreview", "Effect Preview", "0.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		internal static Plugin Instance { get; private set; }

		internal PluginConfig Cfg { get; private set; }

		internal ManualLogSource Log => ((BaseUnityPlugin)this).Logger;

		private void Awake()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0042: 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)
			Instance = this;
			Cfg = new PluginConfig(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("OnlyCook.EffectPreview");
			_harmony.PatchAll();
			GameObject val = new GameObject("EffectPreview.Runtime");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<HeldItemPreviewTracker>();
			val.AddComponent<GhostBarOverlay>();
			val.AddComponent<GhostJetpackFuelGauge>();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Effect Preview 0.1.0 loaded.");
		}
	}
	internal class PluginConfig
	{
		internal ConfigEntry<bool> EnablePreview;

		internal ConfigEntry<bool> EnableWasteIndicator;

		internal ConfigEntry<bool> EnableRemovalBlink;

		internal ConfigEntry<bool> ShowGhostBarCounts;

		internal ConfigEntry<bool> ShowVanillaBarCounts;

		internal ConfigEntry<float> BarCountFontScale;

		internal ConfigEntry<bool> StickyThornRemoval;

		internal ConfigEntry<bool> EnableWorldObjectPreviews;

		internal ConfigEntry<bool> EnablePlayerEntityPreviews;

		internal ConfigEntry<bool> EnableCookingPreview;

		internal ConfigEntry<KeyCode> CookingPreviewKey;

		internal PluginConfig(ConfigFile config)
		{
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			EnablePreview = config.Bind<bool>("General", "enable-preview", true, "Show a ghost preview of status effect changes on both stamina bars while holding an item that would cause them.");
			EnableWorldObjectPreviews = config.Bind<bool>("General", "enable-world-object-previews", true, "Show a preview when empty-handed and able to interact with a world object that changes your status effects (unlit campfires, ancient luggage).");
			EnablePlayerEntityPreviews = config.Bind<bool>("General", "enable-player-entity-previews", true, "Show a preview when empty-handed and able to interact with a physical Thorn/Arrow stuck on your own body.");
			EnableCookingPreview = config.Bind<bool>("General", "enable-cooking-preview", true, "While holding an item you're able to cook (near a lit campfire or portable stove), hold the cooking preview key to preview what its next cook stage would do instead of its current stage.");
			CookingPreviewKey = config.Bind<KeyCode>("General", "cooking-preview-key", (KeyCode)99, "Key to hold to preview a held item's next cook stage instead of its current one.");
			StickyThornRemoval = config.Bind<bool>("General", "sticky-thorn-removal", true, "Keep removing a physical Thorn/Arrow you're holding interact on even if your aim drifts off it, instead of vanilla's behavior of cancelling the moment you're not looking straight at it.");
			EnableWasteIndicator = config.Bind<bool>("General", "enable-waste-indicator", false, "Show a marker on the ghost preview when the held item's effect would only be partially applied (some of it wasted).");
			EnableRemovalBlink = config.Bind<bool>("General", "enable-removal-blink", true, "Pulse the ghost bar for anything the held item would remove, instead of showing it as a steady translucent bar.");
			ShowGhostBarCounts = config.Bind<bool>("General", "show-ghost-bar-counts", false, "Show a number on each ghost preview bar (this mod's own) for how much it would add or remove.");
			ShowVanillaBarCounts = config.Bind<bool>("General", "show-vanilla-bar-counts", false, "Show a number on the game's own (non-ghost) bars for their current amount.");
			BarCountFontScale = config.Bind<float>("General", "bar-count-font-scale", 1f, new ConfigDescription("Multiplier applied on top of the automatic size-to-fit bar scaling used by both ghost/vanilla bar count numbers.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), Array.Empty<object>()));
		}
	}
	public static class PluginInfo
	{
		public const string Guid = "OnlyCook.EffectPreview";

		public const string Name = "Effect Preview";

		public const string Version = "0.1.0";
	}
}
namespace EffectPreview.Ui
{
	internal class BarLabel
	{
		private const float OutlineWidth = 0.08f;

		private const float WidthPadding = 4f;

		private const float MinFontSize = 1f;

		private const float MaxFontSize = 24f;

		private const float BoxHeight = 40f;

		private const float VerticalOffset = 3f;

		private const float MinWidthToShow = 10f;

		private const float GhostAlpha = 0.85f;

		private const float MinReadableFontSizeForFit = 10f;

		private const float EstimatedCharWidthFactor = 0.55f;

		private const string ArrowGlyph = "→";

		private readonly TextMeshProUGUI _text;

		private readonly Vector3[] _cornerBuffer = (Vector3[])(object)new Vector3[4];

		internal bool IsValid => (Object)(object)_text != (Object)null;

		private BarLabel(TextMeshProUGUI text)
		{
			_text = text;
		}

		internal static BarLabel Create(Transform parent, TMP_FontAsset font, Material fontMaterial)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0057: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("EffectPreview BarLabel", new Type[2]
			{
				typeof(RectTransform),
				typeof(LayoutElement)
			});
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent(parent, false);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			val2.pivot = val3;
			Vector2 anchorMin = (val2.anchorMax = val3);
			val2.anchorMin = anchorMin;
			val.GetComponent<LayoutElement>().ignoreLayout = true;
			TextMeshProUGUI val5 = val.AddComponent<TextMeshProUGUI>();
			if ((Object)(object)font != (Object)null)
			{
				((TMP_Text)val5).font = font;
			}
			if ((Object)(object)fontMaterial != (Object)null)
			{
				((TMP_Text)val5).fontSharedMaterial = fontMaterial;
			}
			((TMP_Text)val5).alignment = (TextAlignmentOptions)514;
			((TMP_Text)val5).enableWordWrapping = false;
			((Graphic)val5).raycastTarget = false;
			((TMP_Text)val5).enableAutoSizing = true;
			((TMP_Text)val5).fontSizeMin = 1f;
			((TMP_Text)val5).fontSizeMax = 24f;
			((TMP_Text)val5).outlineWidth = 0.08f;
			val.SetActive(false);
			return new BarLabel(val5);
		}

		internal static string FormatCount(float fraction)
		{
			return Mathf.RoundToInt(fraction * 100f).ToString();
		}

		internal static Color GhostTint(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			Color result = Color.Lerp(color, Color.white, 0.4f);
			result.a = 0.85f;
			return result;
		}

		internal void ApplyTransition(RectTransform target, float beforeFraction, float afterFraction, Color foreground, Color outlineColor, float scaleMultiplier)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null || !((Component)target).gameObject.activeInHierarchy)
			{
				Hide();
				return;
			}
			string text = FormatCount(beforeFraction);
			if (afterFraction >= beforeFraction - 0.0005f)
			{
				Apply(target, text, foreground, outlineColor, scaleMultiplier);
				return;
			}
			string text2 = text + " → " + FormatCount(afterFraction);
			target.GetWorldCorners(_cornerBuffer);
			float num = _cornerBuffer[2].x - _cornerBuffer[0].x;
			float num2 = (float)text2.Length * 0.55f * 10f;
			Apply(target, (num >= num2) ? text2 : text, foreground, outlineColor, scaleMultiplier);
		}

		internal void Apply(RectTransform target, string content, Color foreground, Color outlineColor, float scaleMultiplier)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null || !((Component)target).gameObject.activeInHierarchy || string.IsNullOrEmpty(content))
			{
				Hide();
				return;
			}
			target.GetWorldCorners(_cornerBuffer);
			float num = _cornerBuffer[2].x - _cornerBuffer[0].x;
			float num2 = _cornerBuffer[1].y - _cornerBuffer[0].y;
			if (num < 10f || num2 <= 1f)
			{
				Hide();
				return;
			}
			Vector3 val = (_cornerBuffer[0] + _cornerBuffer[2]) * 0.5f;
			((Component)_text).gameObject.SetActive(true);
			((TMP_Text)_text).transform.SetAsLastSibling();
			((TMP_Text)_text).rectTransform.sizeDelta = new Vector2(Mathf.Max(1f, num - 4f), 40f);
			((TMP_Text)_text).transform.localScale = Vector3.one * Mathf.Max(0.01f, scaleMultiplier);
			Vector3 position = ((Transform)((TMP_Text)_text).rectTransform).position;
			position.x = val.x;
			position.y = val.y + 3f;
			((Transform)((TMP_Text)_text).rectTransform).position = position;
			((TMP_Text)_text).text = content;
			((Graphic)_text).color = foreground;
			((TMP_Text)_text).outlineColor = Color32.op_Implicit(outlineColor);
		}

		internal void Hide()
		{
			if ((Object)(object)_text != (Object)null)
			{
				((Component)_text).gameObject.SetActive(false);
			}
		}
	}
	internal class BorderWarningBlink
	{
		private const float PulseSpeed = 6f;

		private const float PulseAmount = 0.6f;

		private const float LerpRate = 12f;

		private static readonly Color WarnColor = new Color(1f, 0.15f, 0.1f, 1f);

		private readonly Image[] _images;

		private readonly Color[] _originalColors;

		private float _sinTime;

		private float _blend;

		internal bool IsValid
		{
			get
			{
				for (int i = 0; i < _images.Length; i++)
				{
					if ((Object)(object)_images[i] == (Object)null)
					{
						return false;
					}
				}
				return true;
			}
		}

		internal BorderWarningBlink(params Image[] images)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			_images = images;
			_originalColors = (Color[])(object)new Color[images.Length];
			for (int i = 0; i < images.Length; i++)
			{
				_originalColors[i] = (((Object)(object)images[i] != (Object)null) ? ((Graphic)images[i]).color : Color.white);
			}
		}

		internal void Apply(bool active)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			float num = (active ? 1f : 0f);
			_blend = Mathf.MoveTowards(_blend, num, Time.deltaTime * 12f);
			_sinTime = ((_blend > 0f) ? (_sinTime + Time.deltaTime * 6f) : 0f);
			float num2 = (Mathf.Sin(_sinTime) + 1f) * 0.5f * 0.6f * _blend;
			for (int i = 0; i < _images.Length; i++)
			{
				((Graphic)_images[i]).color = Color.Lerp(_originalColors[i], WarnColor, num2);
			}
		}

		internal void Hide()
		{
			Apply(active: false);
		}
	}
	internal class GhostBadge
	{
		private readonly struct Strip
		{
			internal readonly RectTransform Rtf;

			internal readonly Color FillColor;

			private readonly Image[] _images;

			private readonly float[] _baseAlphas;

			private readonly bool _isRemoval;

			private readonly RectTransform _iconRtf;

			private readonly RectTransform _strikethroughRtf;

			private const float StrikethroughThicknessRatio = 0.16f;

			internal bool IsValid => (Object)(object)Rtf != (Object)null;

			private Strip(RectTransform rtf, Color fillColor, Image[] images, float[] baseAlphas, bool isRemoval, RectTransform iconRtf, RectTransform strikethroughRtf)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				Rtf = rtf;
				FillColor = fillColor;
				_images = images;
				_baseAlphas = baseAlphas;
				_isRemoval = isRemoval;
				_iconRtf = iconRtf;
				_strikethroughRtf = strikethroughRtf;
			}

			internal static Strip CloneFrom(RectTransform sourceBadge, Transform insertAfter, bool isRemoval = false)
			{
				//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_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0101: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
				GameObject val = Object.Instantiate<GameObject>(((Component)sourceBadge).gameObject, ((Transform)sourceBadge).parent);
				((Object)val).name = ((Object)sourceBadge).name + " (EffectPreview Ghost)";
				BarAffliction component = val.GetComponent<BarAffliction>();
				Image val2 = (((Object)(object)component != (Object)null) ? component.icon : null);
				if ((Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)component);
				}
				Color fillColor = WasteIndicator.SampleFillColor(val, val2);
				Image[] componentsInChildren = val.GetComponentsInChildren<Image>(true);
				float[] array = new float[componentsInChildren.Length];
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Color val3 = Color.Lerp(((Graphic)componentsInChildren[i]).color, Color.white, 0.4f);
					val3.a = 0.65f;
					((Graphic)componentsInChildren[i]).color = val3;
					array[i] = val3.a;
				}
				RectTransform strikethroughRtf = ((isRemoval && (Object)(object)val2 != (Object)null) ? CreateStrikethrough(((Graphic)val2).rectTransform, ((Graphic)val2).color) : null);
				val.transform.SetSiblingIndex(insertAfter.GetSiblingIndex() + 1);
				val.SetActive(false);
				return new Strip(val.GetComponent<RectTransform>(), fillColor, componentsInChildren, array, isRemoval, ((Object)(object)val2 != (Object)null) ? ((Graphic)val2).rectTransform : null, strikethroughRtf);
			}

			internal void Apply(float targetWidth, float lerpStep)
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				float num = (((Component)Rtf).gameObject.activeSelf ? Rtf.sizeDelta.x : 0f);
				if (targetWidth <= 0f && num < 4f)
				{
					Hide();
					return;
				}
				float num2 = Mathf.Lerp(num, Mathf.Max(0f, targetWidth), lerpStep);
				Rtf.sizeDelta = new Vector2(num2, Rtf.sizeDelta.y);
				((Component)Rtf).gameObject.SetActive(true);
				if (_isRemoval)
				{
					RemovalPulse.Apply(_images, _baseAlphas);
				}
				UpdateStrikethrough();
			}

			internal void Hide()
			{
				if ((Object)(object)Rtf != (Object)null)
				{
					((Component)Rtf).gameObject.SetActive(false);
				}
			}

			private void UpdateStrikethrough()
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_strikethroughRtf == (Object)null) && !((Object)(object)_iconRtf == (Object)null))
				{
					Rect rect = _iconRtf.rect;
					float width = ((Rect)(ref rect)).width;
					rect = _iconRtf.rect;
					float num = Mathf.Min(width, ((Rect)(ref rect)).height);
					if (!(num <= 0f))
					{
						_strikethroughRtf.sizeDelta = new Vector2(num * 1.4142135f, num * 0.16f);
						((Transform)_strikethroughRtf).localRotation = Quaternion.Euler(0f, 0f, 45f);
					}
				}
			}

			private static RectTransform CreateStrikethrough(RectTransform iconRtf, Color tintColor)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Expected O, but got Unknown
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: 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_0058: 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_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Expected O, but got Unknown
				GameObject val = new GameObject("GhostStrikethrough", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				RectTransform val2 = (RectTransform)val.transform;
				((Transform)val2).SetParent((Transform)(object)iconRtf, false);
				Vector2 val3 = default(Vector2);
				((Vector2)(ref val3))..ctor(0.5f, 0.5f);
				val2.pivot = val3;
				Vector2 anchorMin = (val2.anchorMax = val3);
				val2.anchorMin = anchorMin;
				val2.anchoredPosition = Vector2.zero;
				Image component = val.GetComponent<Image>();
				((Graphic)component).color = tintColor;
				((Graphic)component).raycastTarget = false;
				return val2;
			}
		}

		private const float LerpRate = 10f;

		private const float MaxLerpStep = 0.1f;

		private readonly RectTransform _realRtf;

		private readonly GameObject _realIcon;

		private readonly Strip _decreaseGhost;

		private readonly Strip _increaseGhost;

		private readonly WasteIndicator _decreaseWaste;

		private readonly WasteIndicator _increaseWaste;

		private readonly BarLabel _decreaseCountLabel;

		private readonly BarLabel _increaseCountLabel;

		private readonly BarLabel _realCountLabel;

		private readonly Color _vanillaForeground;

		private readonly Color _vanillaOutline;

		private readonly Color _ghostForeground;

		private readonly Color _ghostOutline;

		private bool _realShrinking;

		private float _realDisplayedWidth;

		internal bool IsValid
		{
			get
			{
				if ((Object)(object)_realRtf != (Object)null && _decreaseGhost.IsValid && _increaseGhost.IsValid && _decreaseWaste.IsValid && _increaseWaste.IsValid && _decreaseCountLabel.IsValid && _increaseCountLabel.IsValid)
				{
					return _realCountLabel.IsValid;
				}
				return false;
			}
		}

		internal RectTransform RowParent
		{
			get
			{
				Transform parent = ((Transform)_realRtf).parent;
				return (RectTransform)(object)((parent is RectTransform) ? parent : null);
			}
		}

		private GhostBadge(RectTransform realRtf, GameObject realIcon, Strip decreaseGhost, Strip increaseGhost, WasteIndicator decreaseWaste, WasteIndicator increaseWaste, BarLabel decreaseCountLabel, BarLabel increaseCountLabel, BarLabel realCountLabel)
		{
			//IL_004d: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			_realRtf = realRtf;
			_realIcon = realIcon;
			_decreaseGhost = decreaseGhost;
			_increaseGhost = increaseGhost;
			_decreaseWaste = decreaseWaste;
			_increaseWaste = increaseWaste;
			_decreaseCountLabel = decreaseCountLabel;
			_increaseCountLabel = increaseCountLabel;
			_realCountLabel = realCountLabel;
			_vanillaForeground = decreaseGhost.FillColor;
			_vanillaForeground.a = 1f;
			_vanillaOutline = ColorUtil.Darken(_vanillaForeground);
			_ghostForeground = BarLabel.GhostTint(decreaseGhost.FillColor);
			_ghostOutline = ColorUtil.Darken(_ghostForeground);
		}

		internal static GhostBadge Create(BarAffliction realAffliction, TMP_FontAsset font, Material fontMaterial)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rtf = realAffliction.rtf;
			Strip decreaseGhost = Strip.CloneFrom(rtf, (Transform)(object)rtf, isRemoval: true);
			Strip increaseGhost = Strip.CloneFrom(rtf, (Transform)(object)decreaseGhost.Rtf);
			WasteIndicator decreaseWaste = WasteIndicator.Create(((Transform)rtf).parent, decreaseGhost.FillColor);
			WasteIndicator increaseWaste = WasteIndicator.Create(((Transform)rtf).parent, increaseGhost.FillColor);
			BarLabel decreaseCountLabel = BarLabel.Create(((Transform)rtf).parent, font, fontMaterial);
			BarLabel increaseCountLabel = BarLabel.Create(((Transform)rtf).parent, font, fontMaterial);
			BarLabel realCountLabel = BarLabel.Create(((Transform)rtf).parent, font, fontMaterial);
			GameObject realIcon = (((Object)(object)realAffliction.icon != (Object)null) ? ((Component)realAffliction.icon).gameObject : null);
			return new GhostBadge(rtf, realIcon, decreaseGhost, increaseGhost, decreaseWaste, increaseWaste, decreaseCountLabel, increaseCountLabel, realCountLabel);
		}

		internal void ApplyWidths(float fullLocalWidth, float liveValue, float decreaseAmount, float increaseAmount)
		{
			//IL_0087: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Min(Time.deltaTime * 10f, 0.1f);
			float num2 = Mathf.Min(decreaseAmount, liveValue);
			if (num2 > 0f)
			{
				float num3 = Mathf.Max(0f, liveValue - num2);
				float num4 = fullLocalWidth * num3;
				if (!_realShrinking)
				{
					_realDisplayedWidth = _realRtf.sizeDelta.x;
				}
				_realShrinking = true;
				_realDisplayedWidth = Mathf.Lerp(_realDisplayedWidth, num4, num);
				_realRtf.sizeDelta = new Vector2(_realDisplayedWidth, _realRtf.sizeDelta.y);
				if ((Object)(object)_realIcon != (Object)null)
				{
					_realIcon.SetActive(num3 > 0.001f);
				}
			}
			else if (_realShrinking)
			{
				_realShrinking = false;
				if ((Object)(object)_realIcon != (Object)null)
				{
					_realIcon.SetActive(true);
				}
			}
			float num5 = Mathf.Min(num2, increaseAmount);
			_decreaseGhost.Apply(fullLocalWidth * (num2 - num5), num);
			_increaseGhost.Apply(fullLocalWidth * increaseAmount, num);
		}

		internal float GetTargetRowWidth(float fullLocalWidth, float liveValue, float decreaseAmount, float increaseAmount)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Min(decreaseAmount, liveValue);
			float num3;
			if (num > 0f)
			{
				float num2 = Mathf.Max(0f, liveValue - num);
				num3 = fullLocalWidth * num2;
			}
			else
			{
				num3 = (((Component)_realRtf).gameObject.activeSelf ? _realRtf.sizeDelta.x : 0f);
			}
			float num4 = Mathf.Min(num, increaseAmount);
			float num5 = fullLocalWidth * (num - num4);
			float num6 = fullLocalWidth * increaseAmount;
			return num3 + num5 + num6;
		}

		internal void ApplyOverlays(float liveValue, float decreaseAmount, float increaseAmount, float statusCap, float wasteHeight)
		{
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Min(decreaseAmount, liveValue);
			bool value = Plugin.Instance.Cfg.EnableWasteIndicator.Value;
			if (value && num > 0.0005f && decreaseAmount - num > 0.0005f)
			{
				_decreaseWaste.Apply(_decreaseGhost.Rtf, _realRtf, wasteHeight, rightEdge: false);
			}
			else
			{
				_decreaseWaste.Hide();
			}
			float num2 = Mathf.Max(0f, liveValue - num);
			float num3 = Mathf.Max(0f, statusCap - num2);
			float num4 = Mathf.Min(increaseAmount, num3);
			if (value && num4 > 0.0005f && increaseAmount - num4 > 0.0005f)
			{
				_increaseWaste.Apply(_increaseGhost.Rtf, _realRtf, wasteHeight, rightEdge: false);
			}
			else
			{
				_increaseWaste.Hide();
			}
			float value2 = Plugin.Instance.Cfg.BarCountFontScale.Value;
			if (Plugin.Instance.Cfg.ShowGhostBarCounts.Value)
			{
				float num5 = Mathf.Min(num, increaseAmount);
				float num6 = num - num5;
				_decreaseCountLabel.Apply(_decreaseGhost.Rtf, (num6 > 0.0005f) ? BarLabel.FormatCount(num6) : null, _ghostForeground, _ghostOutline, value2);
				_increaseCountLabel.Apply(_increaseGhost.Rtf, (increaseAmount > 0.0005f) ? BarLabel.FormatCount(increaseAmount) : null, _ghostForeground, _ghostOutline, value2);
			}
			else
			{
				_decreaseCountLabel.Hide();
				_increaseCountLabel.Hide();
			}
			if (Plugin.Instance.Cfg.ShowVanillaBarCounts.Value)
			{
				_realCountLabel.Apply(_realRtf, (num2 > 0.0005f) ? BarLabel.FormatCount(num2) : null, _vanillaForeground, _vanillaOutline, value2);
			}
			else
			{
				_realCountLabel.Hide();
			}
		}

		internal void Hide()
		{
			_realShrinking = false;
			_decreaseGhost.Hide();
			_increaseGhost.Hide();
			_decreaseWaste.Hide();
			_increaseWaste.Hide();
			_decreaseCountLabel.Hide();
			_increaseCountLabel.Hide();
			_realCountLabel.Hide();
			if ((Object)(object)_realIcon != (Object)null)
			{
				_realIcon.SetActive(true);
			}
		}
	}
	internal class GhostBarOverlay : MonoBehaviour
	{
		private StaminaBar _bar;

		private RectTransform _fullBar;

		private bool _built;

		private static readonly HashSet<STATUSTYPE> CurableStatuses = new HashSet<STATUSTYPE>
		{
			(STATUSTYPE)0,
			(STATUSTYPE)1,
			(STATUSTYPE)2,
			(STATUSTYPE)3,
			(STATUSTYPE)6,
			(STATUSTYPE)8,
			(STATUSTYPE)10,
			(STATUSTYPE)11,
			(STATUSTYPE)14
		};

		private readonly Dictionary<STATUSTYPE, GhostBadge> _statusGhosts = new Dictionary<STATUSTYPE, GhostBadge>();

		private readonly Dictionary<STATUSTYPE, float> _dynamicHealBreakdown = new Dictionary<STATUSTYPE, float>();

		private GhostExtraStaminaArea _extraStaminaArea;

		private GhostPetrifyArea _petrifyArea;

		private GhostStaminaArea _staminaArea;

		private GhostRainbowStamina _rainbowArea;

		private GhostInvincibilityShield _shieldArea;

		private BorderWarningBlink _passOutBorderBlink;

		private BorderWarningBlink _petrifyDeathBorderBlink;

		private BarLabel _staminaCountLabel;

		private Color _staminaVanillaForeground;

		private Color _staminaVanillaOutline;

		private void LateUpdate()
		{
			if (!Plugin.Instance.Cfg.EnablePreview.Value || !TryGetBar())
			{
				HideAll();
				return;
			}
			if (_built && IsStale())
			{
				_statusGhosts.Clear();
				_extraStaminaArea = null;
				_petrifyArea = null;
				_staminaArea = null;
				_rainbowArea = null;
				_shieldArea = null;
				_passOutBorderBlink = null;
				_petrifyDeathBorderBlink = null;
				_staminaCountLabel = null;
				_built = false;
			}
			if (!_built)
			{
				Safe.Run("GhostBarOverlay.Build", Build);
			}
			if (_built)
			{
				Safe.Run("GhostBarOverlay.Refresh", Refresh);
			}
		}

		private bool IsStale()
		{
			foreach (GhostBadge value in _statusGhosts.Values)
			{
				if (!value.IsValid)
				{
					return true;
				}
			}
			if (_extraStaminaArea != null && !_extraStaminaArea.IsValid)
			{
				return true;
			}
			if (_petrifyArea != null && !_petrifyArea.IsValid)
			{
				return true;
			}
			if (_rainbowArea != null && !_rainbowArea.IsValid)
			{
				return true;
			}
			if (_shieldArea != null && !_shieldArea.IsValid)
			{
				return true;
			}
			if (_passOutBorderBlink != null && !_passOutBorderBlink.IsValid)
			{
				return true;
			}
			if (_petrifyDeathBorderBlink != null && !_petrifyDeathBorderBlink.IsValid)
			{
				return true;
			}
			if (_staminaCountLabel != null && !_staminaCountLabel.IsValid)
			{
				return true;
			}
			if (_staminaArea != null)
			{
				return !_staminaArea.IsValid;
			}
			return false;
		}

		private bool TryGetBar()
		{
			GUIManager instance = GUIManager.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.bar == (Object)null || (Object)(object)instance.bar.fullBar == (Object)null || instance.bar.afflictions == null)
			{
				return false;
			}
			_bar = instance.bar;
			_fullBar = _bar.fullBar;
			return true;
		}

		private void Build()
		{
			//IL_007e: 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_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			TMP_FontAsset font = (((Object)(object)_bar.moraleBoostText != (Object)null) ? ((TMP_Text)_bar.moraleBoostText).font : null);
			Material fontMaterial = (((Object)(object)_bar.moraleBoostText != (Object)null) ? ((TMP_Text)_bar.moraleBoostText).fontSharedMaterial : null);
			BarAffliction[] afflictions = _bar.afflictions;
			foreach (BarAffliction val in afflictions)
			{
				if (!((Object)(object)val == (Object)null) && !val.isPetrify && !_statusGhosts.ContainsKey(val.afflictionType))
				{
					_statusGhosts[val.afflictionType] = GhostBadge.Create(val, font, fontMaterial);
				}
			}
			if (_extraStaminaArea == null && (Object)(object)_bar.extraBar != (Object)null && (Object)(object)_bar.extraBarStamina != (Object)null && (Object)(object)_bar.extraBarOutline != (Object)null && (Object)(object)_bar.extraStaminaIcon != (Object)null)
			{
				_extraStaminaArea = new GhostExtraStaminaArea(_bar.extraBar, _bar.extraBarStamina, _bar.extraBarOutline, _bar.extraStaminaIcon, font, fontMaterial);
			}
			if (_petrifyArea == null && (Object)(object)_bar.petrifyAffliction != (Object)null && (Object)(object)_bar.petrifyAffliction.rtf != (Object)null)
			{
				_petrifyArea = new GhostPetrifyArea(_bar.petrifyAffliction, font, fontMaterial);
			}
			if (_staminaCountLabel == null && (Object)(object)_bar.staminaBar != (Object)null)
			{
				_staminaCountLabel = BarLabel.Create(((Transform)_bar.staminaBar).parent, font, fontMaterial);
				_staminaVanillaForeground = WasteIndicator.SampleFillColor(((Component)_bar.staminaBar).gameObject, null);
				_staminaVanillaForeground.a = 1f;
				_staminaVanillaOutline = ColorUtil.Darken(_staminaVanillaForeground);
			}
			if (_staminaArea == null && (Object)(object)_bar.maxStaminaBar != (Object)null && (Object)(object)_bar.staminaBar != (Object)null)
			{
				_staminaArea = new GhostStaminaArea(_bar.maxStaminaBar, _bar.staminaBar);
			}
			if (_rainbowArea == null && (Object)(object)_bar.rainbowStamina != (Object)null)
			{
				_rainbowArea = GhostRainbowStamina.Create(_bar.rainbowStamina);
			}
			if (_shieldArea == null && (Object)(object)_bar.shield != (Object)null)
			{
				_shieldArea = GhostInvincibilityShield.Create(_bar.shield);
			}
			if (_passOutBorderBlink == null && (Object)(object)_bar.staminaBarOutline != (Object)null)
			{
				Transform val2 = ((Transform)_bar.staminaBarOutline).Find("OutlineImage");
				Transform val3 = ((Transform)_bar.staminaBarOutline).Find("OutlineCap");
				Image val4 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<Image>() : null);
				Image val5 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<Image>() : null);
				if ((Object)(object)val4 != (Object)null && (Object)(object)val5 != (Object)null)
				{
					_passOutBorderBlink = new BorderWarningBlink(val4, val5);
				}
				else if ((Object)(object)val4 != (Object)null)
				{
					_passOutBorderBlink = new BorderWarningBlink(val4);
				}
			}
			if (_petrifyDeathBorderBlink == null && (Object)(object)_bar.extraBarOutline != (Object)null)
			{
				Image component = ((Component)_bar.extraBarOutline).GetComponent<Image>();
				if ((Object)(object)component != (Object)null)
				{
					_petrifyDeathBorderBlink = new BorderWarningBlink(component);
				}
			}
			_built = true;
		}

		private void Refresh()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null)
			{
				HideAll();
				return;
			}
			ItemPreview current = HeldItemPreviewTracker.Instance.Current;
			float x = _fullBar.sizeDelta.x;
			_dynamicHealBreakdown.Clear();
			if ((Object)(object)current.HealingGemAction != (Object)null)
			{
				DynamicPetrifyPreview.ComputeHealBreakdown(current, localCharacter, _dynamicHealBreakdown);
			}
			float wasteHeight = (((Object)(object)_bar.extraBarStamina != (Object)null) ? WasteIndicator.MeasureHeight(_bar.extraBarStamina) : 0f);
			float num = 0f;
			foreach (KeyValuePair<STATUSTYPE, GhostBadge> statusGhost in _statusGhosts)
			{
				GetStatusPreview(localCharacter, current, statusGhost.Key, out var live, out var decrease, out var increase, out var _);
				statusGhost.Value.ApplyWidths(x, live, decrease, increase);
				num += statusGhost.Value.GetTargetRowWidth(x, live, decrease, increase);
			}
			float num2 = ComputeNetStatusSumDelta(localCharacter, current);
			float maxAllowedWidthPx = Mathf.Max(0f, x - num);
			_staminaArea?.Apply(x, localCharacter.GetMaxStamina(), localCharacter.data.currentStamina, Mathf.Max(0f, num2), maxAllowedWidthPx);
			RectTransform val = null;
			using (Dictionary<STATUSTYPE, GhostBadge>.ValueCollection.Enumerator enumerator2 = _statusGhosts.Values.GetEnumerator())
			{
				if (enumerator2.MoveNext())
				{
					val = enumerator2.Current.RowParent;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				LayoutRebuilder.ForceRebuildLayoutImmediate(val);
			}
			foreach (KeyValuePair<STATUSTYPE, GhostBadge> statusGhost2 in _statusGhosts)
			{
				GetStatusPreview(localCharacter, current, statusGhost2.Key, out var live2, out var decrease2, out var increase2, out var statusCap2);
				statusGhost2.Value.ApplyOverlays(live2, decrease2, increase2, statusCap2, wasteHeight);
			}
			if (_staminaCountLabel != null)
			{
				if (!Plugin.Instance.Cfg.ShowVanillaBarCounts.Value)
				{
					_staminaCountLabel.Hide();
				}
				else if (localCharacter.infiniteStam)
				{
					_staminaCountLabel.Apply(_bar.maxStaminaBar, "∞", _staminaVanillaForeground, _staminaVanillaOutline, Plugin.Instance.Cfg.BarCountFontScale.Value);
				}
				else if (localCharacter.data.currentStamina > 0.0005f)
				{
					float num3 = Mathf.Max(0f, localCharacter.GetMaxStamina() - num2);
					float afterFraction = Mathf.Min(localCharacter.data.currentStamina, num3);
					_staminaCountLabel.ApplyTransition(_bar.staminaBar, localCharacter.data.currentStamina, afterFraction, _staminaVanillaForeground, _staminaVanillaOutline, Plugin.Instance.Cfg.BarCountFontScale.Value);
				}
				else
				{
					_staminaCountLabel.Hide();
				}
			}
			float num4 = localCharacter.refs.afflictions.statusSum + num2;
			bool active = num4 > 0.99f;
			_passOutBorderBlink?.Apply(active);
			if ((Object)(object)_bar.staminaBarOutline != (Object)null)
			{
				float num5 = Mathf.Max(14f + Mathf.Max(1f, num4) * x, 14f + Mathf.Max(x, num));
				if (num5 > _bar.staminaBarOutline.sizeDelta.x)
				{
					_bar.staminaBarOutline.sizeDelta = new Vector2(num5, _bar.staminaBarOutline.sizeDelta.y);
				}
			}
			if (num4 > 1.005f && (Object)(object)_bar.staminaBarOutlineOverflowBar != (Object)null)
			{
				((Component)_bar.staminaBarOutlineOverflowBar).gameObject.SetActive(true);
			}
			float num6 = Mathf.Max(0f, current.PetrifyDelta + DynamicPetrifyPreview.Compute(current, localCharacter));
			float num7 = Mathf.Max(0f, 1f - (float)localCharacter.data.petrifyAmount * 0.01f);
			float num8 = Mathf.Min(num6, num7);
			float currentPetrifyFraction = (float)localCharacter.data.petrifyAmount * 0.01f;
			float shrinkDelta = Mathf.Max(0f, current.PetrifyReductionOnUse);
			bool active2 = num7 > 0.0005f && num8 >= num7 - 0.0005f;
			_petrifyDeathBorderBlink?.Apply(active2);
			bool flag = (Object)(object)_bar.petrifyAffliction != (Object)null && ((Component)_bar.petrifyAffliction).gameObject.activeSelf;
			_petrifyArea?.Apply(x, num8, num6, shrinkDelta, currentPetrifyFraction, flag, wasteHeight);
			bool petrifyGhostVisible = (_petrifyArea?.DisplayedDelta ?? 0f) > 0.002f;
			_extraStaminaArea?.Apply(x, localCharacter.data.extraStamina, current.ExtraStaminaDelta, localCharacter.data.petrifyAmount, flag, num8, petrifyGhostVisible);
			_rainbowArea?.Apply(current.GrantsInfiniteStaminaOnUse, localCharacter.infiniteStam);
			Affliction val2 = default(Affliction);
			bool realActive = localCharacter.refs.afflictions.HasAfflictionType((AfflictionType)16, ref val2);
			_shieldArea?.Apply(current.GrantsInvincibilityOnUse, realActive);
		}

		private void GetStatusPreview(Character character, ItemPreview preview, STATUSTYPE type, out float live, out float decrease, out float increase, out float statusCap)
		{
			//IL_0006: 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_0024: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			preview.StatusIncreases.TryGetValue(type, out increase);
			preview.StatusDecreases.TryGetValue(type, out decrease);
			_dynamicHealBreakdown.TryGetValue(type, out var value);
			decrease += value;
			live = character.refs.afflictions.GetCurrentStatus(type);
			if (preview.ClearsCurableStatusOnUse && CurableStatuses.Contains(type))
			{
				decrease = live;
			}
			statusCap = character.refs.afflictions.GetStatusCap(type);
		}

		private float ComputeNetStatusSumDelta(Character character, ItemPreview preview)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			HashSet<STATUSTYPE> hashSet = new HashSet<STATUSTYPE>();
			foreach (STATUSTYPE key in preview.StatusIncreases.Keys)
			{
				if (hashSet.Add(key))
				{
					num += NetStatusDelta(character, preview, key);
				}
			}
			foreach (STATUSTYPE key2 in preview.StatusDecreases.Keys)
			{
				if (hashSet.Add(key2))
				{
					num += NetStatusDelta(character, preview, key2);
				}
			}
			return num;
		}

		private float NetStatusDelta(Character character, ItemPreview preview, STATUSTYPE type)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			GetStatusPreview(character, preview, type, out var live, out var decrease, out var increase, out var _);
			float num = Mathf.Min(decrease, live);
			return increase - num;
		}

		private void HideAll()
		{
			foreach (GhostBadge value in _statusGhosts.Values)
			{
				value.Hide();
			}
			_extraStaminaArea?.Hide();
			_petrifyArea?.Hide();
			_staminaArea?.Release();
			_rainbowArea?.Hide();
			_shieldArea?.Hide();
			_passOutBorderBlink?.Hide();
			_petrifyDeathBorderBlink?.Hide();
			_staminaCountLabel?.Hide();
		}
	}
	internal class GhostExtraStaminaArea
	{
		private static readonly Vector2 ShownExtraBarSize = new Vector2(45f, 45f);

		private const float OutlinePadding = 12f;

		private const float MinOutlineWidth = 20f;

		private const float ShowDuration = 0.25f;

		private const float HideDuration = 0.2f;

		private const float HiddenThreshold = 0.0001f;

		private const float SeamOverlap = 3f;

		private const float RightEdgePaddingGhostOnly = 9f;

		private const float RightEdgePaddingWithReal = 1f;

		private const float ShrinkLerpRate = 10f;

		private const float ShrinkMaxLerpStep = 0.1f;

		private const float GrowLerpRate = 40f;

		private const float GrowMaxLerpStep = 0.5f;

		private readonly RectTransform _extraBar;

		private readonly RectTransform _extraBarStamina;

		private readonly RectTransform _extraBarOutline;

		private readonly GhostSegment _fillGhost;

		private readonly GhostIcon _icon;

		private readonly WasteIndicator _waste;

		private readonly BarLabel _ghostCountLabel;

		private readonly BarLabel _realCountLabel;

		private readonly Color _vanillaForeground;

		private readonly Color _vanillaOutline;

		private readonly Color _ghostForeground;

		private readonly Color _ghostOutline;

		private readonly Transform _fillParent;

		private readonly Vector3[] _cornerBuffer = (Vector3[])(object)new Vector3[4];

		private Tween _tween;

		private float _tweenTarget;

		private float _displayedDelta;

		private float _lastRealExtraStamina;

		private bool _manualWidthControl;

		private float _manualDisplayedWidth;

		private float _displayedOutlineWidth;

		private bool _hasDisplayedOutlineWidth;

		internal bool IsValid
		{
			get
			{
				if ((Object)(object)_extraBar != (Object)null && (Object)(object)_extraBarStamina != (Object)null && (Object)(object)_extraBarOutline != (Object)null && _fillGhost.IsValid && (_icon == null || _icon.IsValid) && _waste.IsValid && _ghostCountLabel.IsValid)
				{
					return _realCountLabel.IsValid;
				}
				return false;
			}
		}

		internal GhostExtraStaminaArea(RectTransform extraBar, RectTransform extraBarStamina, RectTransform extraBarOutline, Image extraStaminaIcon, TMP_FontAsset font, Material fontMaterial)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			_extraBar = extraBar;
			_extraBarStamina = extraBarStamina;
			_extraBarOutline = extraBarOutline;
			_fillParent = ((Transform)extraBarStamina).parent;
			_fillGhost = GhostSegment.Create(_fillParent, extraBarStamina);
			_icon = (((Object)(object)extraStaminaIcon != (Object)null) ? GhostIcon.Create(extraStaminaIcon) : null);
			Color val = WasteIndicator.SampleFillColor(((Component)extraBarStamina).gameObject, null);
			_waste = WasteIndicator.Create(_fillParent, val);
			_ghostCountLabel = BarLabel.Create(_fillParent, font, fontMaterial);
			_realCountLabel = BarLabel.Create(_fillParent, font, fontMaterial);
			_vanillaForeground = val;
			_vanillaForeground.a = 1f;
			_vanillaOutline = ColorUtil.Darken(_vanillaForeground);
			_ghostForeground = BarLabel.GhostTint(val);
			_ghostOutline = ColorUtil.Darken(_ghostForeground);
		}

		internal void Apply(float fullLocalWidth, float realExtraStamina, float delta, int petrifyAmount, bool petrifyActive, float petrifyPreviewDelta, bool petrifyGhostVisible)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			float num = delta;
			float num2 = realExtraStamina - _lastRealExtraStamina;
			if (num2 > 0.0001f)
			{
				_displayedDelta = Mathf.Max(0f, _displayedDelta - num2);
				Tween tween = _tween;
				if (tween != null)
				{
					TweenExtensions.Kill(tween, false);
				}
				_tweenTarget = _displayedDelta;
				delta = 0f;
				_manualWidthControl = true;
				_manualDisplayedWidth = _extraBarStamina.sizeDelta.x;
			}
			_lastRealExtraStamina = realExtraStamina;
			float num3 = Mathf.Max(0f, 1f - (float)petrifyAmount * 0.01f);
			float num4 = Mathf.Max(0f, num3 - Mathf.Max(0f, petrifyPreviewDelta));
			float num5 = Mathf.Max(0f, num4 - Mathf.Max(0f, realExtraStamina));
			float num6 = ((delta > 0f) ? Mathf.Min(delta, num5) : 0f);
			if (!Mathf.Approximately(num6, _tweenTarget))
			{
				bool flag = num6 > _displayedDelta;
				Tween tween2 = _tween;
				if (tween2 != null)
				{
					TweenExtensions.Kill(tween2, false);
				}
				_tweenTarget = num6;
				_tween = (Tween)(object)TweenSettingsExtensions.SetEase<TweenerCore<float, float, FloatOptions>>(DOTween.To((DOGetter<float>)(() => _displayedDelta), (DOSetter<float>)delegate(float displayedDelta)
				{
					_displayedDelta = displayedDelta;
				}, num6, flag ? 0.25f : 0.2f), (Ease)(flag ? 9 : 8));
			}
			float num7 = Mathf.Max(0f, realExtraStamina) * fullLocalWidth;
			float num8 = Mathf.Min(num7, num4 * fullLocalWidth);
			bool flag2 = num8 < num7 - 0.01f;
			if (num6 <= 0f && _displayedDelta < 0.0001f && !flag2 && !_manualWidthControl && !petrifyGhostVisible)
			{
				_fillGhost.Hide();
				_icon?.Hide();
				_waste.Hide();
				_ghostCountLabel.Hide();
				ApplyRealCountLabel(realExtraStamina, realExtraStamina);
				_hasDisplayedOutlineWidth = false;
				return;
			}
			((Component)_extraBar).gameObject.SetActive(true);
			_extraBar.sizeDelta = ShownExtraBarSize;
			if (realExtraStamina > 0f)
			{
				_icon?.Hide();
			}
			else if (num6 > 0f)
			{
				_icon?.Show();
			}
			else
			{
				_icon?.Hide();
			}
			if (flag2 || _manualWidthControl)
			{
				float num9 = Mathf.Min(Time.deltaTime * 10f, 0.1f);
				if (!_manualWidthControl)
				{
					_manualDisplayedWidth = _extraBarStamina.sizeDelta.x;
				}
				_manualWidthControl = true;
				float num10 = (flag2 ? num8 : num7);
				_manualDisplayedWidth = Mathf.Lerp(_manualDisplayedWidth, num10, num9);
				_extraBarStamina.sizeDelta = new Vector2(_manualDisplayedWidth, _extraBarStamina.sizeDelta.y);
				if (!flag2 && Mathf.Abs(_manualDisplayedWidth - num7) < 0.5f)
				{
					_manualWidthControl = false;
				}
			}
			float num11 = _displayedDelta * fullLocalWidth;
			bool num12 = petrifyActive || petrifyGhostVisible;
			float num13 = (num12 ? fullLocalWidth : (num7 + num11));
			float num14 = Mathf.Max(20f, num13 + 12f);
			if (!_hasDisplayedOutlineWidth)
			{
				_displayedOutlineWidth = _extraBarOutline.sizeDelta.x;
				_hasDisplayedOutlineWidth = true;
			}
			float num15 = ((num14 > _displayedOutlineWidth) ? Mathf.Min(Time.deltaTime * 40f, 0.5f) : Mathf.Min(Time.deltaTime * 10f, 0.1f));
			_displayedOutlineWidth = Mathf.Lerp(_displayedOutlineWidth, num14, num15);
			_extraBarOutline.sizeDelta = new Vector2(_displayedOutlineWidth, _extraBarOutline.sizeDelta.y);
			_extraBarStamina.GetWorldCorners(_cornerBuffer);
			float x = _cornerBuffer[2].x;
			float num16 = Mathf.Min(3f, num11);
			float num17 = ((realExtraStamina > 0f) ? 1f : 9f);
			float num18 = (num12 ? 0f : Mathf.Min(num17, num11 + num16));
			_fillGhost.Apply(x - num16, num11 + num16 - num18);
			if (Plugin.Instance.Cfg.EnableWasteIndicator.Value && num6 > 0.0005f && Mathf.Max(0f, num) - num6 > 0.0005f)
			{
				_waste.Apply(_fillGhost.Rtf, _extraBarStamina, WasteIndicator.MeasureHeight(_extraBarStamina), rightEdge: true);
			}
			else
			{
				_waste.Hide();
			}
			if (Plugin.Instance.Cfg.ShowGhostBarCounts.Value && _displayedDelta > 0.0005f)
			{
				_ghostCountLabel.Apply(_fillGhost.Rtf, BarLabel.FormatCount(_displayedDelta), _ghostForeground, _ghostOutline, Plugin.Instance.Cfg.BarCountFontScale.Value);
			}
			else
			{
				_ghostCountLabel.Hide();
			}
			float afterExtraStamina = Mathf.Min(realExtraStamina + num6, num4);
			ApplyRealCountLabel(realExtraStamina, afterExtraStamina);
		}

		private void ApplyRealCountLabel(float realExtraStamina, float afterExtraStamina)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.Instance.Cfg.ShowVanillaBarCounts.Value && realExtraStamina > 0.0005f)
			{
				_realCountLabel.ApplyTransition(_extraBarStamina, realExtraStamina, afterExtraStamina, _vanillaForeground, _vanillaOutline, Plugin.Instance.Cfg.BarCountFontScale.Value);
			}
			else
			{
				_realCountLabel.Hide();
			}
		}

		internal void Hide()
		{
			Tween tween = _tween;
			if (tween != null)
			{
				TweenExtensions.Kill(tween, false);
			}
			_tween = null;
			_tweenTarget = 0f;
			_displayedDelta = 0f;
			_lastRealExtraStamina = 0f;
			_manualWidthControl = false;
			_hasDisplayedOutlineWidth = false;
			_fillGhost.Hide();
			_icon?.Hide();
			_waste.Hide();
			_ghostCountLabel.Hide();
			_realCountLabel.Hide();
		}
	}
	internal class GhostIcon
	{
		private readonly RectTransform _rtf;

		internal bool IsValid => (Object)(object)_rtf != (Object)null;

		private GhostIcon(RectTransform rtf)
		{
			_rtf = rtf;
		}

		internal static GhostIcon Create(Image template, Transform reparentTo = null)
		{
			//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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, ((Component)template).transform.parent);
			((Object)val).name = ((Object)template).name + " (EffectPreview Ghost)";
			if ((Object)(object)reparentTo != (Object)null)
			{
				val.transform.SetParent(reparentTo, true);
			}
			Image[] componentsInChildren = val.GetComponentsInChildren<Image>(true);
			foreach (Image obj in componentsInChildren)
			{
				Color color = Color.Lerp(((Graphic)obj).color, Color.white, 0.4f);
				color.a *= 0.65f;
				((Graphic)obj).color = color;
			}
			val.transform.localScale = Vector3.one;
			val.SetActive(false);
			return new GhostIcon(val.GetComponent<RectTransform>());
		}

		internal void Show()
		{
			Transform val = ((Component)_rtf).transform;
			while ((Object)(object)val != (Object)null && !((Component)val).gameObject.activeSelf)
			{
				((Component)val).gameObject.SetActive(true);
				val = val.parent;
			}
		}

		internal void Hide()
		{
			if ((Object)(object)_rtf != (Object)null)
			{
				((Component)_rtf).gameObject.SetActive(false);
			}
		}
	}
	internal class GhostInvincibilityShield
	{
		private readonly GameObject _ghost;

		internal bool IsValid => (Object)(object)_ghost != (Object)null;

		private GhostInvincibilityShield(GameObject ghost)
		{
			_ghost = ghost;
		}

		internal static GhostInvincibilityShield Create(GameObject realShield)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(realShield, realShield.transform.parent);
			((Object)val).name = ((Object)realShield).name + " (EffectPreview Ghost)";
			Image[] componentsInChildren = val.GetComponentsInChildren<Image>(true);
			foreach (Image obj in componentsInChildren)
			{
				Color color = Color.Lerp(((Graphic)obj).color, Color.white, 0.4f);
				color.a *= 0.65f;
				((Graphic)obj).color = color;
			}
			val.transform.SetAsLastSibling();
			val.SetActive(false);
			return new GhostInvincibilityShield(val);
		}

		internal void Apply(bool show, bool realActive)
		{
			_ghost.SetActive(show && !realActive);
		}

		internal void Hide()
		{
			if ((Object)(object)_ghost != (Object)null)
			{
				_ghost.SetActive(false);
			}
		}
	}
	internal class GhostJetpackFuelGauge : MonoBehaviour
	{
		private BackpackWheel _wheel;

		private Transform _sourceArrow;

		private RectTransform _ghostRtf;

		private void LateUpdate()
		{
			if (!Plugin.Instance.Cfg.EnablePreview.Value || !TryGetWheel())
			{
				Hide();
			}
			else
			{
				Safe.Run("GhostJetpackFuelGauge.Refresh", Refresh);
			}
		}

		private bool TryGetWheel()
		{
			GUIManager instance = GUIManager.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.backpackWheel == (Object)null)
			{
				return false;
			}
			_wheel = instance.backpackWheel;
			return true;
		}

		private void Refresh()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			if (!((Component)_wheel).gameObject.activeSelf || (int)_wheel.backpackType != 3 || (Object)(object)_wheel.fuelGaugeArrow == (Object)null || !_wheel.chosenSlice.IsSome || !_wheel.chosenSlice.Value.isJetpackFuelSlice)
			{
				Hide();
				return;
			}
			Character localCharacter = Character.localCharacter;
			Item val = (((Object)(object)localCharacter != (Object)null) ? localCharacter.data.currentItem : null);
			if ((Object)(object)val == (Object)null)
			{
				Hide();
				return;
			}
			if ((Object)(object)_ghostRtf == (Object)null || (Object)(object)_sourceArrow != (Object)(object)_wheel.fuelGaugeArrow)
			{
				Build(_wheel.fuelGaugeArrow);
			}
			if (!((Object)(object)_ghostRtf == (Object)null))
			{
				float num = 0f;
				ItemInstanceData itemInstanceData = ((BackpackReference)(ref _wheel.backpack)).GetItemInstanceData();
				FloatItemData val2 = default(FloatItemData);
				if (itemInstanceData != null && itemInstanceData.TryGetDataEntry<FloatItemData>((DataEntryKey)11, ref val2))
				{
					num = val2.Value;
				}
				int num2 = JetpackFuelPreviewCalculator.ComputeAddedFuel(val);
				float num3 = Mathf.Clamp01(num + (float)num2 / 100f);
				((Component)_ghostRtf).gameObject.SetActive(true);
				((Transform)_ghostRtf).position = _sourceArrow.position;
				((Transform)_ghostRtf).localRotation = Quaternion.Euler(0f, 0f, 50f - num3 * 100f);
			}
		}

		private void Build(Transform arrow)
		{
			//IL_003f: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			_sourceArrow = arrow;
			GameObject val = Object.Instantiate<GameObject>(((Component)arrow).gameObject, arrow.parent);
			((Object)val).name = ((Object)arrow).name + " (EffectPreview Ghost)";
			Image[] componentsInChildren = val.GetComponentsInChildren<Image>(true);
			foreach (Image obj in componentsInChildren)
			{
				Color color = Color.Lerp(((Graphic)obj).color, Color.white, 0.4f);
				color.a *= 0.65f;
				((Graphic)obj).color = color;
			}
			val.transform.localScale = Vector3.one;
			_ghostRtf = val.GetComponent<RectTransform>();
			val.SetActive(false);
		}

		private void Hide()
		{
			if ((Object)(object)_ghostRtf != (Object)null)
			{
				((Component)_ghostRtf).gameObject.SetActive(false);
			}
		}
	}
	internal class GhostPetrifyArea
	{
		private const float SeamOverlap = 6f;

		private const float RightEdgePadding = 6f;

		private const float HiddenThreshold = 0.0001f;

		private const float LerpRate = 10f;

		private const float MaxLerpStep = 0.1f;

		private const float IconHideDelay = 0.2f;

		private readonly RectTransform _petrifyRtf;

		private readonly GhostSegment _ghost;

		private readonly GhostSegment _decreaseGhost;

		private readonly GhostIcon _icon;

		private readonly WasteIndicator _increaseWaste;

		private readonly WasteIndicator _decreaseWaste;

		private readonly BarLabel _increaseCountLabel;

		private readonly BarLabel _decreaseCountLabel;

		private readonly BarLabel _realCountLabel;

		private readonly Color _vanillaForeground;

		private readonly Color _vanillaOutline;

		private readonly Color _ghostForeground;

		private readonly Color _ghostOutline;

		private readonly Vector3[] _cornerBuffer = (Vector3[])(object)new Vector3[4];

		private float _displayedDelta;

		private float _timeSinceTargetZero;

		private float _displayedShrinkWidth;

		internal bool IsValid
		{
			get
			{
				if ((Object)(object)_petrifyRtf != (Object)null && _ghost.IsValid && _decreaseGhost.IsValid && (_icon == null || _icon.IsValid) && _increaseWaste.IsValid && _decreaseWaste.IsValid && _increaseCountLabel.IsValid && _decreaseCountLabel.IsValid)
				{
					return _realCountLabel.IsValid;
				}
				return false;
			}
		}

		internal float DisplayedDelta => _displayedDelta;

		internal GhostPetrifyArea(BarAffliction petrifyAffliction, TMP_FontAsset font, Material fontMaterial)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_0114: 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)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			_petrifyRtf = petrifyAffliction.rtf;
			_ghost = GhostSegment.Create(((Transform)_petrifyRtf).parent, _petrifyRtf);
			_decreaseGhost = GhostSegment.Create(((Transform)_petrifyRtf).parent, _petrifyRtf, isRemoval: true);
			_icon = (((Object)(object)petrifyAffliction.icon != (Object)null) ? GhostIcon.Create(petrifyAffliction.icon, ((Transform)_petrifyRtf).parent) : null);
			Color val = WasteIndicator.SampleFillColor(((Component)_petrifyRtf).gameObject, petrifyAffliction.icon);
			_increaseWaste = WasteIndicator.Create(((Transform)_petrifyRtf).parent, val);
			_decreaseWaste = WasteIndicator.Create(((Transform)_petrifyRtf).parent, val);
			_increaseCountLabel = BarLabel.Create(((Transform)_petrifyRtf).parent, font, fontMaterial);
			_decreaseCountLabel = BarLabel.Create(((Transform)_petrifyRtf).parent, font, fontMaterial);
			_realCountLabel = BarLabel.Create(((Transform)_petrifyRtf).parent, font, fontMaterial);
			_vanillaForeground = val;
			_vanillaForeground.a = 1f;
			_vanillaOutline = ColorUtil.Darken(_vanillaForeground);
			_ghostForeground = BarLabel.GhostTint(val);
			_ghostOutline = ColorUtil.Darken(_ghostForeground);
		}

		internal void Apply(float fullLocalWidth, float delta, float rawDelta, float shrinkDelta, float currentPetrifyFraction, bool realPetrifyActive, float wasteHeight)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Min(Time.deltaTime * 10f, 0.1f);
			float num2 = Mathf.Clamp(shrinkDelta, 0f, currentPetrifyFraction);
			float num3 = fullLocalWidth * num2;
			_displayedShrinkWidth = Mathf.Lerp(_displayedShrinkWidth, num3, num);
			float currentPetrifyFraction2 = currentPetrifyFraction;
			if (num2 > 0.0001f || _displayedShrinkWidth > 0.5f)
			{
				float num4 = fullLocalWidth * currentPetrifyFraction;
				float num5 = Mathf.Max(0f, num4 - _displayedShrinkWidth);
				currentPetrifyFraction2 = ((fullLocalWidth > 0f) ? (num5 / fullLocalWidth) : currentPetrifyFraction);
				((Component)_petrifyRtf).gameObject.SetActive(true);
				_petrifyRtf.sizeDelta = new Vector2(num5, _petrifyRtf.sizeDelta.y);
				_petrifyRtf.GetWorldCorners(_cornerBuffer);
				float num6 = _cornerBuffer[2].x - num4;
				_decreaseGhost.Apply(num6 + _displayedShrinkWidth, _displayedShrinkWidth);
				if (Plugin.Instance.Cfg.EnableWasteIndicator.Value && num2 > 0.0005f && shrinkDelta - num2 > 0.0005f)
				{
					_decreaseWaste.Apply(_decreaseGhost.Rtf, _petrifyRtf, wasteHeight, rightEdge: false);
				}
				else
				{
					_decreaseWaste.Hide();
				}
				if (Plugin.Instance.Cfg.ShowGhostBarCounts.Value && _displayedShrinkWidth > 0.5f)
				{
					_decreaseCountLabel.Apply(_decreaseGhost.Rtf, BarLabel.FormatCount(num2), _ghostForeground, _ghostOutline, Plugin.Instance.Cfg.BarCountFontScale.Value);
				}
				else
				{
					_decreaseCountLabel.Hide();
				}
			}
			else
			{
				_displayedShrinkWidth = 0f;
				_decreaseGhost.Hide();
				_decreaseWaste.Hide();
				_decreaseCountLabel.Hide();
			}
			float num7 = ((delta > 0f) ? delta : 0f);
			_displayedDelta = Mathf.Lerp(_displayedDelta, num7, num);
			_timeSinceTargetZero = ((num7 > 0f) ? 0f : (_timeSinceTargetZero + Time.deltaTime));
			if (num7 <= 0f && _displayedDelta < 0.0001f)
			{
				_displayedDelta = 0f;
				_ghost.Hide();
				_icon?.Hide();
				_increaseWaste.Hide();
				_increaseCountLabel.Hide();
				ApplyRealCountLabel(currentPetrifyFraction2);
				return;
			}
			((Component)_petrifyRtf).gameObject.SetActive(true);
			if (!realPetrifyActive && (num7 > 0f || _timeSinceTargetZero < 0.2f))
			{
				_icon?.Show();
			}
			else
			{
				_icon?.Hide();
			}
			float num8 = _displayedDelta * fullLocalWidth;
			_petrifyRtf.GetWorldCorners(_cornerBuffer);
			float x = _cornerBuffer[0].x;
			float num9 = Mathf.Min(6f, num8);
			float num10 = Mathf.Min(6f, num8 + num9);
			float pivotWorldX = x + num9 - num10;
			float width = num8 + num9 - num10;
			_ghost.Apply(pivotWorldX, width);
			if (Plugin.Instance.Cfg.EnableWasteIndicator.Value && num7 > 0.0005f && Mathf.Max(0f, rawDelta) - num7 > 0.0005f)
			{
				_increaseWaste.Apply(_ghost.Rtf, _petrifyRtf, wasteHeight, rightEdge: false);
			}
			else
			{
				_increaseWaste.Hide();
			}
			if (Plugin.Instance.Cfg.ShowGhostBarCounts.Value && _displayedDelta > 0.0005f)
			{
				_increaseCountLabel.Apply(_ghost.Rtf, BarLabel.FormatCount(_displayedDelta), _ghostForeground, _ghostOutline, Plugin.Instance.Cfg.BarCountFontScale.Value);
			}
			else
			{
				_increaseCountLabel.Hide();
			}
			ApplyRealCountLabel(currentPetrifyFraction);
		}

		private void ApplyRealCountLabel(float currentPetrifyFraction)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.Instance.Cfg.ShowVanillaBarCounts.Value && currentPetrifyFraction > 0.0005f)
			{
				_realCountLabel.Apply(_petrifyRtf, BarLabel.FormatCount(currentPetrifyFraction), _vanillaForeground, _vanillaOutline, Plugin.Instance.Cfg.BarCountFontScale.Value);
			}
			else
			{
				_realCountLabel.Hide();
			}
		}

		internal void Hide()
		{
			_displayedDelta = 0f;
			_timeSinceTargetZero = 0.2f;
			_displayedShrinkWidth = 0f;
			_ghost.Hide();
			_decreaseGhost.Hide();
			_icon?.Hide();
			_increaseWaste.Hide();
			_decreaseWaste.Hide();
			_increaseCountLabel.Hide();
			_decreaseCountLabel.Hide();
			_realCountLabel.Hide();
		}
	}
	internal class GhostRainbowStamina
	{
		private const float PreviewAlpha = 0.3f;

		private const float FadeRate = 4f;

		private readonly Image _ghost;

		private float _displayedAlpha;

		internal bool IsValid => (Object)(object)_ghost != (Object)null;

		private GhostRainbowStamina(Image ghost)
		{
			_ghost = ghost;
		}

		internal static GhostRainbowStamina Create(Image realRainbow)
		{
			GameObject obj = Object.Instantiate<GameObject>(((Component)realRainbow).gameObject, ((Component)realRainbow).transform.parent);
			((Object)obj).name = ((Object)realRainbow).name + " (EffectPreview Ghost)";
			Image component = obj.GetComponent<Image>();
			((Behaviour)component).enabled = true;
			obj.transform.SetAsLastSibling();
			obj.SetActive(false);
			return new GhostRainbowStamina(component);
		}

		internal void Apply(bool show, bool realActive)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			float num = ((show && !realActive) ? 0.3f : 0f);
			_displayedAlpha = Mathf.MoveTowards(_displayedAlpha, num, Time.deltaTime * 4f);
			if (_displayedAlpha <= 0.001f)
			{
				Hide();
				return;
			}
			((Component)_ghost).gameObject.SetActive(true);
			Color color = ((Graphic)_ghost).color;
			color.a = _displayedAlpha;
			((Graphic)_ghost).color = color;
		}

		internal void Hide()
		{
			_displayedAlpha = 0f;
			if ((Object)(object)_ghost != (Object)null)
			{
				((Component)_ghost).gameObject.SetActive(false);
			}
		}
	}
	internal class GhostSegment
	{
		private readonly RectTransform _rtf;

		private readonly Image[] _images;

		private readonly float[] _baseAlphas;

		private readonly bool _isRemoval;

		internal bool IsValid => (Object)(object)_rtf != (Object)null;

		internal RectTransform Rtf => _rtf;

		private GhostSegment(RectTransform rtf, Image[] images, float[] baseAlphas, bool isRemoval)
		{
			_rtf = rtf;
			_images = images;
			_baseAlphas = baseAlphas;
			_isRemoval = isRemoval;
		}

		internal static GhostSegment Create(Transform ghostRoot, RectTransform template, bool isRemoval = false)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, ghostRoot);
			((Object)val).name = ((Object)template).name + " (EffectPreview Ghost)";
			RectTransform component = val.GetComponent<RectTransform>();
			BarAffliction component2 = val.GetComponent<BarAffliction>();
			if ((Object)(object)component2 != (Object)null)
			{
				if ((Object)(object)component2.icon != (Object)null)
				{
					((Component)component2.icon).gameObject.SetActive(false);
				}
				Object.Destroy((Object)(object)component2);
			}
			Image[] componentsInChildren = val.GetComponentsInChildren<Image>(true);
			float[] array = new float[componentsInChildren.Length];
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Color val2 = Color.Lerp(((Graphic)componentsInChildren[i]).color, Color.white, 0.4f);
				val2.a *= 0.65f;
				((Graphic)componentsInChildren[i]).color = val2;
				array[i] = val2.a;
			}
			val.SetActive(false);
			return new GhostSegment(component, componentsInChildren, array, isRemoval);
		}

		internal void Apply(float pivotWorldX, float width)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (width <= 0f)
			{
				Hide();
				return;
			}
			Vector3 position = ((Transform)_rtf).position;
			position.x = pivotWorldX;
			((Transform)_rtf).position = position;
			_rtf.sizeDelta = new Vector2(width, _rtf.sizeDelta.y);
			((Component)_rtf).gameObject.SetActive(true);
			if (_isRemoval)
			{
				RemovalPulse.Apply(_images, _baseAlphas);
			}
		}

		internal void Hide()
		{
			if ((Object)(object)_rtf != (Object)null)
			{
				((Component)_rtf).gameObject.SetActive(false);
			}
		}
	}
	internal class GhostStaminaArea
	{
		private const float LerpRate = 10f;

		private const float MaxLerpStep = 0.1f;

		private readonly RectTransform _maxRtf;

		private readonly RectTransform _curRtf;

		private bool _shrinking;

		private float _maxDisplayed;

		private float _curDisplayed;

		internal bool IsValid
		{
			get
			{
				if ((Object)(object)_maxRtf != (Object)null)
				{
					return (Object)(object)_curRtf != (Object)null;
				}
				return false;
			}
		}

		internal GhostStaminaArea(RectTransform maxStaminaBar, RectTransform staminaBar)
		{
			_maxRtf = maxStaminaBar;
			_curRtf = staminaBar;
		}

		internal void Apply(float fullLocalWidth, float trueMaxStamina, float trueCurrentStamina, float totalPositiveDelta, float maxAllowedWidthPx = float.MaxValue)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			if (totalPositiveDelta <= 0f && maxAllowedWidthPx >= fullLocalWidth)
			{
				Release();
				return;
			}
			float num = Mathf.Min(Time.deltaTime * 10f, 0.1f);
			float num2 = Mathf.Min(Mathf.Max(0f, trueMaxStamina * fullLocalWidth - totalPositiveDelta * fullLocalWidth), maxAllowedWidthPx);
			float num3 = Mathf.Min(trueCurrentStamina * fullLocalWidth, num2);
			if (!_shrinking)
			{
				_maxDisplayed = _maxRtf.sizeDelta.x;
				_curDisplayed = _curRtf.sizeDelta.x;
			}
			_shrinking = true;
			_maxDisplayed = Mathf.Lerp(_maxDisplayed, num2, num);
			_curDisplayed = Mathf.Lerp(_curDisplayed, num3, num);
			_maxRtf.sizeDelta = new Vector2(_maxDisplayed, _maxRtf.sizeDelta.y);
			_curRtf.sizeDelta = new Vector2(_curDisplayed, _curRtf.sizeDelta.y);
		}

		internal void Release()
		{
			_shrinking = false;
		}
	}
	internal static class RemovalPulse
	{
		private const float MinAlpha = 0.2f;

		private const float HoldAtFullDuration = 1.6f;

		private const float TransitionDuration = 0.3f;

		private const float HoldAtFloorDuration = 0.2f;

		private const float CycleDuration = 2.4f;

		internal static void Apply(Image[] images, float[] baseAlphas)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			float num = (Plugin.Instance.Cfg.EnableRemovalBlink.Value ? Factor(Time.time % 2.4f) : 1f);
			for (int i = 0; i < images.Length; i++)
			{
				if (!((Object)(object)images[i] == (Object)null))
				{
					float num2 = Mathf.Min(0.2f, baseAlphas[i]);
					Color color = ((Graphic)images[i]).color;
					color.a = Mathf.Lerp(num2, baseAlphas[i], num);
					((Graphic)images[i]).color = color;
				}
			}
		}

		private static float Factor(float t)
		{
			if (t < 1.6f)
			{
				return 1f;
			}
			t -= 1.6f;
			if (t < 0.3f)
			{
				return 1f - Smooth(t / 0.3f);
			}
			t -= 0.3f;
			if (t < 0.2f)
			{
				return 0f;
			}
			t -= 0.2f;
			return Smooth(t / 0.3f);
		}

		private static float Smooth(float t)
		{
			return t * t * (3f - 2f * t);
		}
	}
	internal class WasteIndicator
	{
		private const float Width = 3f;

		private const float LeftEdgeInset = 2f;

		private const float RightEdgeInset = 3f;

		private static readonly Vector3[] MeasureBuffer = (Vector3[])(object)new Vector3[4];

		private readonly RectTransform _rtf;

		private readonly Vector3[] _edgeCorners = (Vector3[])(object)new Vector3[4];

		private readonly Vector3[] _centerCorners = (Vector3[])(object)new Vector3[4];

		internal bool IsValid => (Object)(object)_rtf != (Object)null;

		private WasteIndicator(RectTransform rtf)
		{
			_rtf = rtf;
		}

		internal static WasteIndicator Create(Transform parent, Color color)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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)
			GameObject val = new GameObject("EffectPreview WasteIndicator", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(LayoutElement)
			});
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent(parent, false);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			val2.pivot = val3;
			Vector2 anchorMin = (val2.anchorMax = val3);
			val2.anchorMin = anchorMin;
			val.GetComponent<LayoutElement>().ignoreLayout = true;
			Image component = val.GetComponent<Image>();
			color.a = 1f;
			((Graphic)component).color = color;
			((Graphic)component).raycastTarget = false;
			val.SetActive(false);
			return new WasteIndicator(val2);
		}

		internal static Color SampleFillColor(GameObject root, Image excludeIcon)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			Image[] componentsInChildren = root.GetComponentsInChildren<Image>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)(object)excludeIcon)
				{
					return ((Graphic)componentsInChildren[i]).color;
				}
			}
			if (!((Object)(object)excludeIcon != (Object)null))
			{
				return Color.white;
			}
			return ((Graphic)excludeIcon).color;
		}

		internal static float MeasureHeight(RectTransform rtf)
		{
			rtf.GetWorldCorners(MeasureBuffer);
			return MeasureBuffer[1].y - MeasureBuffer[0].y;
		}

		internal void Apply(RectTransform edgeRtf, RectTransform centerRtf, float height, bool rightEdge)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)edgeRtf == (Object)null || !((Component)edgeRtf).gameObject.activeInHierarchy || (Object)(object)centerRtf == (Object)null)
			{
				Hide();
				return;
			}
			edgeRtf.GetWorldCorners(_edgeCorners);
			centerRtf.GetWorldCorners(_centerCorners);
			float num = (rightEdge ? _edgeCorners[2].x : _edgeCorners[0].x);
			num += (rightEdge ? (-3f) : 2f);
			float y = (_centerCorners[0].y + _centerCorners[1].y) * 0.5f;
			((Component)_rtf).gameObject.SetActive(true);
			((Transform)_rtf).SetAsLastSibling();
			_rtf.sizeDelta = new Vector2(3f, height);
			Vector3 position = ((Transform)_rtf).position;
			position.x = num;
			position.y = y;
			((Transform)_rtf).position = position;
		}

		internal void Hide()
		{
			if ((Object)(object)_rtf != (Object)null)
			{
				((Component)_rtf).gameObject.SetActive(false);
			}
		}
	}
}
namespace EffectPreview.Preview
{
	internal static class CampfirePreviewCalculator
	{
		private const float InjuryReduction = 0.2f;

		private const float PetrifyReduction = 0.2f;

		internal static ItemPreview Compute(Campfire campfire)
		{
			ItemPreview itemPreview = new ItemPreview();
			if ((Object)(object)campfire == (Object)null)
			{
				return itemPreview;
			}
			itemPreview.ExtraStaminaDelta += campfire.moraleBoostBaseline;
			itemPreview.AddStatus((STATUSTYPE)0, -0.2f);
			itemPreview.PetrifyReductionOnUse += 0.2f;
			return itemPreview;
		}
	}
	internal static class CookingPreviewCalculator
	{
		private const float PoisonPerCookAtStage4Plus = 0.1f;

		private const float HungerRestorationDecayPastStage2 = 0.05f;

		private const float MinExtraStaminaAtStage1 = 0.1f;

		internal static bool CanPreviewNextStage(Item item)
		{
			ItemCooking val = (((Object)(object)item != (Object)null) ? item.cooking : null);
			if ((Object)(object)val == (Object)null || !val.canBeCooked || val.wreckWhenCooked)
			{
				return false;
			}
			return val.timesCookedLocal < 12;
		}

		internal static ItemPreview Compute(Item item, Character character)
		{
			if ((Object)(object)item == (Object)null || (Object)(object)character == (Object)null || !CanPreviewNextStage(item))
			{
				return new ItemPreview();
			}
			ItemCooking cooking = item.cooking;
			int num = cooking.timesCookedLocal + 1;
			bool isSkeleton = character.data.isSkeleton;
			Func<ItemAction, bool> isActionActive = BuildNextStageActiveOverride(cooking, num);
			ItemPreview itemPreview = ItemPreviewCalculator.Compute(item, character, isActionActive);
			if (cooking.ignoreDefaultCookBehavior)
			{
				return itemPreview;
			}
			if (WouldExplodeOnNextCook(cooking, num))
			{
				return itemPreview;
			}
			if (!ItemPreviewCalculator.CanEverConsumeItem(item, isActionActive))
			{
				return itemPreview;
			}
			Action_RestoreHunger componentInChildren = ((Component)item).GetComponentInChildren<Action_RestoreHunger>();
			if ((Object)(object)componentInChildren != (Object)null && !isSkeleton)
			{
				float num2 = componentInChildren.restorationAmount;
				if (num < 2)
				{
					num2 *= 2f;
				}
				else if (num > 2)
				{
					num2 = Mathf.Max(num2 - 0.05f, 0f);
				}
				AdjustStatusDecrease(itemPreview, (STATUSTYPE)1, num2 - componentInChildren.restorationAmount);
			}
			Action_GiveExtraStamina componentInChildren2 = ((Component)item).GetComponentInChildren<Action_GiveExtraStamina>();
			float num3 = (((Object)(object)componentInChildren2 != (Object)null) ? componentInChildren2.amount : 0f);
			float num4 = num3;
			if (num < 2)
			{
				num4 = Mathf.Max(0.1f, num3 * 1.5f);
			}
			else if (num > 2)
			{
				num4 = 0f;
			}
			itemPreview.ExtraStaminaDelta += num4 - num3;
			if (num >= 4 && !cooking.ignoreDefaultPoisonBehavior && !isSkeleton)
			{
				itemPreview.AddStatus((STATUSTYPE)3, 0.1f);
			}
			return itemPreview;
		}

		private static bool WouldExplodeOnNextCook(ItemCooking cooking, int nextCookedAmount)
		{
			if (cooking.additionalCookingBehaviors == null)
			{
				return false;
			}
			AdditionalCookingBehavior[] additionalCookingBehaviors = cooking.additionalCookingBehaviors;
			foreach (AdditionalCookingBehavior val in additionalCookingBehaviors)
			{
				if (val is CookingBehavior_Explode && cooking.timesCookedLocal < val.cookedAmountToTrigger && nextCookedAmount >= val.cookedAmountToTrigger)
				{
					return true;
				}
			}
			return false;
		}

		private static Func<ItemAction, bool> BuildNextStageActiveOverride(ItemCooking cooking, int nextCookedAmount)
		{
			if (cooking.additionalCookingBehaviors == null || cooking.additionalCookingBehaviors.Length == 0)
			{
				return null;
			}
			HashSet<ItemAction> forceDisabled = null;
			HashSet<ItemAction> forceEnabled = null;
			AdditionalCookingBehavior[] additionalCookingBehaviors = cooking.additionalCookingBehaviors;
			foreach (AdditionalCookingBehavior val in additionalCookingBehaviors)
			{
				if (val == null || cooking.timesCookedLocal >= val.cookedAmountToTrigger || nextCookedAmount < val.cookedAmountToTrigger)
				{
					continue;
				}
				CookingBehavior_DisableScripts val2 = (CookingBehavior_DisableScripts)(object)((val is CookingBehavior_DisableScripts) ? val : null);
				MonoBehaviour[] scriptsToDisable;
				if (val2 != null && val2.scriptsToDisable != null)
				{
					scriptsToDisable = val2.scriptsToDisable;
					foreach (MonoBehaviour obj in scriptsToDisable)
					{
						ItemAction val3 = (ItemAction)(object)((obj is ItemAction) ? obj : null);
						if (val3 != null)
						{
							(forceDisabled ?? (forceDisabled = new HashSet<ItemAction>())).Add(val3);
						}
					}
					continue;
				}
				CookingBehavior_EnableScripts val4 = (CookingBehavior_EnableScripts)(object)((val is CookingBehavior_EnableScripts) ? val : null);
				if (val4 == null || val4.scriptsToEnable == null)
				{
					continue;
				}
				scriptsToDisable = val4.scriptsToEnable;
				foreach (MonoBehaviour obj2 in scriptsToDisable)
				{
					ItemAction val5 = (ItemAction)(object)((obj2 is ItemAction) ? obj2 : null);
					if (val5 != null)
					{
						(forceEnabled ?? (forceEnabled = new HashSet<ItemAction>())).Add(val5);
					}
				}
			}
			if (forceDisabled == null && forceEnabled == null)
			{
				return null;
			}
			return delegate(ItemAction action)
			{
				if (forceDisabled != null && forceDisabled.Contains(action))
				{
					return false;
				}
				if (forceEnabled != null && forceEnabled.Contains(action))
				{
					return true;
				}
				return ((Behaviour)action).enabled && ((Component)action).gameObject.activeInHierarchy;
			};
		}

		private static void AdjustStatusDecrease(ItemPreview preview, STATUSTYPE type, float delta)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (delta != 0f)
			{
				preview.StatusDecreases.TryGetValue(type, out var value);
				float num = value + delta;
				if (num <= 0f)
				{
					preview.StatusDecreases.Remove(type);
				}
				else
				{
					preview.StatusDecreases[type] = num;
				}
			}
		}
	}
	internal static class DynamicPetrifyPreview
	{
		private static readonly STATUSTYPE[] HealOrder;

		internal static void ComputeHealBreakdown(ItemPreview preview, Character localCharacter, Dictionary<STATUSTYPE, float> buffer)
		{
			//IL_003b: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			Action_HealingGem healingGemAction = preview.HealingGemAction;
			if ((Object)(object)healingGemAction == (Object)null || healingGemAction.healingAffliction == null || (Object)(object)localCharacter == (Object)null)
			{
				return;
			}
			float num = healingGemAction.healingAffliction.maxHealing;
			STATUSTYPE[] healOrder = HealOrder;
			foreach (STATUSTYPE val in healOrder)
			{
				if (!(num <= 0f))
				{
					float currentStatus = localCharacter.refs.afflictions.GetCurrentStatus(val);
					if (currentStatus > 0f)
					{
						float num2 = (buffer[val] = Mathf.Min(currentStatus, num));
						num -= num2;
					}
					continue;
				}
				break;
			}
		}

		internal static float Compute(ItemPreview preview, Character localCharacter)
		{
			float num = 0f;
			if ((Object)(object)preview.CloneItemAction != (Object)null)
			{
				num += ComputeClone(preview.CloneItemAction);
			}
			if ((Object)(object)preview.HealingGemAction != (Object)null && (Object)(object)localCharacter != (Object)null)
			{
				num += ComputeHealingGem(preview.HealingGemAction, localCharacter);
			}
			return num;
		}

		private static float ComputeClone(Action_CloneSelectedItem action)
		{
			//IL_0037: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Interaction.instance == (Object)null)
			{
				return 0f;
			}
			IInteractible val = default(IInteractible);
			Interaction.instance.DoInteractableRaycasts(ref val, action.range, false);
			Item val2 = (Item)(object)((val is Item) ? val : null);
			if (val2 == null)
			{
				return 0f;
			}
			if (((Enum)val2.itemTags).HasFlag((Enum)(object)(ItemTags)512) || ((Enum)val2.itemTags).HasFlag((Enum)(object)(ItemTags)2048))
			{
				return 0f;
			}
			return (float)(((Enum)val2.itemTags).HasFlag((Enum)(object)(ItemTags)1) ? action.petrifyMystical : action.petrify) / 100f;
		}

		private static float ComputeHealingGem(Action_HealingGem action, Character localCharacter)
		{
			if (action.healingAffliction == null)
			{
				return 0f;
			}
			Character val = localCharacter;
			if ((Object)(object)Interaction.instance != (Object)null && Interaction.instance.hasValidTargetCharacter)
			{
				IInteractible val2 = default(IInteractible);
				Interaction.instance.DoInteractableRaycasts(ref val2, -1f, false);
				CharacterInteractible val3 = (CharacterInteractible)(object)((val2 is CharacterInteractible) ? val2 : null);
				if (val3 != null && (Object)(object)val3.character != (Object)null && (Object)(object)val3.character != (Object)(object)localCharacter)
				{
					val = val3.character;
				}
			}
			return Mathf.Clamp(Affliction_HealAll.GetTotalPotentialHeal(val, action.healingAffliction.maxHealing) * action.healingToPetrifyRatio, action.minPetrify, action.maxPetrify);
		}

		static DynamicPetrifyPreview()
		{
			STATUSTYPE[] array = new STATUSTYPE[6];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			HealOrder = (STATUSTYPE[])(object)array;
		}
	}
	internal class HeldItemPreviewTracker : MonoBehaviour
	{
		private Item _lastItem;

		private int _lastCookedAmount;

		private int _lastUses;

		private bool _lastCookingPreviewActive;

		private Object _lastEmptyHandedSource;

		private bool _lastEmptyHandedSourceValid;

		internal static HeldItemPreviewTracker Instance { get; private set; }

		internal ItemPreview Current { get; private set; } = new ItemPreview();

		private void Awake()
		{
			Instance = this;
		}

		private void Update()
		{
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.Instance.Cfg.EnablePreview.Value)
			{
				return;
			}
			Character character = Character.localCharacter;
			Item item = (((Object)(object)character != (Object)null) ? character.data.currentItem : null);
			if ((Object)(object)item != (Object)null && item.consuming)
			{
				Current = new ItemPreview();
				_lastItem = item;
				_lastCookedAmount = 0;
				_lastUses = 0;
				_lastCookingPreviewActive = false;
				_lastEmptyHandedSource = null;
				_lastEmptyHandedSourceValid = false;
				return;
			}
			if ((Object)(object)item == (Object)null)
			{
				UpdateEmptyHandedPreview(character);
				return;
			}
			_lastEmptyHandedSource = null;
			_lastEmptyHandedSourceValid = false;
			IntItemData val = default(IntItemData);
			int num = ((item.data != null && item.data.TryGetDataEntry<IntItemData>((DataEntryKey)1, ref val)) ? val.Value : 0);
			OptionableIntItemData val2 = default(OptionableIntItemData);
			int num2 = ((item.data != null && item.data.TryGetDataEntry<OptionableIntItemData>((DataEntryKey)2, ref val2)) ? val2.Value : 0);
			bool cookingPreviewActive = Plugin.Instance.Cfg.EnableCookingPreview.Value && Input.GetKey(Plugin.Instance.Cfg.CookingPreviewKey.Value) && IsAbleToCookHeldItem(item, character);
			if (item != _lastItem || num != _lastCookedAmount || num2 != _lastUses || cookingPreviewActive != _lastCookingPreviewActive)
			{
				_lastItem = item;
				_lastCookedAmount = num;
				_lastUses = num2;
				_lastCookingPreviewActive = cookingPreviewActive;
				Safe.Run("HeldItemPreviewTracker.Compute", delegate
				{
					Current = (cookingPreviewActive ? CookingPreviewCalculator.Compute(item, character) : ItemPreviewCalculator.Compute(item, character));
				});
			}
		}

		private bool IsAbleToCookHeldItem(Item item, Character character)
		{
			if (!CookingPreviewCalculator.CanPreviewNextStage(item))
			{
				return false;
			}
			Interaction instance = Interaction.instance;
			IInteractible obj = (((Object)(object)instance != (Object)null) ? instance.currentHovered : null);
			Campfire val = (Campfire)(object)((obj is Campfire) ? obj : null);
			if (val != null)
			{
				return val.Lit;
			}
			return false;
		}

		private void UpdateEmptyHandedPreview(Character character)
		{
			_lastItem = null;
			_lastCookedAmount = 0;
			_lastUses = 0;
			Object source = TryGetEmptyHandedPreviewSource(character);
			if (_lastEmptyHandedSourceValid && source == _lastEmptyHandedSource)
			{
				return;
			}
			_lastEmptyHandedSource = source;
			_lastEmptyHandedSourceValid = true;
			Safe.Run("HeldItemPreviewTracker.ComputeEmptyHanded", delegate
			{
				Object obj = source;
				Campfire val = (Campfire)(object)((obj is Campfire) ? obj : null);
				if (val != null)
				{
					Current = CampfirePreviewCalculator.Compute(val);
				}
				else
				{
					Object obj2 = source;
					Luggage val2 = (Luggage)(object)((obj2 is Luggage) ? obj2 : null);
					if (val2 != null)
					{
						Current = LuggagePreviewCalculator.Compute(val2);
					}
					else
					{
						Object obj3 = source;
						ThornOnMe val3 = (ThornOnMe)(object)((obj3 is ThornOnMe) ? obj3 : null);
						if (val3 != null)
						{
							Current = ThornPreviewCalculator.Compute(val3);
						}
						else
						{
							Current = new ItemPreview();
						}
					}
				}
			});
		}

		private static Object TryGetEmptyHandedPreviewSource(Character character)
		{
			if ((Object)(object)character == (Object)null)
			{
				return null;
			}
			Interaction instance = Interaction.instance;
			IInteractible val = (((Object)(object)instance != (Object)null) ? instance.currentHovered : null);
			if (Plugin.Instance.Cfg.EnableWorldObjectPreviews.Value)
			{
				Campfire val2 = (Campfire)(object)((val is Campfire) ? val : null);
				if (val2 != null && IsLightableCampfire(val2))
				{
					return (Object)(object)val2;
				}
				Luggage val3 = (Luggage)(object)((val is Luggage) ? val : null);
				if (val3 != null && IsOpenableLuggage(val3))
				{
					return (Object)(object)val3;
				}
			}
			if (Plugin.Instance.Cfg.EnablePlayerEntityPreviews.Value)
			{
				ThornOnMe val4 = (ThornOnMe)(object)((val is ThornOnMe) ? val : null);
				if (val4 != null && IsRemovableOwnThorn(val4, character))
				{
					return (Object)(object)val4;
				}
			}
			return null;
		}

		private static bool IsLightableCampfire(Campfire campfire)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if ((int)campfire.state != 0)
			{
				return false;
			}
			return campfire.EveryoneInRange();
		}

		private static bool IsOpenableLuggage(Luggage luggage)
		{
			return luggage.IsInteractible(Character.localCharacter);
		}

		private static bool IsRemovableOwnThorn(ThornOnMe thorn, Character character)
		{
			if (!thorn.stuckIn || (Object)(object)thorn.character != (Object)(object)character)
			{
				return false;
			}
			return thorn.IsInteractible(character);
		}
	}
	internal class ItemPreview
	{
		internal readonly Dictionary<STATUSTYPE, float> StatusIncreases = new Dictionary<STATUSTYPE, float>();

		internal readonly Dictionary<STATUSTYPE, float> StatusDecreases = new Dictionary<STATUSTYPE, float>();

		internal float ExtraStaminaDelta;

		internal float PetrifyDelta;

		internal Action_CloneSelectedItem CloneItemAction;

		internal