Decompiled source of PeakSuite v1.1.2

plugins/RayShadow.PeakSuite.dll

Decompiled an hour ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak;
using Peak.Afflictions;
using PeakSuite.Core;
using PeakSuite.Core.Settings;
using PeakSuite.Features.BalloonMerge;
using PeakSuite.Features.CampfireRest;
using PeakSuite.Features.CarryTeammate;
using PeakSuite.Features.InfoPanel;
using PeakSuite.Features.ItemStats;
using PeakSuite.Features.OwnBackpack;
using PeakSuite.Features.PlayerLocator;
using PeakSuite.Features.Scoreboard;
using PeakSuite.Features.StaminaNumbers;
using PeakSuite.Features.TeammateStatus;
using PeakSuite.Features.ThrowPreview;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;
using Zorro.Core.Serizalization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RayShadow.PeakSuite")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.2.0")]
[assembly: AssemblyInformationalVersion("1.1.2+82035020d071ab98cb61d9713b0d7c3dee4679d9")]
[assembly: AssemblyProduct("RayShadow.PeakSuite")]
[assembly: AssemblyTitle("PeakSuite")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace PeakSuite
{
	[BepInPlugin("RayShadow.PeakSuite", "PeakSuite", "1.1.2")]
	public class Plugin : BaseUnityPlugin
	{
		private static Harmony? sharedHarmony;

		private readonly Harmony harmony = new Harmony("RayShadow.PeakSuite");

		public const string Id = "RayShadow.PeakSuite";

		internal static ManualLogSource Log { get; private set; } = null;

		internal static IReadOnlyList<Feature> Features { get; private set; } = Array.Empty<Feature>();

		internal static ConfigEntry<Key> SettingsKey { get; private set; } = null;

		public static string Name => "PeakSuite";

		public static string Version => "1.1.2";

		internal static void EnsureApplied(Feature feature)
		{
			if (feature.IsApplied || sharedHarmony == null)
			{
				return;
			}
			try
			{
				feature.ApplyOnce(sharedHarmony);
				Log.LogInfo((object)("[" + feature.Id + "] enabled from the settings window."));
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"[{feature.Id}] failed to apply: {arg}");
			}
		}

		private void Awake()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			sharedHarmony = harmony;
			HudStyle.Bind(((BaseUnityPlugin)this).Config);
			SettingsKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Settings", "Key", (Key)97, new ConfigDescription("Key that opens the PeakSuite settings window, with a mouse cursor.", (AcceptableValueBase)null, new object[1]
			{
				new SettingLabel("設定視窗按鍵")
			}));
			List<Feature> list = new List<Feature>
			{
				new StaminaNumbersFeature(),
				new PlayerLocatorFeature(),
				new CampfireRestFeature(),
				new OwnBackpackFeature(),
				new BalloonMergeFeature(),
				new ItemStatsFeature(),
				new TeammateStatusFeature(),
				new CarryTeammateFeature(),
				new InfoPanelFeature(),
				new ScoreboardFeature(),
				new ThrowPreviewFeature()
			};
			foreach (Feature item in list)
			{
				InitializeFeature(item);
			}
			Features = list;
			HudRoot.Install(harmony);
			SettingsHost.Create(((BaseUnityPlugin)this).Config, harmony);
			Log.LogInfo((object)$"{Name} {Version} loaded with {list.Count} features.");
		}

		private void InitializeFeature(Feature feature)
		{
			try
			{
				feature.Bind(((BaseUnityPlugin)this).Config);
				if (!feature.Enabled.Value)
				{
					Log.LogInfo((object)("[" + feature.Id + "] disabled in config, patches skipped."));
					return;
				}
				feature.ApplyOnce(harmony);
				Log.LogInfo((object)("[" + feature.Id + "] enabled."));
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"[{feature.Id}] failed to initialize and is skipped: {arg}");
			}
		}
	}
}
namespace PeakSuite.Features.ThrowPreview
{
	internal static class ThrowAccuracyLog
	{
		private readonly struct Aim
		{
			public string ItemName { get; }

			public float Charge { get; }

			public Vector3? Point { get; }

			public float FlightSeconds { get; }

			public VinePrediction? Vine { get; }

			public float At { get; }

			public Aim(string itemName, float charge, Vector3? point, float flightSeconds, VinePrediction? vine, float at)
			{
				ItemName = itemName;
				Charge = charge;
				Point = point;
				FlightSeconds = flightSeconds;
				Vine = vine;
				At = at;
			}
		}

		private readonly struct Flight
		{
			public Item Item { get; }

			public Aim Aim { get; }

			public float SpawnedAt { get; }

			public bool HasLanded { get; }

			public Flight(Item item, Aim aim, float spawnedAt, bool hasLanded = false)
			{
				Item = item;
				Aim = aim;
				SpawnedAt = spawnedAt;
				HasLanded = hasLanded;
			}

			public Flight? WithLanded()
			{
				if (!Aim.Vine.HasValue)
				{
					return null;
				}
				return new Flight(Item, Aim, SpawnedAt, hasLanded: true);
			}
		}

		private const float ReleaseWindowSeconds = 0.5f;

		private static Aim? lastAim;

		private static Flight? flight;

		public static void Aimed(string itemName, float charge, ThrowImpact? impact, float flightSeconds, VinePrediction? vine)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			lastAim = new Aim(itemName, charge, impact?.Point, flightSeconds, vine, Time.time);
		}

		public static void Spawned(Item item)
		{
			if ((Object)(object)item.lastThrownCharacter == (Object)null || (Object)(object)item.lastThrownCharacter != (Object)(object)Character.localCharacter)
			{
				return;
			}
			Aim? aim = lastAim;
			if (aim.HasValue)
			{
				Aim valueOrDefault = aim.GetValueOrDefault();
				if (!(Time.time - valueOrDefault.At > 0.5f))
				{
					lastAim = null;
					flight = new Flight(item, valueOrDefault, Time.time);
				}
			}
		}

		public static void Collided(Item? item, Collision collision)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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)
			//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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			Flight? flight = ThrowAccuracyLog.flight;
			if (!flight.HasValue)
			{
				return;
			}
			Flight valueOrDefault = flight.GetValueOrDefault();
			if (!valueOrDefault.HasLanded && !((Object)(object)item == (Object)null) && !((Object)(object)item != (Object)(object)valueOrDefault.Item) && collision.contactCount != 0)
			{
				ThrowAccuracyLog.flight = valueOrDefault.WithLanded();
				Aim aim = valueOrDefault.Aim;
				float seconds = Time.time - valueOrDefault.SpawnedAt;
				ContactPoint contact = collision.GetContact(0);
				Vector3 point = ((ContactPoint)(ref contact)).point;
				Vector3? point2 = aim.Point;
				string text;
				if (point2.HasValue)
				{
					Vector3 valueOrDefault2 = point2.GetValueOrDefault();
					text = "landed " + Meters(Vector3.Distance(valueOrDefault2, point)) + " from the ring after " + Seconds(seconds) + " (predicted " + Seconds(aim.FlightSeconds) + ")";
				}
				else
				{
					text = "no landing was predicted within the simulated time; first contact after " + Seconds(seconds);
				}
				string text2 = text;
				Plugin.Log.LogInfo((object)("[ThrowPreview] Throw check: " + aim.ItemName + ", charge " + aim.Charge.ToString("F2", CultureInfo.InvariantCulture) + ", hit " + ((Object)collision.gameObject).name + " — " + text2 + "."));
			}
		}

		public static void Planted(MagicBean bean, in VinePrediction actual)
		{
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			Flight? flight = ThrowAccuracyLog.flight;
			if (!flight.HasValue)
			{
				return;
			}
			Flight valueOrDefault = flight.GetValueOrDefault();
			if (!((Object)(object)valueOrDefault.Item == (Object)null) && !((Object)(object)((ItemComponent)bean).item != (Object)(object)valueOrDefault.Item))
			{
				VinePrediction? vine = valueOrDefault.Aim.Vine;
				if (vine.HasValue)
				{
					VinePrediction valueOrDefault2 = vine.GetValueOrDefault();
					ThrowAccuracyLog.flight = null;
					Plugin.Log.LogInfo((object)("[ThrowPreview] Vine check: predicted " + Meters(valueOrDefault2.Length) + " " + Walk(valueOrDefault2.IsWalkable) + ", actual " + Meters(actual.Length) + " " + Walk(actual.IsWalkable) + ", directions " + Vector3.Angle(valueOrDefault2.Direction, actual.Direction).ToString("F1", CultureInfo.InvariantCulture) + "° apart, starts " + Meters(Vector3.Distance(valueOrDefault2.Start, actual.Start)) + " apart."));
				}
			}
		}

		private static string Meters(float units)
		{
			return HudFormat.WorldToMeters(units).ToString("F2", CultureInfo.InvariantCulture) + " m";
		}

		private static string Seconds(float seconds)
		{
			return seconds.ToString("F2", CultureInfo.InvariantCulture) + " s";
		}

		private static string Walk(bool isWalkable)
		{
			if (!isWalkable)
			{
				return "climb";
			}
			return "walkable";
		}
	}
	internal sealed class ThrowPreviewFeature : Feature
	{
		[HarmonyPatch]
		private static class Patches
		{
			[HarmonyPatch(typeof(Item), "RPC_SetThrownData")]
			[HarmonyPostfix]
			private static void AfterThrown(Item __instance)
			{
				PlantedBeans.Track(__instance);
				ThrowAccuracyLog.Spawned(__instance);
			}

			[HarmonyPatch(typeof(ItemImpactSFX), "OnCollisionEnter")]
			[HarmonyPostfix]
			private static void AfterImpact(ItemImpactSFX __instance, Collision collision)
			{
				ThrowAccuracyLog.Collided(__instance.item, collision);
			}
		}

		public override string Id => "ThrowPreview";

		public override string ChineseName => "投擲預測";

		protected override string Description => "While charging a throw, show where the item flies and lands; for a magic bean, the vine it would grow.";

		public static ConfigEntry<bool> HideHeldItem { get; private set; }

		public static ConfigEntry<bool> ShowVine { get; private set; }

		public static ConfigEntry<bool> ShowPlantedVine { get; private set; }

		protected override void BindOptions(ConfigFile config)
		{
			HideHeldItem = Bind(config, "HideHeldItem", defaultValue: true, "蓄力時隱藏手上物品", "Hide the item in your hand while charging, so it does not cover the start of the path.");
			ShowVine = Bind(config, "ShowVine", defaultValue: true, "顯示魔豆藤蔓", "Magic bean: show the vine it would grow where it lands, its length, and whether you can walk up it.");
			ShowPlantedVine = Bind(config, "ShowPlantedVine", defaultValue: true, "顯示已落地魔豆的藤蔓", "Show the vine a magic bean that already landed is about to grow (anyone's bean).");
		}

		protected override void Apply(Harmony harmony)
		{
			harmony.PatchAll(typeof(Patches));
			HudRoot.Created += delegate(RectTransform root, GUIManager _)
			{
				((Component)root).gameObject.AddComponent<ThrowPreviewView>().Initialize(root, this);
			};
		}
	}
	internal static class PlantedBeans
	{
		private static readonly List<MagicBean> Tracked = new List<MagicBean>();

		public static void Track(Item item)
		{
			MagicBean item2 = default(MagicBean);
			if (!((Object)(object)item == (Object)null) && ((Component)item).TryGetComponent<MagicBean>(ref item2) && !Tracked.Contains(item2))
			{
				Tracked.Add(item2);
			}
		}

		public static List<MagicBean> Alive()
		{
			Tracked.RemoveAll((MagicBean bean) => (Object)(object)bean == (Object)null);
			return Tracked;
		}
	}
	internal sealed class WorldLine
	{
		private const float HiddenAlpha = 0.3f;

		private static readonly int SrcBlendId = Shader.PropertyToID("_SrcBlend");

		private static readonly int DstBlendId = Shader.PropertyToID("_DstBlend");

		private static readonly int CullId = Shader.PropertyToID("_Cull");

		private static readonly int ZWriteId = Shader.PropertyToID("_ZWrite");

		private static readonly int ZTestId = Shader.PropertyToID("_ZTest");

		private static readonly int ColorId = Shader.PropertyToID("_Color");

		private static Material? frontMaterial;

		private static Material? behindMaterial;

		private static bool hasLookedForShader;

		private readonly GameObject host;

		private readonly LineRenderer front;

		private readonly LineRenderer? behind;

		private readonly float fadeIn;

		private readonly Gradient gradient = new Gradient();

		private Vector3[] buffer = (Vector3[])(object)new Vector3[64];

		private Color shownColor = Color.clear;

		private WorldLine(string name, float width, bool isLoop, float fadeIn, AnimationCurve? widthCurve)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_003d: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			this.fadeIn = fadeIn;
			host = new GameObject(name);
			front = AddLine(host, frontMaterial, width, isLoop, widthCurve);
			if ((Object)(object)behindMaterial != (Object)null)
			{
				GameObject val = new GameObject(name + "_Behind");
				val.transform.SetParent(host.transform, false);
				behind = AddLine(val, behindMaterial, width, isLoop, widthCurve);
			}
			host.SetActive(false);
		}

		public static WorldLine? Create(string name, float width, bool isLoop = false, float fadeIn = 0f, AnimationCurve? widthCurve = null)
		{
			FindMaterials();
			if (!((Object)(object)frontMaterial == (Object)null))
			{
				return new WorldLine(name, width, isLoop, fadeIn, widthCurve);
			}
			return null;
		}

		public static void Circle(Vector3 center, Vector3 normal, float radius, Vector3[] points)
		{
			//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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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)
			Vector3 val = Vector3.Cross(normal, (Mathf.Abs(normal.y) < 0.99f) ? Vector3.up : Vector3.right);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 val2 = Vector3.Cross(normal, normalized);
			for (int i = 0; i < points.Length; i++)
			{
				float num = (float)i * (MathF.PI * 2f / (float)points.Length);
				points[i] = center + (normalized * Mathf.Cos(num) + val2 * Mathf.Sin(num)) * radius;
			}
		}

		public void Show(List<Vector3> points, Color color)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (buffer.Length < points.Count)
			{
				buffer = (Vector3[])(object)new Vector3[Mathf.NextPowerOfTwo(points.Count)];
			}
			points.CopyTo(buffer);
			Show(buffer, points.Count, color);
		}

		public void Show(Vector3[] points, int count, Color color)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (count < 2)
			{
				Hide();
				return;
			}
			SetColor(HudStyle.WithOpacity(color));
			front.positionCount = count;
			front.SetPositions(points);
			if ((Object)(object)behind != (Object)null)
			{
				behind.positionCount = count;
				behind.SetPositions(points);
			}
			if (!host.activeSelf)
			{
				host.SetActive(true);
			}
		}

		public void Hide()
		{
			if ((Object)(object)host != (Object)null && host.activeSelf)
			{
				host.SetActive(false);
			}
		}

		public void Destroy()
		{
			if ((Object)(object)host != (Object)null)
			{
				Object.Destroy((Object)(object)host);
			}
		}

		private void SetColor(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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_0011: 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)
			//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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_00d7: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0037: 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)
			if (color == shownColor)
			{
				return;
			}
			shownColor = color;
			if (fadeIn <= 0f)
			{
				LineRenderer obj = front;
				Color startColor = (front.endColor = color);
				obj.startColor = startColor;
				if ((Object)(object)behind != (Object)null)
				{
					LineRenderer? obj2 = behind;
					startColor = (behind.endColor = color);
					obj2.startColor = startColor;
				}
				return;
			}
			gradient.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
			{
				new GradientColorKey(color, 0f),
				new GradientColorKey(color, 1f)
			}, (GradientAlphaKey[])(object)new GradientAlphaKey[3]
			{
				new GradientAlphaKey(0f, 0f),
				new GradientAlphaKey(color.a, fadeIn),
				new GradientAlphaKey(color.a, 1f)
			});
			front.colorGradient = gradient;
			if ((Object)(object)behind != (Object)null)
			{
				behind.colorGradient = gradient;
			}
		}

		private static LineRenderer AddLine(GameObject target, Material material, float width, bool isLoop, AnimationCurve? widthCurve)
		{
			LineRenderer val = target.AddComponent<LineRenderer>();
			((Renderer)val).sharedMaterial = material;
			val.useWorldSpace = true;
			val.loop = isLoop;
			val.widthMultiplier = width;
			if (widthCurve != null)
			{
				val.widthCurve = widthCurve;
			}
			val.numCapVertices = 3;
			val.numCornerVertices = 2;
			val.alignment = (LineAlignment)0;
			((Renderer)val).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)val).receiveShadows = false;
			((Renderer)val).lightProbeUsage = (LightProbeUsage)0;
			((Renderer)val).reflectionProbeUsage = (ReflectionProbeUsage)0;
			((Renderer)val).allowOcclusionWhenDynamic = false;
			val.positionCount = 0;
			return val;
		}

		private static void FindMaterials()
		{
			//IL_005a: 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)
			//IL_006c: Expected O, but got Unknown
			if (hasLookedForShader)
			{
				return;
			}
			hasLookedForShader = true;
			Shader val = Shader.Find("Hidden/Internal-Colored");
			if ((Object)(object)val != (Object)null)
			{
				frontMaterial = ColoredMaterial(val, (CompareFunction)4, 1f);
				behindMaterial = ColoredMaterial(val, (CompareFunction)5, 0.3f);
				return;
			}
			Shader val2 = Shader.Find("Sprites/Default");
			if ((Object)(object)val2 != (Object)null)
			{
				frontMaterial = new Material(val2)
				{
					hideFlags = (HideFlags)61
				};
				Plugin.Log.LogWarning((object)"[ThrowPreview] Hidden/Internal-Colored not in this build; paths behind terrain are not drawn.");
			}
			else
			{
				Plugin.Log.LogError((object)"[ThrowPreview] No line shader (Hidden/Internal-Colored, Sprites/Default) in this build; nothing is drawn.");
			}
		}

		private static Material ColoredMaterial(Shader shader, CompareFunction depthTest, float alpha)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0030: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected I4, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(shader)
			{
				name = $"PeakSuite Line {depthTest}",
				hideFlags = (HideFlags)61,
				renderQueue = 3050
			};
			val.SetInt(SrcBlendId, 5);
			val.SetInt(DstBlendId, 10);
			val.SetInt(CullId, 0);
			val.SetInt(ZWriteId, 0);
			val.SetInt(ZTestId, (int)depthTest);
			val.SetColor(ColorId, new Color(1f, 1f, 1f, alpha));
			return val;
		}
	}
	internal sealed class WorldLabel
	{
		private const float FontSize = 18f;

		private static readonly Vector2 Offset = new Vector2(0f, 26f);

		private readonly RectTransform root;

		private readonly TextMeshProUGUI label;

		public WorldLabel(RectTransform hudRoot, string name)
		{
			//IL_004c: 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)
			root = hudRoot;
			label = HudStyle.CreateLabel(name, (Transform)(object)hudRoot, 18f);
			RectTransform rectTransform = ((TMP_Text)label).rectTransform;
			RectTransform rectTransform2 = ((TMP_Text)label).rectTransform;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			rectTransform2.anchorMax = val;
			rectTransform.anchorMin = val;
			((Component)label).gameObject.SetActive(false);
		}

		public void Show(string text, Color color, Vector3 world, Camera camera)
		{
			//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)
			//IL_0030: 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_0046: 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)
			if (!HudRoot.TryScreenToLocal(root, camera.WorldToScreenPoint(world), out var localPoint))
			{
				Hide();
				return;
			}
			HudStyle.SetText((TMP_Text)(object)label, text);
			((Graphic)label).color = HudStyle.WithOpacity(color);
			((TMP_Text)label).rectTransform.anchoredPosition = localPoint + Offset;
			if (!((Component)label).gameObject.activeSelf)
			{
				((Component)label).gameObject.SetActive(true);
			}
		}

		public void Hide()
		{
			if ((Object)(object)label != (Object)null && ((Component)label).gameObject.activeSelf)
			{
				((Component)label).gameObject.SetActive(false);
			}
		}

		public void Destroy()
		{
			if ((Object)(object)label != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)label).gameObject);
			}
		}
	}
	internal sealed class LandingMarker
	{
		private const float Radius = 0.3f;

		private const float Width = 0.03f;

		private const float SurfaceLift = 0.04f;

		private const int Segments = 32;

		private readonly WorldLine ring;

		private readonly WorldLabel note;

		private readonly Vector3[] points = (Vector3[])(object)new Vector3[32];

		private LandingMarker(WorldLine ring, WorldLabel note)
		{
			this.ring = ring;
			this.note = note;
		}

		public static LandingMarker? Create(RectTransform hudRoot)
		{
			WorldLine worldLine = WorldLine.Create("PeakSuite_ThrowLanding", 0.03f, isLoop: true);
			if (worldLine != null)
			{
				return new LandingMarker(worldLine, new WorldLabel(hudRoot, "PeakSuite_ThrowLandingNote"));
			}
			return null;
		}

		public void Show(in ThrowImpact impact, Color color, string? text, Camera camera)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_005b: 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)
			WorldLine.Circle(impact.Point + impact.Normal * 0.04f, impact.Normal, 0.3f, points);
			ring.Show(points, 32, color);
			if (text == null)
			{
				note.Hide();
			}
			else
			{
				note.Show(text, color, impact.Point, camera);
			}
		}

		public void Hide()
		{
			ring.Hide();
			note.Hide();
		}

		public void Destroy()
		{
			ring.Destroy();
			note.Destroy();
		}
	}
	internal sealed class VineMarker
	{
		private const float StemWidth = 0.1f;

		private const float TipRadius = 0.35f;

		private const float TipWidth = 0.03f;

		private const int TipSegments = 24;

		private readonly WorldLine stem;

		private readonly WorldLine tip;

		private readonly WorldLabel label;

		private readonly Vector3[] stemPoints = (Vector3[])(object)new Vector3[2];

		private readonly Vector3[] tipPoints = (Vector3[])(object)new Vector3[24];

		private VineMarker(WorldLine stem, WorldLine tip, WorldLabel label)
		{
			this.stem = stem;
			this.tip = tip;
			this.label = label;
		}

		public static VineMarker? Create(RectTransform hudRoot)
		{
			WorldLine worldLine = WorldLine.Create("PeakSuite_VineStem", 0.1f);
			WorldLine worldLine2 = WorldLine.Create("PeakSuite_VineTip", 0.03f, isLoop: true);
			if (worldLine == null || worldLine2 == null)
			{
				worldLine?.Destroy();
				worldLine2?.Destroy();
				return null;
			}
			return new VineMarker(worldLine, worldLine2, new WorldLabel(hudRoot, "PeakSuite_VineLabel"));
		}

		public void Show(in VinePrediction vine, Camera camera)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_007d: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			Color color = (vine.IsWalkable ? HudStyle.GoodText : HudStyle.BadText);
			stemPoints[0] = vine.Start;
			stemPoints[1] = vine.End;
			stem.Show(stemPoints, stemPoints.Length, color);
			WorldLine.Circle(vine.End, vine.Direction, 0.35f, tipPoints);
			tip.Show(tipPoints, 24, color);
			label.Show(ThrowPreviewText.Vine(vine.Length, vine.IsWalkable), color, vine.End, camera);
		}

		public void Hide()
		{
			stem.Hide();
			tip.Hide();
			label.Hide();
		}

		public void Destroy()
		{
			stem.Destroy();
			tip.Destroy();
			label.Destroy();
		}
	}
	internal static class ThrowPreviewText
	{
		public static string NoSprout => GameLanguage.Pick("不會在這裡發芽", "won't sprout here");

		public static string Vine(float lengthUnits, bool isWalkable)
		{
			string text = HudFormat.Meters(HudFormat.WorldToMeters(lengthUnits));
			string text2 = " " + HudStyle.Glyph('·', "|") + " ";
			return GameLanguage.Pick("藤蔓 " + text + text2 + (isWalkable ? "走得上去" : "要用爬的"), "Vine " + text + text2 + (isWalkable ? "walkable" : "climb it"));
		}
	}
	internal sealed class ThrowPreviewView : MonoBehaviour
	{
		private sealed class PlantedBeanView
		{
			private readonly VineMarker marker;

			private Vector3 computedAt = new Vector3(float.NaN, float.NaN, float.NaN);

			private VinePrediction vine;

			private bool hasVine;

			public PlantedBeanView(VineMarker marker)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				this.marker = marker;
			}

			public void Update(MagicBean bean, Camera camera)
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: 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_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: 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)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				if (!VinePredictor.IsPlanted(bean))
				{
					computedAt = new Vector3(float.NaN, float.NaN, float.NaN);
					marker.Hide();
					return;
				}
				Vector3 position = ((Component)bean).transform.position;
				if (position != computedAt)
				{
					computedAt = position;
					hasVine = VinePredictor.TryPlanted(bean, out vine);
					if (hasVine && bean.isPlanted)
					{
						ThrowAccuracyLog.Planted(bean, in vine);
					}
				}
				if (hasVine)
				{
					marker.Show(in vine, camera);
				}
				else
				{
					marker.Hide();
				}
			}

			public void Hide()
			{
				marker.Hide();
			}

			public void Destroy()
			{
				marker.Destroy();
			}
		}

		private const float PathWidth = 0.04f;

		private const float PathFadeIn = 0.12f;

		private static readonly Color PathColor = new Color(1f, 1f, 1f, 0.9f);

		private readonly ThrowSimulator simulator = new ThrowSimulator();

		private readonly HeldItemHider hider = new HeldItemHider();

		private readonly Dictionary<MagicBean, PlantedBeanView> plantedViews = new Dictionary<MagicBean, PlantedBeanView>();

		private readonly List<MagicBean> goneBeans = new List<MagicBean>();

		private ThrowPreviewFeature feature;

		private RectTransform root;

		private WorldLine path;

		private LandingMarker landing;

		private VineMarker aimVine;

		private ThrowItemTraits? traits;

		private bool canDraw;

		public void Initialize(RectTransform hudRoot, ThrowPreviewFeature owner)
		{
			root = hudRoot;
			feature = owner;
			WorldLine worldLine = WorldLine.Create("PeakSuite_ThrowPath", 0.04f, isLoop: false, 0.12f, TaperedWidth());
			LandingMarker landingMarker = LandingMarker.Create(hudRoot);
			VineMarker vineMarker = VineMarker.Create(hudRoot);
			canDraw = worldLine != null && landingMarker != null && vineMarker != null;
			if (!canDraw)
			{
				worldLine?.Destroy();
				landingMarker?.Destroy();
				vineMarker?.Destroy();
			}
			else
			{
				path = worldLine;
				landing = landingMarker;
				aimVine = vineMarker;
			}
		}

		private void LateUpdate()
		{
			Camera main = Camera.main;
			if (!canDraw || !feature.Enabled.Value || (Object)(object)main == (Object)null)
			{
				HideAll();
				return;
			}
			UpdateAim(main);
			UpdatePlanted(main);
		}

		private void OnDisable()
		{
			if (canDraw)
			{
				HideAll();
			}
		}

		private void OnDestroy()
		{
			hider.Restore();
			if (!canDraw)
			{
				return;
			}
			path.Destroy();
			landing.Destroy();
			aimVine.Destroy();
			foreach (PlantedBeanView value in plantedViews.Values)
			{
				value.Destroy();
			}
			plantedViews.Clear();
		}

		private void UpdateAim(Camera camera)
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			Character localCharacter = Character.localCharacter;
			if (!TryGetChargedItem(localCharacter, out Item item))
			{
				HideAim();
				return;
			}
			if (traits == null || (Object)(object)traits.Item != (Object)(object)item)
			{
				traits = new ThrowItemTraits(item);
			}
			if (ThrowPreviewFeature.HideHeldItem.Value)
			{
				hider.Hide(item);
			}
			else
			{
				hider.Restore();
			}
			float throwChargeLevel = localCharacter.refs.items.throwChargeLevel;
			ThrowImpact? impact = simulator.Run(ThrowLaunch.FromHeld(localCharacter, item, throwChargeLevel), traits, localCharacter);
			bool flag = IsChargeEnough(localCharacter, throwChargeLevel);
			path.Show(simulator.Path, flag ? PathColor : HudStyle.MutedText);
			VinePrediction? vine = ShowLanding(impact, flag ? HudStyle.HighlightText : HudStyle.MutedText, camera);
			ThrowAccuracyLog.Aimed(traits.Name, throwChargeLevel, impact, simulator.FlightSeconds, vine);
		}

		private VinePrediction? ShowLanding(ThrowImpact? impact, Color ringColor, Camera camera)
		{
			//IL_005c: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			if (impact.HasValue)
			{
				ThrowImpact impact2 = impact.GetValueOrDefault();
				MagicBean bean = traits.Bean;
				if ((Object)(object)bean == (Object)null || !ThrowPreviewFeature.ShowVine.Value)
				{
					landing.Show(in impact2, ringColor, null, camera);
					aimVine.Hide();
					return null;
				}
				if (!VinePredictor.Plants(impact2.HitObject))
				{
					landing.Show(in impact2, HudStyle.MutedText, ThrowPreviewText.NoSprout, camera);
					aimVine.Hide();
					return null;
				}
				VinePrediction vine = VinePredictor.Predict(bean, impact2.Center, impact2.Point, impact2.Normal);
				landing.Show(in impact2, ringColor, null, camera);
				aimVine.Show(in vine, camera);
				return vine;
			}
			landing.Hide();
			aimVine.Hide();
			return null;
		}

		private static bool TryGetChargedItem([NotNullWhen(true)] Character? scout, [NotNullWhen(true)] out Item? item)
		{
			item = null;
			if ((Object)(object)scout == (Object)null || scout.data.dead || scout.data.passedOut || scout.data.fullyPassedOut)
			{
				return false;
			}
			if ((Object)(object)Character.observedCharacter != (Object)null && (Object)(object)Character.observedCharacter != (Object)(object)scout)
			{
				return false;
			}
			Item currentItem = scout.data.currentItem;
			if ((Object)(object)currentItem == (Object)null || (Object)(object)currentItem.rig == (Object)null || scout.refs.items.throwChargeLevel <= 0f)
			{
				return false;
			}
			item = currentItem;
			return true;
		}

		private static bool IsChargeEnough(Character scout, float charge)
		{
			StickyItemComponent currentStickyItem = scout.data.currentStickyItem;
			if (!((Object)(object)currentStickyItem == (Object)null))
			{
				return charge >= currentStickyItem.throwChargeRequirement;
			}
			return true;
		}

		private static AnimationCurve TaperedWidth()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_002d: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			return new AnimationCurve((Keyframe[])(object)new Keyframe[3]
			{
				new Keyframe(0f, 0.25f),
				new Keyframe(0.12f, 1f),
				new Keyframe(1f, 1f)
			});
		}

		private void UpdatePlanted(Camera camera)
		{
			List<MagicBean> list = PlantedBeans.Alive();
			DropGoneBeans(list);
			if (!ThrowPreviewFeature.ShowPlantedVine.Value)
			{
				HidePlanted();
				return;
			}
			foreach (MagicBean item in list)
			{
				if (!plantedViews.TryGetValue(item, out PlantedBeanView value))
				{
					VineMarker vineMarker = VineMarker.Create(root);
					if (vineMarker == null)
					{
						continue;
					}
					value = new PlantedBeanView(vineMarker);
					plantedViews[item] = value;
				}
				value.Update(item, camera);
			}
		}

		private void DropGoneBeans(List<MagicBean> alive)
		{
			goneBeans.Clear();
			foreach (KeyValuePair<MagicBean, PlantedBeanView> plantedView in plantedViews)
			{
				if ((Object)(object)plantedView.Key == (Object)null || !alive.Contains(plantedView.Key))
				{
					plantedView.Value.Destroy();
					goneBeans.Add(plantedView.Key);
				}
			}
			foreach (MagicBean goneBean in goneBeans)
			{
				plantedViews.Remove(goneBean);
			}
		}

		private void HideAim()
		{
			hider.Restore();
			path.Hide();
			landing.Hide();
			aimVine.Hide();
		}

		private void HidePlanted()
		{
			foreach (PlantedBeanView value in plantedViews.Values)
			{
				value.Hide();
			}
		}

		private void HideAll()
		{
			hider.Restore();
			if (canDraw)
			{
				HideAim();
				HidePlanted();
			}
		}
	}
	internal sealed class HeldItemHider
	{
		private readonly List<Renderer> hidden = new List<Renderer>();

		private Item? item;

		public void Hide(Item target)
		{
			if ((Object)(object)item == (Object)(object)target)
			{
				return;
			}
			Restore();
			item = target;
			Renderer[] componentsInChildren = ((Component)target).GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && !val.forceRenderingOff)
				{
					val.forceRenderingOff = true;
					hidden.Add(val);
				}
			}
		}

		public void Restore()
		{
			foreach (Renderer item in hidden)
			{
				if ((Object)(object)item != (Object)null)
				{
					item.forceRenderingOff = false;
				}
			}
			hidden.Clear();
			this.item = null;
		}
	}
	internal readonly struct ThrowLaunch
	{
		private const float BackpackLift = 0.25f;

		private const float ForceToVelocity = 0.5f;

		public Vector3 Position { get; }

		public Vector3 Velocity { get; }

		public Quaternion Rotation { get; }

		public Vector3 Spin { get; }

		private ThrowLaunch(Vector3 position, Vector3 velocity, Quaternion rotation, Vector3 spin)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_000f: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			Position = position;
			Velocity = velocity;
			Rotation = rotation;
			Spin = spin;
		}

		public static ThrowLaunch FromHeld(Character thrower, Item item, float charge)
		{
			//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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_005d: 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_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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			CharacterItems items = thrower.refs.items;
			float num = ((charge > 0f) ? (items.minThrowForce + (items.maxThrowForce - items.minThrowForce) * charge) : 0f);
			Vector3 val = item.transform.position;
			Vector3 val2 = item.rig.linearVelocity;
			if (item is Backpack)
			{
				val += 0.25f * Vector3.up;
				val2 = Vector3.zero;
			}
			Vector3 val3 = HelperFunctions.LookToDirection(Vector2.op_Implicit(thrower.data.lookValues), Vector3.forward);
			Vector3 normalized = ((Vector3)(ref val3)).normalized;
			val2 += normalized * (num * 0.5f * item.throwForceMultiplier);
			Vector3 spin = (((item.itemTags & 0x400) != 0) ? Vector3.zero : (Vector3.Cross(normalized, Vector3.up) * (num * 0.5f)));
			return new ThrowLaunch(val, val2, item.transform.rotation, spin);
		}
	}
	internal sealed class ThrowItemTraits
	{
		private const float MinRadius = 0.02f;

		private const float MaxRadius = 0.3f;

		private const int LayerCount = 32;

		private static readonly int?[] MaskByLayer = new int?[32];

		public Item Item { get; }

		public string Name { get; }

		public int CollisionMask { get; }

		public float Radius { get; }

		public float Drag { get; }

		public float AngularDrag { get; }

		public float MaxSpin { get; }

		public float Mass { get; }

		public bool HasAntigrav { get; }

		public float AntigravIntensity { get; }

		public Frisbee? Frisbee { get; }

		public Vector3 FrisbeeLocalUp { get; }

		public MagicBean? Bean { get; }

		public ThrowItemTraits(Item item)
		{
			//IL_00ea: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			Item = item;
			Name = ((Object)item).name;
			CollisionMask = CollisionMaskFor(((Component)item).gameObject.layer);
			Radius = RadiusOf(item);
			Drag = item.rig.linearDamping;
			AngularDrag = item.rig.angularDamping;
			MaxSpin = item.rig.maxAngularVelocity;
			Mass = Mathf.Max(item.rig.mass, 0.0001f);
			Antigrav component = ((Component)item).GetComponent<Antigrav>();
			HasAntigrav = (Object)(object)component != (Object)null;
			AntigravIntensity = (((Object)(object)component != (Object)null) ? component.intensity : 0f);
			Frisbee componentInChildren = ((Component)item).GetComponentInChildren<Frisbee>();
			Frisbee = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren : null);
			FrisbeeLocalUp = (((Object)(object)componentInChildren != (Object)null) ? (Quaternion.Inverse(item.transform.rotation) * ((Component)componentInChildren).transform.up) : Vector3.up);
			MagicBean component2 = ((Component)item).GetComponent<MagicBean>();
			Bean = (((Object)(object)component2 != (Object)null) ? component2 : null);
		}

		private static int CollisionMaskFor(int layer)
		{
			int? num = MaskByLayer[layer];
			if (num.HasValue)
			{
				return num.GetValueOrDefault();
			}
			int num2 = 0;
			for (int i = 0; i < 32; i++)
			{
				if (!Physics.GetIgnoreLayerCollision(layer, i))
				{
					num2 |= 1 << i;
				}
			}
			MaskByLayer[layer] = num2;
			return num2;
		}

		private static float RadiusOf(Item item)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			Bounds val = default(Bounds);
			Collider[] array = item.colliders ?? Array.Empty<Collider>();
			foreach (Collider val2 in array)
			{
				if (!((Object)(object)val2 == (Object)null) && val2.enabled && !val2.isTrigger)
				{
					if (flag)
					{
						((Bounds)(ref val)).Encapsulate(val2.bounds);
						continue;
					}
					val = val2.bounds;
					flag = true;
				}
			}
			if (!flag)
			{
				return 0.02f;
			}
			Vector3 extents = ((Bounds)(ref val)).extents;
			return Mathf.Clamp(Mathf.Min(extents.x, Mathf.Min(extents.y, extents.z)), 0.02f, 0.3f);
		}
	}
	internal readonly struct ThrowImpact
	{
		public Vector3 Point { get; }

		public Vector3 Normal { get; }

		public Vector3 Center { get; }

		public Collider Collider { get; }

		public GameObject HitObject
		{
			get
			{
				if (!((Object)(object)Collider.attachedRigidbody != (Object)null))
				{
					return ((Component)Collider).gameObject;
				}
				return ((Component)Collider.attachedRigidbody).gameObject;
			}
		}

		public ThrowImpact(Vector3 point, Vector3 normal, Vector3 center, Collider collider)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_000f: 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)
			Point = point;
			Normal = normal;
			Center = center;
			Collider = collider;
		}
	}
	internal sealed class ThrowSimulator
	{
		private const float MaxSeconds = 6f;

		private const int StepsPerSweep = 3;

		private const float ThrowerIgnoredSeconds = 0.5f;

		private const float AntiSphereLift = 1.2f;

		private const float EnvironmentRefreshSeconds = 2f;

		private const float MinSweepDistance = 0.0001f;

		private const float MinSpin = 0.0001f;

		private readonly RaycastHit[] hits = (RaycastHit[])(object)new RaycastHit[64];

		private readonly List<WindChillZone> windZones = new List<WindChillZone>();

		private readonly List<AntiSphere> antiSpheres = new List<AntiSphere>();

		private float environmentReadAt = float.NegativeInfinity;

		public List<Vector3> Path { get; } = new List<Vector3>();

		public float FlightSeconds { get; private set; }

		public ThrowImpact? Run(in ThrowLaunch launch, ThrowItemTraits traits, Character thrower)
		{
			//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_006f: 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)
			//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_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_008f: 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_00ae: 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)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			Path.Clear();
			FlightSeconds = 0f;
			float fixedDeltaTime = Time.fixedDeltaTime;
			if (fixedDeltaTime <= 0f)
			{
				return null;
			}
			RefreshEnvironment();
			float num = Mathf.Max(0f, 1f - traits.Drag * fixedDeltaTime);
			float num2 = Mathf.Max(0f, 1f - traits.AngularDrag * fixedDeltaTime);
			Vector3 val = launch.Position;
			Vector3 val2 = launch.Velocity;
			Quaternion rotation = launch.Rotation;
			Vector3 val3 = launch.Spin;
			int num3 = 0;
			Path.Add(val);
			int num4 = Mathf.CeilToInt(6f / fixedDeltaTime);
			for (int i = 1; i <= num4; i++)
			{
				val2 = (val2 + Acceleration(val, val2, rotation, traits) * fixedDeltaTime) * num;
				val += val2 * fixedDeltaTime;
				if ((Object)(object)traits.Frisbee != (Object)null)
				{
					val3 = Vector3.ClampMagnitude(val3 * num2, traits.MaxSpin);
					rotation = Rotate(rotation, val3, fixedDeltaTime);
				}
				Path.Add(val);
				if (i % 3 == 0 || i == num4)
				{
					if (TrySweep(Path[num3], val, traits, thrower, (float)num3 * fixedDeltaTime, out var impact, out var share))
					{
						Path.RemoveRange(num3 + 1, Path.Count - num3 - 1);
						Path.Add(impact.Center);
						FlightSeconds = ((float)num3 + share * (float)(i - num3)) * fixedDeltaTime;
						return impact;
					}
					num3 = i;
				}
			}
			FlightSeconds = (float)num4 * fixedDeltaTime;
			return null;
		}

		private Vector3 Acceleration(Vector3 position, Vector3 velocity, Quaternion rotation, ThrowItemTraits traits)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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)
			//IL_0035: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0063: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			Vector3 gravity = Physics.gravity;
			Vector3 val = gravity;
			if (IsInAntiSphere(position, traits.Radius))
			{
				if (!traits.HasAntigrav)
				{
					val -= gravity * 1.2f;
				}
			}
			else
			{
				val -= gravity * traits.AntigravIntensity;
			}
			if ((Object)(object)traits.Frisbee != (Object)null)
			{
				val += FrisbeeLift(traits, traits.Frisbee, velocity, rotation);
			}
			foreach (WindChillZone windZone in windZones)
			{
				val += Wind(windZone, position);
			}
			return val;
		}

		private static Vector3 FrisbeeLift(ThrowItemTraits traits, Frisbee frisbee, Vector3 velocity, Quaternion rotation)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = rotation * traits.FrisbeeLocalUp;
			float num = Mathf.InverseLerp(0f, frisbee.velocityForLift, ((Vector3)(ref velocity)).sqrMagnitude);
			float num2 = Mathf.Clamp01(Vector3.Dot(val, Vector3.up));
			return val * (num2 * frisbee.liftForce * num / traits.Mass);
		}

		private static Vector3 Wind(WindChillZone zone, Vector3 position)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)zone == (Object)null || !((Behaviour)zone).isActiveAndEnabled || !zone.windMovesItems || !((Bounds)(ref zone.windZoneBounds)).Contains(position))
			{
				return Vector3.zero;
			}
			float num = (zone.useIntensityCurve ? (Mathf.Clamp01(zone.windIntensity - 0.5f) * 2f) : 1f);
			return zone.currentWindDirection * (zone.windForce * zone.windItemFactor * num);
		}

		private bool IsInAntiSphere(Vector3 position, float radius)
		{
			//IL_0053: 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_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_0070: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			foreach (AntiSphere antiSphere in antiSpheres)
			{
				if (!((Object)(object)antiSphere == (Object)null) && ((Behaviour)antiSphere).isActiveAndEnabled && !((Object)(object)antiSphere.coll == (Object)null) && ((Collider)antiSphere.coll).enabled)
				{
					float num = antiSphere.coll.radius * ((Component)antiSphere).transform.lossyScale.x + radius;
					Bounds bounds = ((Collider)antiSphere.coll).bounds;
					Vector3 val = position - ((Bounds)(ref bounds)).center;
					if (((Vector3)(ref val)).sqrMagnitude < num * num)
					{
						return true;
					}
				}
			}
			return false;
		}

		private bool TrySweep(Vector3 from, Vector3 to, ThrowItemTraits traits, Character thrower, float time, out ThrowImpact impact, out float share)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0066: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			impact = default(ThrowImpact);
			share = 0f;
			Vector3 val = to - from;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude < 0.0001f)
			{
				return false;
			}
			Vector3 val2 = val / magnitude;
			int num = Physics.SphereCastNonAlloc(from, traits.Radius, val2, hits, magnitude, traits.CollisionMask, (QueryTriggerInteraction)1);
			int num2 = -1;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val3 = hits[i];
				bool flag = ((RaycastHit)(ref val3)).distance <= 0f && ((RaycastHit)(ref val3)).point == Vector3.zero;
				if (!((Object)(object)((RaycastHit)(ref val3)).collider == (Object)null || flag) && !IsIgnored(((RaycastHit)(ref val3)).collider, traits.Item, thrower, time) && (num2 < 0 || ((RaycastHit)(ref val3)).distance < ((RaycastHit)(ref hits[num2])).distance))
				{
					num2 = i;
				}
			}
			if (num2 < 0)
			{
				return false;
			}
			RaycastHit val4 = hits[num2];
			impact = new ThrowImpact(((RaycastHit)(ref val4)).point, ((RaycastHit)(ref val4)).normal, from + val2 * ((RaycastHit)(ref val4)).distance, ((RaycastHit)(ref val4)).collider);
			share = ((RaycastHit)(ref val4)).distance / magnitude;
			return true;
		}

		private static bool IsIgnored(Collider collider, Item held, Character thrower, float time)
		{
			Item val = default(Item);
			if (Item.TryGetItemFromCollider(collider, ref val) && (Object)(object)val == (Object)(object)held)
			{
				return true;
			}
			Character val2 = default(Character);
			if (time < 0.5f && CharacterRagdoll.TryGetCharacterFromCollider(collider, ref val2))
			{
				return (Object)(object)val2 == (Object)(object)thrower;
			}
			return false;
		}

		private static Quaternion Rotate(Quaternion rotation, Vector3 spin, float dt)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			float magnitude = ((Vector3)(ref spin)).magnitude;
			if (!(magnitude < 0.0001f))
			{
				return Quaternion.AngleAxis(magnitude * dt * 57.29578f, spin / magnitude) * rotation;
			}
			return rotation;
		}

		private void RefreshEnvironment()
		{
			if (!(Time.time - environmentReadAt < 2f))
			{
				environmentReadAt = Time.time;
				windZones.Clear();
				windZones.AddRange(Object.FindObjectsByType<WindChillZone>((FindObjectsSortMode)0));
				antiSpheres.Clear();
				antiSpheres.AddRange(Object.FindObjectsByType<AntiSphere>((FindObjectsSortMode)0));
			}
		}
	}
	internal readonly struct VinePrediction
	{
		public Vector3 Start { get; }

		public Vector3 Direction { get; }

		public float Length { get; }

		public bool IsWalkable { get; }

		public Vector3 End => Start + Direction * Length;

		public VinePrediction(Vector3 start, Vector3 direction, float length, bool isWalkable)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//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)
			Start = start;
			Direction = direction;
			Length = length;
			IsWalkable = isWalkable;
		}
	}
	internal static class VinePredictor
	{
		private const float ProbeSpacing = 0.2f;

		private const float ProbeHeight = 1f;

		private const float MinStopDistance = 0.7f;

		private const float FallbackMaxLength = 20f;

		private const float FallbackStandAngle = 50f;

		private const float ContactSearchDistance = 0.75f;

		private static readonly RaycastHit[] StopHits = (RaycastHit[])(object)new RaycastHit[128];

		private static readonly Vector3[] SearchDirections = BuildSearchDirections();

		public static bool Plants(GameObject hitObject)
		{
			return HelperFunctions.IsLayerInLayerMask((LayerType)1, hitObject.layer);
		}

		public static VinePrediction Predict(MagicBean bean, Vector3 beanPosition, Vector3 contactPoint, Vector3 contactNormal)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return Grow(bean, beanPosition, AverageNormal(contactPoint, contactNormal, bean.snapToVerticalAngle));
		}

		public static bool IsPlanted(MagicBean bean)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (bean.isPlanted)
			{
				return true;
			}
			Item item = ((ItemComponent)bean).item;
			if ((Object)(object)item != (Object)null && (int)item.itemState == 0 && (Object)(object)item.rig != (Object)null)
			{
				return item.rig.isKinematic;
			}
			return false;
		}

		public static bool TryPlanted(MagicBean bean, out VinePrediction vine)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)bean).transform.position;
			if (bean.isPlanted)
			{
				vine = Grow(bean, position, bean.averageNormal);
				return true;
			}
			if (TryFindContact(position, out var point, out var normal))
			{
				vine = Predict(bean, position, point, normal);
				return true;
			}
			vine = default(VinePrediction);
			return false;
		}

		public static Vector3 AverageNormal(Vector3 contactPoint, Vector3 contactNormal, float snapToVerticalAngle)
		{
			//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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_002d: 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_003b: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_0095: 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)
			Vector3 val = contactNormal;
			for (int i = -1; i <= 1; i++)
			{
				for (int j = -1; j <= 1; j++)
				{
					if (i != 0 || j != 0)
					{
						Vector3 val2 = Vector3.ProjectOnPlane(new Vector3((float)i, 0f, (float)j), contactNormal);
						Vector3 val3 = ((Vector3)(ref val2)).normalized * 0.2f;
						Vector3 val4 = contactPoint + val3 + contactNormal * 1f;
						RaycastHit val5 = HelperFunctions.LineCheck(val4, val4 - contactNormal * 2f, (LayerType)1, 0f, (QueryTriggerInteraction)1);
						if ((Object)(object)((RaycastHit)(ref val5)).collider != (Object)null)
						{
							val += ((RaycastHit)(ref val5)).normal;
						}
					}
				}
			}
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			if (!(Vector3.Angle(normalized, Vector3.up) < snapToVerticalAngle))
			{
				return normalized;
			}
			return Vector3.up;
		}

		public static float Length(Vector3 start, Vector3 direction, float maxLength)
		{
			//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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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)
			int num = HelperFunctions.LineCheckAll(start, start + direction * maxLength, (LayerType)1, StopHits, 0f, (QueryTriggerInteraction)1);
			float num2 = maxLength;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = StopHits[i];
				if ((Object)(object)((RaycastHit)(ref val)).collider != (Object)null && ((RaycastHit)(ref val)).distance > 0.7f && ((RaycastHit)(ref val)).distance < num2)
				{
					num2 = ((RaycastHit)(ref val)).distance;
				}
			}
			return num2;
		}

		public static bool IsWalkable(Vector3 direction)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Abs(90f - Vector3.Angle(direction, Vector3.up));
			return num < StandAngle();
		}

		private static VinePrediction Grow(MagicBean bean, Vector3 start, Vector3 direction)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			float maxLength = (((Object)(object)bean.plantPrefab != (Object)null) ? bean.plantPrefab.maxLength : 20f);
			return new VinePrediction(start, direction, Length(start, direction, maxLength), IsWalkable(direction));
		}

		private static float StandAngle()
		{
			Character localCharacter = Character.localCharacter;
			if (!((Object)(object)localCharacter != (Object)null) || !((Object)(object)localCharacter.refs.movement != (Object)null))
			{
				return 50f;
			}
			return localCharacter.refs.movement.maxAngle;
		}

		private static bool TryFindContact(Vector3 beanPosition, out Vector3 point, out Vector3 normal)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_002e: 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_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_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_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)
			point = default(Vector3);
			normal = default(Vector3);
			float num = float.MaxValue;
			Vector3[] searchDirections = SearchDirections;
			foreach (Vector3 val in searchDirections)
			{
				RaycastHit val2 = HelperFunctions.LineCheck(beanPosition, beanPosition + val * 0.75f, (LayerType)1, 0f, (QueryTriggerInteraction)1);
				if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) && !(((RaycastHit)(ref val2)).distance >= num))
				{
					num = ((RaycastHit)(ref val2)).distance;
					point = ((RaycastHit)(ref val2)).point;
					normal = ((RaycastHit)(ref val2)).normal;
				}
			}
			return num < float.MaxValue;
		}

		private static Vector3[] BuildSearchDirections()
		{
			//IL_002e: 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_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)
			Vector3[] array = (Vector3[])(object)new Vector3[26];
			int num = 0;
			for (int i = -1; i <= 1; i++)
			{
				for (int j = -1; j <= 1; j++)
				{
					for (int k = -1; k <= 1; k++)
					{
						if (i != 0 || j != 0 || k != 0)
						{
							int num2 = num++;
							Vector3 val = new Vector3((float)i, (float)j, (float)k);
							array[num2] = ((Vector3)(ref val)).normalized;
						}
					}
				}
			}
			return array;
		}
	}
}
namespace PeakSuite.Features.TeammateStatus
{
	internal sealed class TeammateStatusFeature : Feature
	{
		public override string Id => "TeammateStatus";

		public override string ChineseName => "隊友頭頂體力條";

		protected override string Description => "Show a copy of your stamina bar (with status icons) above nearby teammates.";

		public static ConfigEntry<float> MaxDistanceMeters { get; private set; }

		public static ConfigEntry<float> BarScale { get; private set; }

		public static ConfigEntry<float> TextScale { get; private set; }

		public static ConfigEntry<bool> ShowNumber { get; private set; }

		public static ConfigEntry<bool> ShowAfflictionNumbers { get; private set; }

		protected override void BindOptions(ConfigFile config)
		{
			MaxDistanceMeters = Bind(config, "MaxDistanceMeters", 50f, "最遠距離(公尺)", "Only teammates within this many meters (the game's meters) get a bar.", (AcceptableValueBase?)(object)new AcceptableValueRange<float>(10f, 500f));
			BarScale = Bind(config, "BarScale", 1f, "體力條大小", "Size of the overhead bar.", (AcceptableValueBase?)(object)new AcceptableValueRange<float>(0.5f, 2.5f));
			TextScale = Bind(config, "TextScale", 1.5f, "數字大小", "Size of the numbers inside the overhead bar, relative to the bar.", (AcceptableValueBase?)(object)new AcceptableValueRange<float>(0.5f, 3f));
			ShowNumber = Bind(config, "ShowNumber", defaultValue: true, "顯示體力數字", "Print the stamina number inside the bar.");
			ShowAfflictionNumbers = Bind(config, "ShowAfflictionNumbers", defaultValue: true, "顯示狀態數字", "Print each affliction's value inside its segment.");
		}

		protected override void Apply(Harmony harmony)
		{
			HudRoot.Created += delegate(RectTransform root, GUIManager _)
			{
				((Component)root).gameObject.AddComponent<TeammateStatusView>().Initialize(root, this);
			};
		}
	}
	internal sealed class TeammateStatusView : MonoBehaviour
	{
		private const float OverheadScale = 0.42f;

		private const float HeadOffsetUnits = 1.35f;

		private const float GapPixels = 4f;

		private const float EstimatedNameHeightPerFontSize = 1.1f;

		private const float MeasureIntervalSeconds = 1f;

		private readonly Dictionary<Character, StaminaBarReplica> bars = new Dictionary<Character, StaminaBarReplica>();

		private readonly Dictionary<Character, Transform> nameAnchors = new Dictionary<Character, Transform>();

		private readonly List<Character> stale = new List<Character>();

		private TeammateStatusFeature feature;

		private RectTransform root;

		private float? nameTopPixels;

		private float nextMeasureTime;

		private float nextContentTime;

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

		public void Initialize(RectTransform hudRoot, TeammateStatusFeature owner)
		{
			root = hudRoot;
			feature = owner;
		}

		private void LateUpdate()
		{
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			RemoveStale();
			Camera main = Camera.main;
			Character localCharacter = Character.localCharacter;
			bool flag = feature.Enabled.Value && (Object)(object)main != (Object)null && (Object)(object)localCharacter != (Object)null;
			if (flag && Time.unscaledTime >= nextMeasureTime)
			{
				nextMeasureTime = Time.unscaledTime + 1f;
				MeasureNameHeight();
			}
			bool flag2 = Time.unscaledTime >= nextContentTime;
			if (flag2)
			{
				nextContentTime = Time.unscaledTime + 1f / (float)StaminaNumbersFeature.RefreshRate.Value;
			}
			bool flag3 = false;
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if ((Object)(object)allCharacter == (Object)null || allCharacter.IsLocal || !allCharacter.IsPlayerControlled)
				{
					continue;
				}
				bool flag4 = flag && !allCharacter.data.dead && HudFormat.WorldToMeters(Vector3.Distance(localCharacter.Center, allCharacter.Center)) <= TeammateStatusFeature.MaxDistanceMeters.Value;
				bool flag5 = false;
				if (!bars.TryGetValue(allCharacter, out StaminaBarReplica value))
				{
					if (!flag4 || flag3)
					{
						continue;
					}
					flag3 = true;
					value = StaminaBarReplica.Create("PeakSuite_TeammateStatus", (Transform)(object)root, TeammateStatusFeature.TextScale.Value);
					if (value == null)
					{
						continue;
					}
					bars[allCharacter] = value;
					flag5 = true;
				}
				if (!flag4)
				{
					value.SetVisible(isVisible: false);
				}
				else
				{
					Place(value, allCharacter, main, flag2 || flag5);
				}
			}
		}

		private void Place(StaminaBarReplica bar, Character character, Camera camera, bool isContentDue)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_003d: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			float num = 0.42f * TeammateStatusFeature.BarScale.Value;
			Transform val = NameAnchor(character);
			Vector3 screenPoint = (((Object)(object)val != (Object)null) ? camera.WorldToScreenPoint(val.position) : camera.WorldToScreenPoint(character.Center + Vector3.up * 1.35f));
			if ((Object)(object)val != (Object)null)
			{
				screenPoint.y += (nameTopPixels ?? EstimatedNameTop()) + 4f;
			}
			if (!HudRoot.TryScreenToLocal(root, screenPoint, out var localPoint))
			{
				bar.SetVisible(isVisible: false);
				return;
			}
			bool isVisible = bar.IsVisible;
			bar.SetVisible(isVisible: true);
			float num2 = (((Object)(object)val != (Object)null) ? ((0f - bar.BottomOffset) * num) : 0f);
			bar.Root.anchoredPosition = localPoint + new Vector2(0f, num2);
			((Transform)bar.Root).localScale = new Vector3(num, num, 1f);
			if (isContentDue || !isVisible)
			{
				bar.Show(character, TeammateStatusFeature.ShowNumber.Value, TeammateStatusFeature.ShowAfflictionNumbers.Value, StaminaNumbersFeature.DecimalPlaces.Value);
			}
		}

		private Transform? NameAnchor(Character character)
		{
			if (nameAnchors.TryGetValue(character, out Transform value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			IsLookedAt componentInChildren = ((Component)character).GetComponentInChildren<IsLookedAt>(true);
			if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren.playerNamePos == (Object)null)
			{
				return null;
			}
			nameAnchors[character] = componentInChildren.playerNamePos;
			return componentInChildren.playerNamePos;
		}

		private void MeasureNameHeight()
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			PlayerName[] array = (((Object)(object)GUIManager.instance != (Object)null && (Object)(object)GUIManager.instance.playerNames != (Object)null) ? GUIManager.instance.playerNames.playerNameText : null);
			if (array == null)
			{
				return;
			}
			PlayerName[] array2 = array;
			foreach (PlayerName val in array2)
			{
				if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy && !((Object)(object)val.group == (Object)null) && !(val.group.alpha < 0.95f) && !((Object)(object)val.text == (Object)null) && !string.IsNullOrEmpty(((TMP_Text)val.text).text))
				{
					Canvas canvas = ((Graphic)val.text).canvas;
					Camera val2 = (((Object)(object)canvas == (Object)null || (int)canvas.renderMode == 0) ? null : canvas.worldCamera);
					float y = RectTransformUtility.WorldToScreenPoint(val2, ((Component)val).transform.position).y;
					float num = TextTop((TMP_Text)(object)val.text, val2);
					Image[] componentsInChildren = ((Component)val).GetComponentsInChildren<Image>(false);
					foreach (Image val3 in componentsInChildren)
					{
						num = Mathf.Max(num, RectTop(((Graphic)val3).rectTransform, val2));
					}
					if (num > y)
					{
						nameTopPixels = num - y;
						break;
					}
				}
			}
		}

		private float EstimatedNameTop()
		{
			PlayerName[] array = (((Object)(object)GUIManager.instance != (Object)null && (Object)(object)GUIManager.instance.playerNames != (Object)null) ? GUIManager.instance.playerNames.playerNameText : null);
			TextMeshProUGUI val = ((array != null && array.Length != 0 && (Object)(object)array[0] != (Object)null) ? array[0].text : null);
			if ((Object)(object)val == (Object)null)
			{
				return 30f;
			}
			float num = (((Object)(object)((Graphic)val).canvas != (Object)null) ? ((Graphic)val).canvas.scaleFactor : 1f);
			return ((TMP_Text)val).fontSize * num * 1.1f;
		}

		private static float TextTop(TMP_Text text, Camera? eye)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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)
			//IL_002f: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			Bounds textBounds = text.textBounds;
			if (((Bounds)(ref textBounds)).size.y <= 0f)
			{
				return RectTop(text.rectTransform, eye);
			}
			Vector3 val = ((Transform)text.rectTransform).TransformPoint(new Vector3(((Bounds)(ref textBounds)).center.x, ((Bounds)(ref textBounds)).max.y, 0f));
			return RectTransformUtility.WorldToScreenPoint(eye, val).y;
		}

		private static float RectTop(RectTransform rect, Camera? eye)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			rect.GetWorldCorners(Corners);
			float num = float.MinValue;
			Vector3[] corners = Corners;
			foreach (Vector3 val in corners)
			{
				num = Mathf.Max(num, RectTransformUtility.WorldToScreenPoint(eye, val).y);
			}
			return num;
		}

		private void OnDestroy()
		{
			foreach (StaminaBarReplica value in bars.Values)
			{
				value.Destroy();
			}
			bars.Clear();
			nameAnchors.Clear();
		}

		private void RemoveStale()
		{
			stale.Clear();
			foreach (KeyValuePair<Character, StaminaBarReplica> bar in bars)
			{
				if ((Object)(object)bar.Key == (Object)null)
				{
					bar.Value.Destroy();
					stale.Add(bar.Key);
				}
			}
			foreach (Character item in stale)
			{
				bars.Remove(item);
				nameAnchors.Remove(item);
			}
		}
	}
}
namespace PeakSuite.Features.StaminaNumbers
{
	internal sealed class StaminaNumbersFeature : Feature
	{
		public override string Id => "StaminaNumbers";

		public override string ChineseName => "體力數字";

		protected override string Description => "Show numbers on your stamina bar, bonus stamina and affliction segments.";

		public static ConfigEntry<int> DecimalPlaces { get; private set; }

		public static ConfigEntry<bool> ShowAfflictions { get; private set; }

		public static ConfigEntry<int> RefreshRate { get; private set; }

		public static ConfigEntry<bool> ShowDecayTime { get; private set; }

		public static ConfigEntry<float> TextScale { get; private set; }

		protected override void BindOptions(ConfigFile config)
		{
			TextScale = Bind(config, "TextScale", 1f, "文字大小", "Size of the numbers on the stamina bar, on top of [Hud] TextScale.", (AcceptableValueBase?)(object)new AcceptableValueRange<float>(0.5f, 2f));
			DecimalPlaces = Bind(config, "DecimalPlaces", 1, "小數位數", "Digits after the decimal point on every stamina bar: yours, teammates' and the scoreboard's.", (AcceptableValueBase?)(object)new AcceptableValueRange<int>(0, 2));
			Feature.FollowMovedDefault(DecimalPlaces, 0);
			ShowAfflictions = Bind(config, "ShowAfflictions", defaultValue: true, "顯示各狀態數值", "Also print the value on every affliction segment (weight, heat, hunger, injury, cold, poison...).");
			ShowDecayTime = Bind(config, "ShowDecayTime", defaultValue: true, "顯示狀態退完倒數", "After the value on poison, heat, spores and drowsiness, show how long until they wear off on their own (your own bar only).");
			RefreshRate = Bind(config, "RefreshRate", 20, "每秒更新次數", "Updates per second of the numbers on your bar, and of teammates' overhead bars, the scoreboard rows and the altitude bar's pins (lower costs less with many players).", (AcceptableValueBase?)(object)new AcceptableValueRange<int>(5, 60));
		}

		protected override void Apply(Harmony harmony)
		{
			HudRoot.Created += delegate(RectTransform _, GUIManager gui)
			{
				if ((Object)(object)gui.bar == (Object)null)
				{
					Plugin.Log.LogWarning((object)("[" + Id + "] GUIManager.bar missing; stamina numbers not attached."));
				}
				else
				{
					StaminaNumbersView staminaNumbersView = default(StaminaNumbersView);
					if (((Component)gui.bar).TryGetComponent<StaminaNumbersView>(ref staminaNumbersView))
					{
						Object.DestroyImmediate((Object)(object)staminaNumbersView);
					}
					StaminaNumbersView staminaNumbersView2 = ((Component)gui.bar).gameObject.AddComponent<StaminaNumbersView>();
					staminaNumbersView2.Initialize(gui.bar, this);
				}
			};
		}
	}
	internal sealed class StaminaNumbersView : MonoBehaviour
	{
		private sealed class SegmentLabels
		{
			public BarAffliction Segment { get; }

			public STATUSTYPE Type { get; }

			public TextMeshProUGUI Label { get; }

			public SegmentLabels(BarAffliction segment, STATUSTYPE type, TextMeshProUGUI label)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				Segment = segment;
				Type = type;
				Label = label;
			}
		}

		private const float MinimumDecaySeconds = 0.5f;

		private const string DecayOpen = " <size=72%>";

		private const string DecayClose = "</size>";

		private readonly List<SegmentLabels> segments = new List<SegmentLabels>();

		private StaminaNumbersFeature feature;

		private TextMeshProUGUI staminaLabel;

		private TextMeshProUGUI extraLabel;

		private float nextRefreshTime;

		public unsafe void Initialize(StaminaBar bar, StaminaNumbersFeature owner)
		{
			//IL_0031: 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)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			feature = owner;
			float value = StaminaNumbersFeature.TextScale.Value;
			staminaLabel = HudStyle.CreateBarLabel("PeakSuite_Stamina", bar.staminaBar, 30f * value, BarTextColor.For("Stamina", bar.staminaBar));
			extraLabel = HudStyle.CreateBarLabel("PeakSuite_ExtraStamina", bar.extraBarStamina, 30f * value, BarTextColor.For("ExtraStamina", bar.extraBarStamina));
			foreach (BarAffliction item in StatusIcons.FindSegments(bar))
			{
				if ((Object)(object)item.rtf != (Object)null)
				{
					STATUSTYPE val = StatusIcons.TypeOf(item);
					TextMeshProUGUI label = HudStyle.CreateBarLabel($"PeakSuite_{val}", item.rtf, 24f * value, BarTextColor.For(((object)(*(STATUSTYPE*)(&val))/*cast due to .constrained prefix*/).ToString(), item.rtf, item.icon));
					segments.Add(new SegmentLabels(item, val, label));
				}
			}
			BarTextColor.LogOnce();
		}

		private void OnDestroy()
		{
			DestroyLabel(staminaLabel);
			DestroyLabel(extraLabel);
			foreach (SegmentLabels segment in segments)
			{
				DestroyLabel(segment.Label);
			}
			segments.Clear();
		}

		private static void DestroyLabel(TextMeshProUGUI? label)
		{
			if ((Object)(object)label != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)label).gameObject);
			}
		}

		private void Update()
		{
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime < nextRefreshTime)
			{
				return;
			}
			nextRefreshTime = Time.unscaledTime + 1f / (float)StaminaNumbersFeature.RefreshRate.Value;
			Character observedCharacter = Character.observedCharacter;
			if (!feature.Enabled.Value || (Object)(object)observedCharacter == (Object)null)
			{
				SetAllText(string.Empty);
				return;
			}
			int value = StaminaNumbersFeature.DecimalPlaces.Value;
			HudStyle.SetText((TMP_Text)(object)staminaLabel, HudFormat.BarValue(observedCharacter.data.currentStamina, value));
			HudStyle.SetText((TMP_Text)(object)extraLabel, Hu