Decompiled source of FogAndColdControl v1.0.1

BepInEx/plugins/Thanks.Fog&ColdControl.dll

Decompiled 13 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Thanks.Fog&ColdControl")]
[assembly: AssemblyDescription("Host-only PEAK fog and cold control mode with synced fog movement, compass rewards, HUD, and separate fog-cold and night-cold handling.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Thanks")]
[assembly: AssemblyProduct("Fog&ColdControl")]
[assembly: AssemblyCopyright("Copyright (c) Thanks 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f3d09c64-b194-4a16-9196-85106f2f0d01")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FogColdControl
{
	[HarmonyPatch(typeof(Fog), "MakePlayerCold")]
	internal static class FogMakePlayerColdPatch
	{
		private static bool Prefix()
		{
			return !Plugin.ShouldSuppressFogColdLocally();
		}
	}
	[HarmonyPatch(typeof(FogSphere), "SetSharderVars")]
	internal static class FogSphereSetShaderVarsPatch
	{
		private static void Prefix()
		{
			Plugin.BeginLocalFogStatusSuppression();
		}

		private static Exception Finalizer(Exception __exception)
		{
			Plugin.EndLocalFogStatusSuppression();
			return __exception;
		}
	}
	[HarmonyPatch(typeof(OrbFogHandler), "WaitToMove")]
	internal static class OrbFogHandlerWaitToMovePatch
	{
		private static bool Prefix(OrbFogHandler __instance)
		{
			return !Plugin.ShouldBlockVanillaOrbFogWait(__instance);
		}
	}
	[HarmonyPatch(typeof(OrbFogHandler), "Start")]
	internal static class OrbFogHandlerStartPatch
	{
		private static void Postfix(OrbFogHandler __instance)
		{
			Plugin.NotifyFogHandlerChanged(__instance);
		}
	}
	[HarmonyPatch(typeof(OrbFogHandler), "SetFogOrigin")]
	internal static class OrbFogHandlerSetFogOriginPatch
	{
		private static void Postfix(OrbFogHandler __instance)
		{
			Plugin.NotifyFogHandlerChanged(__instance);
		}
	}
	[HarmonyPatch(typeof(OrbFogHandler), "RPC_InitFog")]
	internal static class OrbFogHandlerRpcInitFogPatch
	{
		private static void Postfix(OrbFogHandler __instance)
		{
			Plugin.NotifyFogHandlerChanged(__instance);
		}
	}
	[HarmonyPatch(typeof(Ascents), "get_fogEnabled")]
	internal static class AscentsFogEnabledPatch
	{
		private static void Postfix(ref bool __result)
		{
			if (Plugin.ShouldForceFogCoverageEverywhere())
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")]
	internal static class CharacterAfflictionsAddStatusPatch
	{
		private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE statusType, ref bool __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.ShouldSuppressLocalFogSourceStatus(__instance, statusType))
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(Campfire), "Light_Rpc")]
	internal static class CampfireLightRpcPatch
	{
		private static void Postfix(Campfire __instance)
		{
			Plugin.NotifyCampfireLit(__instance);
		}
	}
	[BepInPlugin("com.github.Thanks.FogClimb", "Fog&ColdControl", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		private enum ConfigKey
		{
			ModEnabled,
			FogColdSuppression,
			NightColdEnabled,
			FogSpeed,
			FogDelay,
			CompassEnabled,
			CompassHotkey,
			FogPauseHotkey,
			FogUiEnabled,
			CampfireLocatorUiEnabled,
			FogUiX,
			FogUiY,
			FogUiScale
		}

		private enum VanillaProgressStartUiState
		{
			Hidden,
			Unavailable,
			Tracking
		}

		private enum FogUiIconKind
		{
			State,
			Speed,
			Buffer,
			Delay,
			Distance,
			Eta,
			Direct,
			Pause,
			FogHandling,
			Night
		}

		private sealed class FogUiEntryView
		{
			public RectTransform Root;

			public Image Icon;

			public TextMeshProUGUI Text;

			public string LastText = string.Empty;

			public FogUiIconKind LastIconKind;

			public Color LastIconColor = Color.clear;
		}

		private readonly struct FogUiDisplayEntry
		{
			public readonly FogUiIconKind Kind;

			public readonly Color IconColor;

			public readonly string Text;

			public FogUiDisplayEntry(FogUiIconKind kind, Color iconColor, string text)
			{
				//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)
				Kind = kind;
				IconColor = iconColor;
				Text = text ?? string.Empty;
			}
		}

		[CompilerGenerated]
		private sealed class <EnumerateCandidateTransforms>d__435 : IEnumerable<Transform>, IEnumerable, IEnumerator<Transform>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private Transform <>2__current;

			private int <>l__initialThreadId;

			private object menuInstance;

			public object <>3__menuInstance;

			private Type menuType;

			public Type <>3__menuType;

			Transform IEnumerator<Transform>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnumerateCandidateTransforms>d__435(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				object? obj2;
				Transform val2;
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					object obj = menuInstance;
					Component val = (Component)((obj is Component) ? obj : null);
					if (val != null)
					{
						<>2__current = val.transform;
						<>1__state = 1;
						return true;
					}
					goto IL_004d;
				}
				case 1:
					<>1__state = -1;
					goto IL_004d;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_004d:
					obj2 = menuType?.GetProperty("Content", InstanceBindingFlags)?.GetValue(menuInstance);
					val2 = (Transform)((obj2 is Transform) ? obj2 : null);
					if (val2 != null)
					{
						<>2__current = val2;
						<>1__state = 2;
						return true;
					}
					break;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<Transform> IEnumerable<Transform>.GetEnumerator()
			{
				<EnumerateCandidateTransforms>d__435 <EnumerateCandidateTransforms>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<EnumerateCandidateTransforms>d__ = this;
				}
				else
				{
					<EnumerateCandidateTransforms>d__ = new <EnumerateCandidateTransforms>d__435(0);
				}
				<EnumerateCandidateTransforms>d__.menuInstance = <>3__menuInstance;
				<EnumerateCandidateTransforms>d__.menuType = <>3__menuType;
				return <EnumerateCandidateTransforms>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Transform>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <EnumerateModConfigUiRoots>d__434 : IEnumerable<Transform>, IEnumerable, IEnumerator<Transform>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private Transform <>2__current;

			private int <>l__initialThreadId;

			private object menuInstance;

			public object <>3__menuInstance;

			private Type menuType;

			public Type <>3__menuType;

			private HashSet<int> <visited>5__2;

			private IEnumerator<Transform> <>7__wrap2;

			Transform IEnumerator<Transform>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnumerateModConfigUiRoots>d__434(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<visited>5__2 = null;
				<>7__wrap2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<visited>5__2 = new HashSet<int>();
						<>7__wrap2 = EnumerateCandidateTransforms(menuInstance, menuType).GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						break;
					}
					while (<>7__wrap2.MoveNext())
					{
						Transform current = <>7__wrap2.Current;
						if ((Object)(object)current != (Object)null && <visited>5__2.Add(((Object)current).GetInstanceID()))
						{
							<>2__current = current;
							<>1__state = 1;
							return true;
						}
					}
					<>m__Finally1();
					<>7__wrap2 = null;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap2 != null)
				{
					<>7__wrap2.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<Transform> IEnumerable<Transform>.GetEnumerator()
			{
				<EnumerateModConfigUiRoots>d__434 <EnumerateModConfigUiRoots>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<EnumerateModConfigUiRoots>d__ = this;
				}
				else
				{
					<EnumerateModConfigUiRoots>d__ = new <EnumerateModConfigUiRoots>d__434(0);
				}
				<EnumerateModConfigUiRoots>d__.menuInstance = <>3__menuInstance;
				<EnumerateModConfigUiRoots>d__.menuType = <>3__menuType;
				return <EnumerateModConfigUiRoots>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Transform>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <EnumerateTargetPlayers>d__384 : IEnumerable<Player>, IEnumerable, IEnumerator<Player>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private Player <>2__current;

			private int <>l__initialThreadId;

			private HashSet<int> <yieldedPlayerIds>5__2;

			private IEnumerator<Player> <>7__wrap2;

			private Player[] <>7__wrap3;

			private int <>7__wrap4;

			Player IEnumerator<Player>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnumerateTargetPlayers>d__384(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<yieldedPlayerIds>5__2 = null;
				<>7__wrap2 = null;
				<>7__wrap3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					Player[] array;
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<yieldedPlayerIds>5__2 = new HashSet<int>();
						if (PhotonNetwork.InRoom)
						{
							<>7__wrap2 = PlayerHandler.GetAllPlayers().GetEnumerator();
							<>1__state = -3;
							goto IL_0098;
						}
						goto IL_00b2;
					case 1:
						<>1__state = -3;
						goto IL_0098;
					case 2:
						{
							<>1__state = -1;
							goto IL_0110;
						}
						IL_0110:
						<>7__wrap4++;
						goto IL_011e;
						IL_0098:
						while (<>7__wrap2.MoveNext())
						{
							Player current = <>7__wrap2.Current;
							if ((Object)(object)current != (Object)null && <yieldedPlayerIds>5__2.Add(((Object)current).GetInstanceID()))
							{
								<>2__current = current;
								<>1__state = 1;
								return true;
							}
						}
						<>m__Finally1();
						<>7__wrap2 = null;
						goto IL_00b2;
						IL_00b2:
						array = Object.FindObjectsByType<Player>((FindObjectsSortMode)0);
						<>7__wrap3 = array;
						<>7__wrap4 = 0;
						goto IL_011e;
						IL_011e:
						if (<>7__wrap4 < <>7__wrap3.Length)
						{
							Player val = <>7__wrap3[<>7__wrap4];
							if ((Object)(object)val != (Object)null && <yieldedPlayerIds>5__2.Add(((Object)val).GetInstanceID()))
							{
								<>2__current = val;
								<>1__state = 2;
								return true;
							}
							goto IL_0110;
						}
						<>7__wrap3 = null;
						return false;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap2 != null)
				{
					<>7__wrap2.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<Player> IEnumerable<Player>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <EnumerateTargetPlayers>d__384(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Player>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <GetAliasDefinitions>d__267 : IEnumerable<ConfigDefinition>, IEnumerable, IEnumerator<ConfigDefinition>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private ConfigDefinition <>2__current;

			private int <>l__initialThreadId;

			private ConfigKey configKey;

			public ConfigKey <>3__configKey;

			private string <canonicalKey>5__2;

			private string <chineseKey>5__3;

			private string[] <>7__wrap3;

			private int <>7__wrap4;

			private string <section>5__6;

			ConfigDefinition IEnumerator<ConfigDefinition>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetAliasDefinitions>d__267(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<canonicalKey>5__2 = null;
				<chineseKey>5__3 = null;
				<>7__wrap3 = null;
				<section>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0104: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Expected O, but got Unknown
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<canonicalKey>5__2 = GetConfigKeyName(configKey);
					<chineseKey>5__3 = GetKeyName(configKey, isChineseLanguage: true);
					string[] array = new string[4]
					{
						GetConfigSectionName(configKey),
						GetSectionName(configKey, isChineseLanguage: true),
						GetLegacyConfigSectionName(),
						GetLegacySectionName(isChineseLanguage: true)
					}.Where((string section) => !string.IsNullOrWhiteSpace(section)).Distinct<string>(StringComparer.Ordinal).ToArray();
					<>7__wrap3 = array;
					<>7__wrap4 = 0;
					break;
				}
				case 1:
					<>1__state = -1;
					<>2__current = new ConfigDefinition(<section>5__6, <chineseKey>5__3);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<section>5__6 = null;
					<>7__wrap4++;
					break;
				}
				if (<>7__wrap4 < <>7__wrap3.Length)
				{
					<section>5__6 = <>7__wrap3[<>7__wrap4];
					<>2__current = new ConfigDefinition(<section>5__6, <canonicalKey>5__2);
					<>1__state = 1;
					return true;
				}
				<>7__wrap3 = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<ConfigDefinition> IEnumerable<ConfigDefinition>.GetEnumerator()
			{
				<GetAliasDefinitions>d__267 <GetAliasDefinitions>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetAliasDefinitions>d__ = this;
				}
				else
				{
					<GetAliasDefinitions>d__ = new <GetAliasDefinitions>d__267(0);
				}
				<GetAliasDefinitions>d__.configKey = <>3__configKey;
				return <GetAliasDefinitions>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<ConfigDefinition>)this).GetEnumerator();
			}
		}

		public const string PluginGuid = "com.github.Thanks.FogClimb";

		public const string PluginName = "Fog&ColdControl";

		public const string PluginVersion = "1.0.0";

		private const string PreferredConfigFileName = "Thanks.Fog&ColdControl.cfg";

		private const string PreferredPluginFileName = "Thanks.Fog&ColdControl.dll";

		private static readonly string[] LegacyConfigFileNames = new string[2] { "Thanks.FogClimb.cfg", "com.github.Thanks.FogClimb.cfg" };

		private static readonly string[] LegacyPluginFileNames = new string[2] { "Thanks.FogClimb.dll", "com.github.Thanks.FogClimb.dll" };

		private const float DefaultVanillaFogSpeed = 0.3f;

		private const float DefaultFogSpeed = 0.4f;

		private const float DefaultFogDelaySeconds = 900f;

		private const float MinFogSpeed = 0.3f;

		private const float MaxFogSpeed = 20f;

		private const float MinFogDelaySeconds = 20f;

		private const float MaxFogDelaySeconds = 1000f;

		private const float DefaultFogUiX = 60f;

		private const float DefaultFogUiY = 0f;

		private const float DefaultFogUiScale = 0.9f;

		private const float MinFogUiX = -400f;

		private const float MaxFogUiX = 400f;

		private const float MinFogUiY = -500f;

		private const float MaxFogUiY = 500f;

		private const float MinFogUiScale = 0.5f;

		private const float MaxFogUiScale = 2.5f;

		private const float FogHandlerSearchIntervalSeconds = 1f;

		private const float FogStateSyncIntervalSeconds = 0.18f;

		private const float FogStateSyncSizeThreshold = 0.35f;

		private const float RemoteStatusSyncIntervalSeconds = 0.25f;

		private const float LateGameRemoteStatusSyncIntervalSeconds = 0.1f;

		private const float CompassGrantSyncIntervalSeconds = 0.75f;

		private const float FogColdPerSecond = 0.0105f;

		private const float FogSporesPerSecond = 0.005f;

		private const float RemoteFogSuppressionSafetyMultiplier = 1.12f;

		private const float NightColdPerSecond = 0.008f;

		private const float StatusChunkSize = 0.025f;

		private const float StalledFogResumeDelayRatio = 0.02f;

		private const float MinStalledFogResumeDelaySeconds = 2f;

		private const float MaxStalledFogResumeDelaySeconds = 8f;

		private const float HiddenFogDelayBufferSeconds = 10f;

		private const float FogEtaMinSampleIntervalSeconds = 0.1f;

		private const float FogEtaMinSizeDelta = 0.05f;

		private const float FogEtaMinReliableRate = 0.02f;

		private const float FogEtaRateSmoothing = 0.35f;

		private const float FogEtaDangerWindowSeconds = 45f;

		private const float FogEtaWarningWindowSeconds = 90f;

		private const float FogEtaDisplayStepSeconds = 0.5f;

		private const float FogDistanceDangerWindowUnits = 120f;

		private const float FogDistanceWarningWindowUnits = 300f;

		private const float FogDistanceEtaRefreshIntervalSeconds = 0.8f;

		private const string FogUiDistanceLabelColor = "#79E2D0";

		private const string FogUiDistanceValueColor = "#D9FFF5";

		private const string FogUiDistanceWarningLabelColor = "#FFB864";

		private const string FogUiDistanceWarningValueColor = "#FFE6BF";

		private const float PeakFogMinStartSize = 650f;

		private const float PeakFogMaxStartSize = 1400f;

		private const float PeakVerticalFogStopHeight = 1800f;

		private const float FogArrivalStopSize = 30f;

		private const KeyCode HiddenNightTestHotkey = 91;

		private const float HiddenNightTestHoldSeconds = 5f;

		private const float FallbackNightTimeNormalized = 0.85f;

		private const float RemotePlayerJoinGraceSeconds = 8f;

		private const int MaxCompassGrantsPerPlayerPerSync = 1;

		private const float CampfireCompassGrantDelaySeconds = 0.9f;

		private const float FogUiWidth = 1360f;

		private const float FogUiHeight = 34f;

		private const float FogUiHorizontalPadding = 10f;

		private const float FogUiIconSize = 19f;

		private const float FogUiIconVerticalOffset = -1f;

		private const float FogUiEntrySpacing = 14f;

		private const float FogUiEntryIconTextSpacing = 3f;

		private const float FogUiEntryTextSizeMultiplier = 0.9f;

		private const float CampfireLocatorUiWidth = 372f;

		private const float CampfireLocatorUiHeight = 24f;

		private const float CampfireLocatorTopOffset = 54f;

		private const float CampfireLocatorLineWidth = 360f;

		private const float CampfireLocatorLineHeight = 2f;

		private const float CampfireLocatorDotSize = 18f;

		private const float CampfireLocatorDotSmoothing = 12f;

		private const float CompassLobbyNoticeRightOffset = 28f;

		private const float CompassLobbyNoticeDownOffset = 0f;

		private const float CompassLobbyNoticeWidth = 735f;

		private const float CompassLobbyNoticeHeight = 81f;

		private const float CompassLobbyNoticeFontSizeMultiplier = 1.2f;

		private const float CompassLobbyNoticeLineSpacing = 1.125f;

		private const string CompassLobbyNoticeKeyColor = "#FF3B30";

		private const string FogUiSpeedLabelColor = "#8EC5FF";

		private const string FogUiSpeedValueColor = "#D6F1FF";

		private const string FogUiWaitLabelColor = "#F2C75C";

		private const string FogUiWaitValueColor = "#FFE8A3";

		private const string FogUiCountdownLabelColor = "#FF8A5B";

		private const string FogUiCountdownValueColor = "#FFD2B8";

		private const string FogUiCountdownDangerLabelColor = "#FF2D2D";

		private const string FogUiCountdownDangerValueColor = "#FFC0C0";

		private const string FogUiDelayCountdownStartLabelColor = "#FF8A8A";

		private const string FogUiDelayCountdownStartValueColor = "#FFD6D6";

		private const string FogUiDelayCountdownEndLabelColor = "#7A0000";

		private const string FogUiDelayCountdownEndValueColor = "#B31212";

		private const string FogUiStateLabelColor = "#A8E0A0";

		private const string FogUiStateRunningColor = "#B5FFB8";

		private const string FogUiStatePausedColor = "#FFC37D";

		private const string FogUiStateWaitingColor = "#FFE08A";

		private const string FogUiStateSyncingColor = "#A3D2FF";

		private const string FogUiHintLabelColor = "#B7C0CC";

		private const string FogUiHintValueColor = "#E2EAF3";

		private const string FogUiNightEnabledColor = "#9FFFA8";

		private const string FogUiNightDisabledColor = "#FFB3B3";

		private static readonly ushort CompassItemIdOverride = 0;

		private const string CompassNameKeyword = "Compass";

		private const string ModConfigPluginGuid = "com.github.PEAKModding.PEAKLib.ModConfig";

		private const string LegacyCanonicalConfigSectionName = "Fog";

		private const string CanonicalBasicConfigSectionName = "Basic";

		private const string CanonicalAdjustmentConfigSectionName = "Adjustments";

		private const string NetworkInstallStateKey = "FogClimb.Enabled";

		private const int SimplifiedChineseLanguageIndex = 9;

		private static readonly BindingFlags InstanceBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly BindingFlags StaticBindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly FieldInfo ConfigEntryDescriptionField = typeof(ConfigEntryBase).GetField("<Description>k__BackingField", InstanceBindingFlags);

		private static readonly PropertyInfo ConfigFileEntriesProperty = typeof(ConfigFile).GetProperty("Entries", InstanceBindingFlags);

		private static readonly FieldInfo BasePluginConfigBackingField = typeof(BaseUnityPlugin).GetField("<Config>k__BackingField", InstanceBindingFlags);

		private static readonly FieldInfo OrbFogHandlerOriginsField = typeof(OrbFogHandler).GetField("origins", InstanceBindingFlags);

		private static readonly FieldInfo OrbFogHandlerSphereField = typeof(OrbFogHandler).GetField("sphere", InstanceBindingFlags);

		private static readonly int StatusTypeCount = Enum.GetNames(typeof(STATUSTYPE)).Length;

		private static readonly string[] DayNightTimeMemberCandidates = new string[5] { "currentTime", "time", "timeOfDay", "timeNormalized", "cycleTime" };

		private static readonly Color CampfireLocatorLineColor = new Color(1f, 1f, 1f, 0.95f);

		private static readonly Color CampfireLocatorDotColor = new Color(1f, 0.2f, 0.2f, 1f);

		private static int _localFogStatusSuppressionDepth;

		private Harmony _harmony;

		private OrbFogHandler _orbFogHandler;

		private FogSphere _fogSphere;

		private Fog _legacyFog;

		private bool _fogStateInitialized;

		private bool _initialDelayCompleted;

		private int _trackedFogOriginId = -1;

		private float _fogDelayTimer;

		private float _fogHiddenBufferTimer;

		private float _fogHandlerSearchTimer;

		private float _lastFogStateSyncTime = -0.18f;

		private float _lastRemoteStatusSyncTime = -0.25f;

		private float _lastCompassGrantSyncTime = -0.75f;

		private bool _lastHadFogAuthority;

		private bool _lastModEnabledState;

		private bool _lastFogUiEnabledState;

		private bool _lastCampfireLocatorUiEnabledState;

		private bool _lastDetectedChineseLanguage;

		private bool _isRefreshingLanguage;

		private bool _pendingConfigFileLocalizationRefresh;

		private bool _pendingConfigFileLocalizationSave;

		private float _lastFogUiX;

		private float _lastFogUiY;

		private float _lastFogUiScale;

		private bool _hasAdvertisedInstallState;

		private bool _lastAdvertisedInstallState;

		private float _hiddenNightTestHoldTimer;

		private bool _hiddenNightTestTriggeredThisHold;

		private bool _fogPaused;

		private readonly HashSet<int> _grantedCampfireCompassIds = new HashSet<int>();

		private readonly HashSet<int> _restoredCheckpointCampfireIds = new HashSet<int>();

		private readonly Dictionary<int, int> _playerCompassGrantCounts = new Dictionary<int, int>();

		private readonly Dictionary<int, float> _remoteFogSuppressionDebt = new Dictionary<int, float>();

		private readonly Dictionary<int, float> _remoteFogSporesSuppressionDebt = new Dictionary<int, float>();

		private readonly Dictionary<int, float> _remotePlayerFirstSeenTimes = new Dictionary<int, float>();

		private readonly Dictionary<int, int> _remotePlayerCompassBaselineCounts = new Dictionary<int, int>();

		private readonly Dictionary<int, float> _pendingCampfireCompassGrantTimes = new Dictionary<int, float>();

		private Item _compassItem;

		private RectTransform _fogUiRect;

		private TextMeshProUGUI _fogUiText;

		private string _lastFogUiRenderedText = string.Empty;

		private RectTransform _fogUiEntriesRect;

		private readonly List<FogUiEntryView> _fogUiEntryViews = new List<FogUiEntryView>();

		private readonly List<FogUiDisplayEntry> _fogUiDisplayEntries = new List<FogUiDisplayEntry>(8);

		private readonly Dictionary<FogUiIconKind, Sprite> _fogUiIconSprites = new Dictionary<FogUiIconKind, Sprite>();

		private Sprite _campfireLocatorDotSprite;

		private RectTransform _campfireLocatorUiRect;

		private RectTransform _campfireLocatorDotRect;

		private float _campfireLocatorCurrentDotX;

		private RectTransform _compassLobbyNoticeRect;

		private TextMeshProUGUI _compassLobbyNoticeText;

		private string _lastCompassLobbyNoticeText = string.Empty;

		private bool _initialCompassGranted;

		private int _totalCompassGrantCount;

		private bool _hasSyncedFogStateSnapshot;

		private int _lastSyncedFogOriginId = -1;

		private float _lastSyncedFogSize = float.NaN;

		private bool _lastSyncedFogIsMoving;

		private bool _lastSyncedFogHasArrived;

		private int _delayedFogOriginId = -1;

		private int _pendingSyntheticFogSegmentId = -1;

		private int _activeSyntheticFogSegmentId = -1;

		private Vector3 _syntheticFogPoint;

		private float _syntheticFogStartSize;

		private int _fogEtaTrackedOriginId = -1;

		private float _fogEtaLastObservedSize = float.NaN;

		private float _fogEtaLastObservedTime = -1f;

		private float _fogEtaEstimatedUnitsPerSecond;

		private bool _fogEtaHasReliableRate;

		private float _fogDistanceEtaLastRefreshTime = -1f;

		private bool _fogDistanceEtaHasSnapshot;

		private bool _fogDistanceEtaHasEta;

		private float _fogDistanceEtaRemainingDistance;

		private float _fogDistanceEtaSeconds;

		internal static Plugin Instance { get; private set; }

		internal static ConfigEntry<bool> ModEnabled { get; private set; }

		internal static ConfigEntry<bool> FogColdSuppression { get; private set; }

		internal static ConfigEntry<bool> NightColdEnabled { get; private set; }

		internal static ConfigEntry<float> FogSpeed { get; private set; }

		internal static ConfigEntry<float> FogDelay { get; private set; }

		internal static ConfigEntry<bool> CompassEnabled { get; private set; }

		internal static ConfigEntry<KeyCode> CompassHotkey { get; private set; }

		internal static ConfigEntry<KeyCode> FogPauseHotkey { get; private set; }

		internal static ConfigEntry<bool> FogUiEnabled { get; private set; }

		internal static ConfigEntry<bool> CampfireLocatorUiEnabled { get; private set; }

		internal static ConfigEntry<float> FogUiX { get; private set; }

		internal static ConfigEntry<float> FogUiY { get; private set; }

		internal static ConfigEntry<float> FogUiScale { get; private set; }

		private void Awake()
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			Instance = this;
			_lastHadFogAuthority = HasFogAuthority();
			TryCleanupGeneratedBackupFile();
			TryCleanupLegacyPluginFile();
			EnsurePreferredConfigFile();
			_lastDetectedChineseLanguage = DetectChineseLanguage();
			InitializeConfig(_lastDetectedChineseLanguage);
			RegisterConfigChangeHandlers();
			_lastModEnabledState = IsModFeatureEnabled();
			_lastFogUiEnabledState = FogUiEnabled?.Value ?? true;
			_lastCampfireLocatorUiEnabledState = CampfireLocatorUiEnabled?.Value ?? true;
			_lastFogUiX = FogUiX?.Value ?? 60f;
			_lastFogUiY = FogUiY?.Value ?? 0f;
			_lastFogUiScale = FogUiScale?.Value ?? 0.9f;
			MarkConfigFileLocalizationDirty(saveConfigFile: true);
			_harmony = new Harmony("com.github.Thanks.FogClimb");
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			SceneManager.sceneLoaded += OnSceneLoaded;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[Fog&ColdControl] Loaded.");
		}

		private void OnDestroy()
		{
			UnregisterConfigChangeHandlers();
			SceneManager.sceneLoaded -= OnSceneLoaded;
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			CleanupFogUi();
			CleanupCampfireLocatorUi();
			CleanupCompassLobbyNotice();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void InitializeConfig(bool isChineseLanguage)
		{
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.ModEnabled), GetConfigKeyName(ConfigKey.ModEnabled), true, CreateConfigDescription(ConfigKey.ModEnabled, isChineseLanguage));
			FogColdSuppression = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.FogColdSuppression), GetConfigKeyName(ConfigKey.FogColdSuppression), false, CreateConfigDescription(ConfigKey.FogColdSuppression, isChineseLanguage));
			NightColdEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.NightColdEnabled), GetConfigKeyName(ConfigKey.NightColdEnabled), true, CreateConfigDescription(ConfigKey.NightColdEnabled, isChineseLanguage));
			FogSpeed = ((BaseUnityPlugin)this).Config.Bind<float>(GetConfigSectionName(ConfigKey.FogSpeed), GetConfigKeyName(ConfigKey.FogSpeed), 0.4f, CreateConfigDescription(ConfigKey.FogSpeed, isChineseLanguage));
			FogDelay = ((BaseUnityPlugin)this).Config.Bind<float>(GetConfigSectionName(ConfigKey.FogDelay), GetConfigKeyName(ConfigKey.FogDelay), 900f, CreateConfigDescription(ConfigKey.FogDelay, isChineseLanguage));
			CompassEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.CompassEnabled), GetConfigKeyName(ConfigKey.CompassEnabled), false, CreateConfigDescription(ConfigKey.CompassEnabled, isChineseLanguage));
			CompassHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>(GetConfigSectionName(ConfigKey.CompassHotkey), GetConfigKeyName(ConfigKey.CompassHotkey), (KeyCode)103, CreateConfigDescription(ConfigKey.CompassHotkey, isChineseLanguage));
			FogPauseHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>(GetConfigSectionName(ConfigKey.FogPauseHotkey), GetConfigKeyName(ConfigKey.FogPauseHotkey), (KeyCode)121, CreateConfigDescription(ConfigKey.FogPauseHotkey, isChineseLanguage));
			FogUiEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.FogUiEnabled), GetConfigKeyName(ConfigKey.FogUiEnabled), true, CreateConfigDescription(ConfigKey.FogUiEnabled, isChineseLanguage));
			CampfireLocatorUiEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(GetConfigSectionName(ConfigKey.CampfireLocatorUiEnabled), GetConfigKeyName(ConfigKey.CampfireLocatorUiEnabled), true, CreateConfigDescription(ConfigKey.CampfireLocatorUiEnabled, isChineseLanguage));
			FogUiX = ((BaseUnityPlugin)this).Config.Bind<float>(GetConfigSectionName(ConfigKey.FogUiX), GetConfigKeyName(ConfigKey.FogUiX), 60f, CreateConfigDescription(ConfigKey.FogUiX, isChineseLanguage));
			FogUiY = ((BaseUnityPlugin)this).Config.Bind<float>(GetConfigSectionName(ConfigKey.FogUiY), GetConfigKeyName(ConfigKey.FogUiY), 0f, CreateConfigDescription(ConfigKey.FogUiY, isChineseLanguage));
			FogUiScale = ((BaseUnityPlugin)this).Config.Bind<float>(GetConfigSectionName(ConfigKey.FogUiScale), GetConfigKeyName(ConfigKey.FogUiScale), 0.9f, CreateConfigDescription(ConfigKey.FogUiScale, isChineseLanguage));
			MigrateLocalizedConfigEntries();
			ClampConfigValues();
		}

		private void EnsurePreferredConfigFile()
		{
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			try
			{
				string configDirectory = Paths.ConfigPath;
				if (!string.IsNullOrWhiteSpace(configDirectory))
				{
					Directory.CreateDirectory(configDirectory);
					string text = Path.Combine(configDirectory, "Thanks.Fog&ColdControl.cfg");
					string text2 = LegacyConfigFileNames.Select((string fileName) => Path.Combine(configDirectory, fileName)).Concat(new string[1] { Path.Combine(configDirectory, "com.github.Thanks.FogClimb.cfg") }).Distinct<string>(StringComparer.OrdinalIgnoreCase)
						.ToArray()
						.FirstOrDefault(File.Exists);
					if (!string.IsNullOrWhiteSpace(text2) && !string.Equals(text, text2, StringComparison.OrdinalIgnoreCase) && !File.Exists(text))
					{
						File.Move(text2, text);
						((BaseUnityPlugin)this).Logger.LogInfo((object)"[Fog&ColdControl] Migrated config file to Thanks.Fog&ColdControl.cfg.");
					}
					if (!(BasePluginConfigBackingField == null) && (((BaseUnityPlugin)this).Config == null || !string.Equals(((BaseUnityPlugin)this).Config.ConfigFilePath, text, StringComparison.OrdinalIgnoreCase)))
					{
						ConfigFile value = new ConfigFile(text, true);
						BasePluginConfigBackingField.SetValue(this, value);
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[Fog&ColdControl] Failed to switch config path to Thanks.Fog&ColdControl.cfg: " + ex.Message));
			}
		}

		private ConfigDescription CreateConfigDescription(ConfigKey configKey, bool isChineseLanguage)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			return (ConfigDescription)(configKey switch
			{
				ConfigKey.FogSpeed => (object)new ConfigDescription(GetLocalizedDescription(configKey, isChineseLanguage), (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 20f), Array.Empty<object>()), 
				ConfigKey.FogDelay => (object)new ConfigDescription(GetLocalizedDescription(configKey, isChineseLanguage), (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 1000f), Array.Empty<object>()), 
				ConfigKey.FogUiX => (object)new ConfigDescription(GetLocalizedDescription(configKey, isChineseLanguage), (AcceptableValueBase)(object)new AcceptableValueRange<float>(-400f, 400f), Array.Empty<object>()), 
				ConfigKey.FogUiY => (object)new ConfigDescription(GetLocalizedDescription(configKey, isChineseLanguage), (AcceptableValueBase)(object)new AcceptableValueRange<float>(-500f, 500f), Array.Empty<object>()), 
				ConfigKey.FogUiScale => (object)new ConfigDescription(GetLocalizedDescription(configKey, isChineseLanguage), (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2.5f), Array.Empty<object>()), 
				_ => (object)new ConfigDescription(GetLocalizedDescription(configKey, isChineseLanguage), (AcceptableValueBase)null, Array.Empty<object>()), 
			});
		}

		private void MigrateLocalizedConfigEntries()
		{
			IDictionary orphanedEntries = GetOrphanedEntries(((BaseUnityPlugin)this).Config);
			if (orphanedEntries != null && orphanedEntries.Count != 0 && (false | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)ModEnabled, ConfigKey.ModEnabled, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)FogColdSuppression, ConfigKey.FogColdSuppression, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)NightColdEnabled, ConfigKey.NightColdEnabled, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)FogSpeed, ConfigKey.FogSpeed, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)FogDelay, ConfigKey.FogDelay, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)CompassEnabled, ConfigKey.CompassEnabled, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)CompassHotkey, ConfigKey.CompassHotkey, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)FogPauseHotkey, ConfigKey.FogPauseHotkey, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)FogUiEnabled, ConfigKey.FogUiEnabled, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)CampfireLocatorUiEnabled, ConfigKey.CampfireLocatorUiEnabled, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)FogUiX, ConfigKey.FogUiX, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)FogUiY, ConfigKey.FogUiY, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)FogUiScale, ConfigKey.FogUiScale, orphanedEntries)))
			{
				((BaseUnityPlugin)this).Config.Save();
			}
		}

		private static bool TryMigrateLocalizedConfigValue(ConfigEntryBase entry, ConfigKey configKey, IDictionary orphanedEntries)
		{
			if (((entry != null) ? entry.Definition : null) == (ConfigDefinition)null || orphanedEntries == null)
			{
				return false;
			}
			bool flag = false;
			foreach (ConfigDefinition aliasDefinition in GetAliasDefinitions(configKey))
			{
				if (DefinitionsEqual(aliasDefinition, entry.Definition) || !orphanedEntries.Contains(aliasDefinition))
				{
					continue;
				}
				if (!flag)
				{
					object obj = orphanedEntries[aliasDefinition];
					if (obj != null)
					{
						entry.SetSerializedValue(obj.ToString());
					}
					flag = true;
				}
				orphanedEntries.Remove(aliasDefinition);
			}
			return flag;
		}

		[IteratorStateMachine(typeof(<GetAliasDefinitions>d__267))]
		private static IEnumerable<ConfigDefinition> GetAliasDefinitions(ConfigKey configKey)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetAliasDefinitions>d__267(-2)
			{
				<>3__configKey = configKey
			};
		}

		private static IDictionary GetOrphanedEntries(ConfigFile configFile)
		{
			return ((object)configFile)?.GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(configFile) as IDictionary;
		}

		private static bool DefinitionsEqual(ConfigDefinition left, ConfigDefinition right)
		{
			if (string.Equals((left != null) ? left.Section : null, (right != null) ? right.Section : null, StringComparison.Ordinal))
			{
				return string.Equals((left != null) ? left.Key : null, (right != null) ? right.Key : null, StringComparison.Ordinal);
			}
			return false;
		}

		private static void ClampConfigValues()
		{
			if (FogSpeed != null)
			{
				FogSpeed.Value = Mathf.Clamp(FogSpeed.Value, 0.3f, 20f);
			}
			if (FogDelay != null)
			{
				FogDelay.Value = Mathf.Clamp(FogDelay.Value, 20f, 1000f);
			}
			if (FogUiX != null)
			{
				FogUiX.Value = Mathf.Clamp(FogUiX.Value, -400f, 400f);
			}
			if (FogUiY != null)
			{
				FogUiY.Value = Mathf.Clamp(FogUiY.Value, -500f, 500f);
			}
			if (FogUiScale != null)
			{
				FogUiScale.Value = Mathf.Clamp(FogUiScale.Value, 0.5f, 2.5f);
			}
			NormalizeShootZombiesFogUiDefaults();
		}

		private static void NormalizeShootZombiesFogUiDefaults()
		{
			if (FogUiX != null && FogUiY != null && FogUiScale != null)
			{
				bool num = Approximately(FogUiX.Value, 70f) && Approximately(FogUiY.Value, 4f) && Approximately(FogUiScale.Value, 1.1f);
				bool flag = Approximately(FogUiX.Value, 10f) && Approximately(FogUiY.Value, 10f) && Approximately(FogUiScale.Value, 1.2f);
				bool flag2 = Approximately(FogUiX.Value, 4f) && Approximately(FogUiY.Value, 4f) && Approximately(FogUiScale.Value, 1.1f);
				bool flag3 = Approximately(FogUiX.Value, 60f) && Approximately(FogUiY.Value, -200f) && Approximately(FogUiScale.Value, 1.1f);
				bool flag4 = Approximately(FogUiX.Value, 60f) && Approximately(FogUiY.Value, -200f) && Approximately(FogUiScale.Value, 1f);
				bool flag5 = Approximately(FogUiX.Value, 60f) && Approximately(FogUiY.Value, 16f) && Approximately(FogUiScale.Value, 1.2f);
				bool flag6 = Approximately(FogUiX.Value, 60f) && Approximately(FogUiY.Value, 0f) && Approximately(FogUiScale.Value, 1.2f);
				if (num || flag || flag2 || flag3 || flag4 || flag5 || flag6)
				{
					FogUiX.Value = 60f;
					FogUiY.Value = 0f;
					FogUiScale.Value = 0.9f;
				}
			}
		}

		private static bool Approximately(float left, float right)
		{
			return Mathf.Abs(left - right) < 0.001f;
		}

		private void RegisterConfigChangeHandlers()
		{
			if (((BaseUnityPlugin)this).Config != null)
			{
				((BaseUnityPlugin)this).Config.SettingChanged -= OnConfigSettingChanged;
				((BaseUnityPlugin)this).Config.SettingChanged += OnConfigSettingChanged;
			}
		}

		private void UnregisterConfigChangeHandlers()
		{
			if (((BaseUnityPlugin)this).Config != null)
			{
				((BaseUnityPlugin)this).Config.SettingChanged -= OnConfigSettingChanged;
			}
		}

		private void OnConfigSettingChanged(object sender, SettingChangedEventArgs e)
		{
			MarkConfigFileLocalizationDirty(saveConfigFile: false);
		}

		private void MarkConfigFileLocalizationDirty(bool saveConfigFile)
		{
			_pendingConfigFileLocalizationRefresh = true;
			_pendingConfigFileLocalizationSave |= saveConfigFile;
		}

		private void HandlePendingConfigFileLocalizationRefresh()
		{
			if (_pendingConfigFileLocalizationRefresh && !_isRefreshingLanguage)
			{
				bool lastDetectedChineseLanguage = _lastDetectedChineseLanguage;
				bool pendingConfigFileLocalizationSave = _pendingConfigFileLocalizationSave;
				_pendingConfigFileLocalizationRefresh = false;
				_pendingConfigFileLocalizationSave = false;
				TryRefreshLocalizedConfigFile(lastDetectedChineseLanguage, pendingConfigFileLocalizationSave);
			}
		}

		private void Update()
		{
			bool flag = IsModFeatureEnabled();
			HandleAuthorityChangeIfNeeded(flag);
			if (flag != _lastModEnabledState)
			{
				_lastModEnabledState = flag;
				if (!flag)
				{
					RestoreVanillaFogSpeed();
					ResetFogRuntimeState();
					SetFogUiVisible(visible: false);
				}
				else
				{
					_fogStateInitialized = false;
					_lastFogStateSyncTime = -0.18f;
					_lastRemoteStatusSyncTime = -0.25f;
					_lastCompassGrantSyncTime = -0.75f;
				}
			}
			TryResolveRuntimeObjects();
			if (flag)
			{
				EnsureFogCoverageAcrossAllLevels();
			}
			UpdateLocalInstallStateAdvertisement();
			HandleLanguageChangeIfNeeded();
			HandlePendingConfigFileLocalizationRefresh();
			HandleFogUiConfigChanges();
			HandleManualCompassHotkey();
			HandleFogPauseHotkey();
			HandleHiddenNightTestHotkey();
			RefreshRemotePlayerJoinGraceState();
			ProcessPendingCampfireCompassGrants();
			if (!flag)
			{
				UpdateFogUi();
				UpdateCampfireLocatorUi();
				UpdateCompassLobbyNotice();
				return;
			}
			if ((Object)(object)_orbFogHandler != (Object)null && !_fogStateInitialized)
			{
				InitializeFogRuntimeState(_orbFogHandler);
			}
			if ((Object)(object)_orbFogHandler != (Object)null && HasFogAuthority())
			{
				TryRestoreCheckpointCampfireDelay();
				UpdateAuthorityFogMode();
				SyncFogStateToGuestsIfNeeded();
				SyncRemoteStatusSuppressionIfNeeded();
				SyncCompassGrantsToPlayersIfNeeded();
			}
			UpdateFogArrivalEstimate();
			UpdateFogUi();
			UpdateCampfireLocatorUi();
			UpdateCompassLobbyNotice();
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			ResetFogRuntimeState();
			_orbFogHandler = null;
			_fogSphere = null;
			_legacyFog = null;
			_compassItem = null;
			CleanupFogUi();
			CleanupCampfireLocatorUi();
			CleanupCompassLobbyNotice();
		}

		private void TryResolveRuntimeObjects()
		{
			bool flag = (Object)(object)_orbFogHandler == (Object)null;
			bool flag2 = (Object)(object)_fogSphere == (Object)null;
			bool flag3 = (Object)(object)_legacyFog == (Object)null;
			if (!flag && !flag2 && !flag3)
			{
				return;
			}
			_fogHandlerSearchTimer -= Time.unscaledDeltaTime;
			if (_fogHandlerSearchTimer > 0f)
			{
				return;
			}
			_fogHandlerSearchTimer = 1f;
			if (flag)
			{
				_orbFogHandler = Object.FindAnyObjectByType<OrbFogHandler>();
				if ((Object)(object)_orbFogHandler != (Object)null)
				{
					_fogStateInitialized = false;
				}
			}
			if (flag2)
			{
				_fogSphere = Object.FindAnyObjectByType<FogSphere>();
			}
			if (flag3)
			{
				_legacyFog = Object.FindAnyObjectByType<Fog>();
			}
		}

		private void EnsureFogCoverageAcrossAllLevels()
		{
			EnsureFogCoverage(_orbFogHandler);
		}

		private void EnsureFogCoverage(OrbFogHandler fogHandler)
		{
			if (!ShouldForceFogCoverageEverywhere() || (Object)(object)fogHandler == (Object)null)
			{
				return;
			}
			FogSphereOrigin[] array = ResolveFogOrigins(fogHandler);
			for (int i = 0; i < array.Length; i++)
			{
				if (!ShouldDeferFogToVanillaForSegment((Segment)(byte)i))
				{
					FogSphereOrigin val = array[i];
					if (!((Object)(object)val == (Object)null) && val.disableFog)
					{
						val.disableFog = false;
					}
				}
			}
			if (ShouldDeferFogToVanillaInCurrentScene())
			{
				return;
			}
			FogSphere val2 = ResolveFogSphere(fogHandler);
			if (!((Object)(object)val2 == (Object)null))
			{
				_fogSphere = val2;
				if (!((Component)val2).gameObject.activeSelf)
				{
					((Component)val2).gameObject.SetActive(true);
				}
				if (fogHandler.currentSize > 0f && val2.currentSize <= 0f)
				{
					val2.currentSize = fogHandler.currentSize;
				}
			}
		}

		private static FogSphereOrigin[] ResolveFogOrigins(OrbFogHandler fogHandler)
		{
			if ((Object)(object)fogHandler == (Object)null)
			{
				return Array.Empty<FogSphereOrigin>();
			}
			if (OrbFogHandlerOriginsField?.GetValue(fogHandler) is FogSphereOrigin[] array && array.Length != 0)
			{
				return array;
			}
			FogSphereOrigin[] componentsInChildren = ((Component)fogHandler).GetComponentsInChildren<FogSphereOrigin>(true);
			if (componentsInChildren != null && componentsInChildren.Length != 0)
			{
				try
				{
					OrbFogHandlerOriginsField?.SetValue(fogHandler, componentsInChildren);
				}
				catch
				{
				}
				return componentsInChildren;
			}
			return Array.Empty<FogSphereOrigin>();
		}

		private static FogSphere ResolveFogSphere(OrbFogHandler fogHandler)
		{
			if ((Object)(object)fogHandler == (Object)null)
			{
				return null;
			}
			object? obj = OrbFogHandlerSphereField?.GetValue(fogHandler);
			FogSphere val = (FogSphere)((obj is FogSphere) ? obj : null);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			val = ((Component)fogHandler).GetComponentInChildren<FogSphere>(true);
			if ((Object)(object)val != (Object)null)
			{
				try
				{
					OrbFogHandlerSphereField?.SetValue(fogHandler, val);
				}
				catch
				{
				}
			}
			return val;
		}

		private void InitializeFogRuntimeState(OrbFogHandler fogHandler)
		{
			_fogStateInitialized = true;
			_trackedFogOriginId = (((Object)(object)fogHandler != (Object)null) ? fogHandler.currentID : (-1));
			_initialDelayCompleted = ShouldSkipInitialDelay(fogHandler);
			_fogDelayTimer = ((!_initialDelayCompleted) ? 0f : (FogDelay?.Value ?? 0f));
			_fogHiddenBufferTimer = (_initialDelayCompleted ? 10f : 0f);
			ResetFogArrivalEstimate();
		}

		private static bool HasAnyConfiguredFogDelay()
		{
			return true;
		}

		private static bool TryGetVanillaProgressStartThresholds(OrbFogHandler fogHandler, out float requiredHeight, out float requiredForward)
		{
			requiredHeight = 0f;
			requiredForward = 0f;
			if ((Object)(object)fogHandler == (Object)null)
			{
				return false;
			}
			requiredHeight = fogHandler.currentStartHeight;
			requiredForward = fogHandler.currentStartForward;
			if (!float.IsNaN(requiredHeight) && !float.IsInfinity(requiredHeight) && !float.IsNaN(requiredForward))
			{
				return !float.IsInfinity(requiredForward);
			}
			return false;
		}

		private static bool TryGetVanillaProgressStartProgress(OrbFogHandler fogHandler, out int passedCount, out int totalCount, out float requiredHeight, out float requiredForward)
		{
			//IL_0067: 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)
			passedCount = 0;
			totalCount = 0;
			requiredHeight = 0f;
			requiredForward = 0f;
			if (Ascents.currentAscent < 0 || !TryGetVanillaProgressStartThresholds(fogHandler, out requiredHeight, out requiredForward))
			{
				return false;
			}
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (!((Object)(object)allCharacter?.data == (Object)null) && !allCharacter.data.dead)
				{
					totalCount++;
					if (allCharacter.Center.y >= requiredHeight && allCharacter.Center.z >= requiredForward)
					{
						passedCount++;
					}
				}
			}
			return totalCount > 0;
		}

		private bool ShouldSkipInitialDelay(OrbFogHandler fogHandler)
		{
			if ((Object)(object)fogHandler == (Object)null || !HasAnyConfiguredFogDelay())
			{
				return true;
			}
			if (IsCampfireDelayPendingForOrigin(fogHandler.currentID))
			{
				return false;
			}
			if (fogHandler.currentID <= 0)
			{
				if (!fogHandler.isMoving && !(fogHandler.currentWaitTime > 1f))
				{
					return fogHandler.hasArrived;
				}
				return true;
			}
			if (ShouldHoldFogUntilCampfireActivation(fogHandler))
			{
				return false;
			}
			if (!fogHandler.isMoving && !(fogHandler.currentWaitTime > 1f))
			{
				return fogHandler.hasArrived;
			}
			return true;
		}

		private void UpdateAuthorityFogMode()
		{
			if ((Object)(object)_orbFogHandler == (Object)null)
			{
				return;
			}
			ClampConfigValues();
			if (ShouldDeferFogToVanillaInCurrentScene())
			{
				ClearSyntheticFogStage();
				_pendingSyntheticFogSegmentId = -1;
				_delayedFogOriginId = -1;
				RestoreVanillaFogSpeed();
				return;
			}
			TryAlignFogOriginToCurrentSegment();
			TryUpdateSyntheticFogStage();
			UpdateTrackedFogOrigin();
			if (ShouldAutoCompleteDelayForCurrentOrigin(_orbFogHandler))
			{
				_initialDelayCompleted = true;
			}
			if (!_initialDelayCompleted)
			{
				_orbFogHandler.speed = 0f;
				if (!ShouldEnforceConfiguredDelay(_orbFogHandler) || TryStartFogFromVanillaProgressTrigger(_orbFogHandler))
				{
					return;
				}
				if (_fogHiddenBufferTimer < 10f)
				{
					_fogHiddenBufferTimer = Mathf.Min(_fogHiddenBufferTimer + Time.unscaledDeltaTime, 10f);
					if (_fogHiddenBufferTimer < 10f)
					{
						return;
					}
				}
				float num = FogDelay?.Value ?? 0f;
				if (num <= 0f)
				{
					_initialDelayCompleted = true;
					ClearPendingCampfireDelayForOrigin(_orbFogHandler.currentID);
					if (!_orbFogHandler.isMoving)
					{
						StartFogMovement();
					}
					return;
				}
				_fogDelayTimer += Time.unscaledDeltaTime;
				if (_fogDelayTimer >= num)
				{
					_fogDelayTimer = num;
					_initialDelayCompleted = true;
					ClearPendingCampfireDelayForOrigin(_orbFogHandler.currentID);
					if (!_orbFogHandler.isMoving)
					{
						StartFogMovement();
					}
				}
			}
			else if (_fogPaused)
			{
				ApplyPausedFogState(syncImmediately: false);
			}
			else
			{
				_orbFogHandler.speed = FogSpeed.Value;
				TryAutoStartCustomRunFogIfNeeded();
				TryAutoResumeStalledFogMovement();
				TryGrantInitialCompassIfNeeded();
			}
		}

		private bool TryStartFogFromVanillaProgressTrigger(OrbFogHandler fogHandler)
		{
			if (!TryGetVanillaProgressStartProgress(fogHandler, out var passedCount, out var totalCount, out var requiredHeight, out var requiredForward))
			{
				return false;
			}
			if (passedCount < totalCount)
			{
				return false;
			}
			float num = Mathf.Max(10f - _fogHiddenBufferTimer, 0f);
			float num2 = Mathf.Max(FogDelay?.Value ?? 900f, 0f);
			float num3 = Mathf.Max(num2 - _fogDelayTimer, 0f);
			_initialDelayCompleted = true;
			_fogHiddenBufferTimer = 10f;
			_fogDelayTimer = num2;
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] Starting fog early from vanilla progress trigger at origin {1}. progress={2}/{3}, thresholdY={4:F1}, thresholdZ={5:F1}, remainingBuffer={6:F1}s, remainingDelay={7:F1}s.", "Fog&ColdControl", fogHandler.currentID, passedCount, totalCount, requiredHeight, requiredForward, num, num3));
			StartFogMovement();
			return true;
		}

		private bool IsCampfireDelayPendingForOrigin(int originId)
		{
			if (originId >= 0)
			{
				return _delayedFogOriginId == originId;
			}
			return false;
		}

		private bool ShouldAutoCompleteDelayForCurrentOrigin(OrbFogHandler fogHandler)
		{
			if ((Object)(object)fogHandler == (Object)null)
			{
				return true;
			}
			if (fogHandler.currentID == 0)
			{
				return false;
			}
			if (ShouldHoldFogUntilCampfireActivation(fogHandler))
			{
				return false;
			}
			return !IsCampfireDelayPendingForOrigin(fogHandler.currentID);
		}

		private bool ShouldEnforceConfiguredDelay(OrbFogHandler fogHandler)
		{
			if (_initialDelayCompleted || (Object)(object)fogHandler == (Object)null || !HasAnyConfiguredFogDelay())
			{
				return false;
			}
			if (fogHandler.currentID != 0)
			{
				return IsCampfireDelayPendingForOrigin(fogHandler.currentID);
			}
			return true;
		}

		private bool ShouldHoldFogUntilCampfireActivation(OrbFogHandler fogHandler)
		{
			if ((Object)(object)fogHandler != (Object)null && fogHandler.currentID > 0 && !IsCampfireDelayPendingForOrigin(fogHandler.currentID) && !fogHandler.isMoving && !fogHandler.hasArrived)
			{
				return !_initialDelayCompleted;
			}
			return false;
		}

		private bool HasVisibleFogDelayCountdown()
		{
			return _fogHiddenBufferTimer >= 10f;
		}

		private void ClearPendingCampfireDelayForOrigin(int originId)
		{
			if (_delayedFogOriginId == originId)
			{
				_delayedFogOriginId = -1;
			}
		}

		private int GetAvailableFogOriginCount()
		{
			if (!((Object)(object)_orbFogHandler == (Object)null))
			{
				return ResolveFogOrigins(_orbFogHandler).Length;
			}
			return 0;
		}

		private bool TryResolveFogPointForCurrentOrigin(out Vector3 fogPoint, out string pointDescription)
		{
			//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_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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			fogPoint = Vector3.zero;
			pointDescription = string.Empty;
			if ((Object)(object)_fogSphere != (Object)null)
			{
				fogPoint = _fogSphere.fogPoint;
				pointDescription = "fogSphere";
				return true;
			}
			if ((Object)(object)_orbFogHandler == (Object)null)
			{
				return false;
			}
			FogSphereOrigin[] array = ResolveFogOrigins(_orbFogHandler);
			if (array.Length == 0)
			{
				return false;
			}
			int num = Mathf.Clamp(_orbFogHandler.currentID, 0, array.Length - 1);
			FogSphereOrigin val = array[num] ?? ((IEnumerable<FogSphereOrigin>)array).LastOrDefault((Func<FogSphereOrigin, bool>)((FogSphereOrigin candidate) => (Object)(object)candidate != (Object)null));
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			fogPoint = ((Component)val).transform.position;
			pointDescription = $"origin-{num}";
			return true;
		}

		private bool TryGetPreviousRealFogOriginSize(out float previousOriginSize)
		{
			previousOriginSize = 900f;
			FogSphereOrigin[] array = ResolveFogOrigins(_orbFogHandler);
			if (array.Length == 0)
			{
				return false;
			}
			int num = Mathf.Clamp(array.Length - 2, 0, array.Length - 1);
			FogSphereOrigin val = array[num];
			if ((Object)(object)val == (Object)null || val.size <= 0f)
			{
				return false;
			}
			previousOriginSize = val.size;
			return true;
		}

		private bool TryResolveFogStageCoverageAnchor(Segment fogStageSegment, out Vector3 stageAnchor, out string anchorDescription)
		{
			//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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			//IL_01b1: 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_003f: 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_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected I4, but got Unknown
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: 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_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			stageAnchor = Vector3.zero;
			anchorDescription = string.Empty;
			MapHandler instance = Singleton<MapHandler>.Instance;
			if ((int)fogStageSegment >= 5 && (Object)(object)instance != (Object)null && (Object)(object)instance.respawnThePeak != (Object)null)
			{
				stageAnchor = instance.respawnThePeak.position;
				anchorDescription = "respawnThePeak";
				return true;
			}
			if ((int)fogStageSegment >= 4 && (Object)(object)instance != (Object)null && (Object)(object)instance.respawnTheKiln != (Object)null)
			{
				stageAnchor = instance.respawnTheKiln.position;
				anchorDescription = "respawnTheKiln";
				return true;
			}
			if ((Object)(object)instance != (Object)null && instance.segments != null && instance.segments.Length != 0)
			{
				int num = Mathf.Clamp((int)fogStageSegment, 0, instance.segments.Length - 1);
				MapSegment val = instance.segments[num];
				if (val != null)
				{
					if ((Object)(object)val.segmentCampfire != (Object)null)
					{
						Campfire componentInChildren = val.segmentCampfire.GetComponentInChildren<Campfire>(true);
						if ((Object)(object)componentInChildren != (Object)null)
						{
							stageAnchor = ((Component)componentInChildren).transform.position;
							anchorDescription = $"{fogStageSegment} campfire";
							return true;
						}
						stageAnchor = val.segmentCampfire.transform.position;
						anchorDescription = $"{fogStageSegment} segmentCampfire";
						return true;
					}
					if ((Object)(object)val.reconnectSpawnPos != (Object)null)
					{
						stageAnchor = val.reconnectSpawnPos.position;
						anchorDescription = $"{fogStageSegment} reconnectSpawnPos";
						return true;
					}
					if ((Object)(object)val.segmentParent != (Object)null)
					{
						stageAnchor = val.segmentParent.transform.position;
						anchorDescription = $"{fogStageSegment} segmentParent";
						return true;
					}
				}
			}
			if (TryResolveSyntheticTargetAnchor(fogStageSegment, out stageAnchor, out anchorDescription))
			{
				return true;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter != (Object)null)
			{
				stageAnchor = localCharacter.Center;
				anchorDescription = "localCharacter";
				return true;
			}
			Character val2 = ((IEnumerable<Character>)Character.AllCharacters).FirstOrDefault((Func<Character, bool>)((Character character) => (Object)(object)character != (Object)null && (Object)(object)character.data != (Object)null && !character.data.dead));
			if ((Object)(object)val2 != (Object)null)
			{
				stageAnchor = val2.Center;
				anchorDescription = "firstAliveCharacter";
				return true;
			}
			return false;
		}

		private float ComputeFogStartSizeForStage(Segment fogStageSegment, Vector3 fogPoint, float baseSize, float minSize, float maxSize, float anchorMargin, float playerMargin)
		{
			//IL_000a: 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_0018: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(baseSize, minSize);
			if (TryResolveFogStageCoverageAnchor(fogStageSegment, out var stageAnchor, out var _))
			{
				num = Mathf.Max(num, Vector3.Distance(fogPoint, stageAnchor) + anchorMargin);
			}
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter.data == (Object)null) && !allCharacter.data.dead)
				{
					num = Mathf.Max(num, Vector3.Distance(fogPoint, allCharacter.Center) + playerMargin);
				}
			}
			return Mathf.Clamp(num, minSize, maxSize);
		}

		private static bool ShouldUseCustomFogPositionForSegment(Segment segment)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			if ((int)segment >= 5)
			{
				return !ShouldDeferFogToVanillaForSegment(segment);
			}
			return false;
		}

		private static bool ShouldDeferFogToVanillaForSegment(Segment segment)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			return (int)segment >= 3;
		}

		private static bool ShouldRemoveFogForSegment(Segment segment)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)segment != 3)
			{
				return (int)segment == 4;
			}
			return true;
		}

		private static bool TryGetCurrentGameplaySegment(out Segment segment)
		{
			//IL_0003: 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: Expected I4, but got Unknown
			segment = (Segment)0;
			if (!IsGameplayFogScene(SceneManager.GetActiveScene()) || LoadingScreenHandler.loading)
			{
				return false;
			}
			if ((Object)(object)Singleton<MapHandler>.Instance == (Object)null)
			{
				return false;
			}
			segment = (Segment)(int)MapHandler.CurrentSegmentNumber;
			return true;
		}

		private static bool IsFogRemovedInCurrentScene()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetCurrentGameplaySegment(out var segment))
			{
				return ShouldRemoveFogForSegment(segment);
			}
			return false;
		}

		private static bool ShouldDeferFogToVanillaInCurrentScene()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetCurrentGameplaySegment(out var segment))
			{
				return ShouldDeferFogToVanillaForSegment(segment);
			}
			return false;
		}

		private void ApplyRemovedFogState()
		{
			if ((Object)(object)_orbFogHandler == (Object)null)
			{
				return;
			}
			_orbFogHandler.speed = 0f;
			_orbFogHandler.isMoving = false;
			_orbFogHandler.currentWaitTime = 0f;
			_orbFogHandler.hasArrived = false;
			_orbFogHandler.currentStartHeight = float.NegativeInfinity;
			_orbFogHandler.currentStartForward = float.NegativeInfinity;
			_orbFogHandler.currentSize = 0f;
			FogSphere val = _fogSphere ?? ResolveFogSphere(_orbFogHandler);
			if (!((Object)(object)val == (Object)null))
			{
				_fogSphere = val;
				val.currentSize = 0f;
				if (((Component)val).gameObject.activeSelf)
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
		}

		private bool IsLateGameFogColdSuppressionActive()
		{
			//IL_0000: 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_0033: Invalid comparison between Unknown and I4
			if (!IsGameplayFogScene(SceneManager.GetActiveScene()) || LoadingScreenHandler.loading)
			{
				return _activeSyntheticFogSegmentId >= 3;
			}
			if ((Object)(object)Singleton<MapHandler>.Instance != (Object)null && (int)MapHandler.CurrentSegmentNumber >= 3)
			{
				return true;
			}
			return _activeSyntheticFogSegmentId >= 3;
		}

		private void ClearSyntheticFogStage()
		{
			//IL_000f: 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)
			_pendingSyntheticFogSegmentId = -1;
			_activeSyntheticFogSegmentId = -1;
			_syntheticFogPoint = Vector3.zero;
			_syntheticFogStartSize = 0f;
		}

		private static bool TryMapSegmentToFogOriginId(Segment segment, int availableOriginCount, out int originId)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected I4, but got Unknown
			originId = -1;
			if (availableOriginCount <= 0)
			{
				return false;
			}
			originId = Mathf.Clamp((int)segment, 0, availableOriginCount - 1);
			return true;
		}

		private void TryAlignFogOriginToCurrentSegment()
		{
			if (!((Object)(object)_orbFogHandler == (Object)null) && HasFogAuthority() && !_orbFogHandler.isMoving && !IsFogRemovedInCurrentScene() && TryGetTargetFogOriginId(out var expectedOriginId) && _orbFogHandler.currentID != expectedOriginId)
			{
				int currentID = _orbFogHandler.currentID;
				_orbFogHandler.SetFogOrigin(expectedOriginId);
				EnsureFogCoverage(_orbFogHandler);
				SyncFogOriginToGuests();
				((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] Aligned fog origin from {1} to {2}.", "Fog&ColdControl", currentID, expectedOriginId));
			}
		}

		private void TryUpdateSyntheticFogStage()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected I4, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_orbFogHandler == (Object)null || !HasFogAuthority())
			{
				return;
			}
			MapHandler instance = Singleton<MapHandler>.Instance;
			int availableFogOriginCount = GetAvailableFogOriginCount();
			if ((Object)(object)instance == (Object)null || availableFogOriginCount <= 0)
			{
				return;
			}
			int num = (int)MapHandler.CurrentSegmentNumber;
			if (num < availableFogOriginCount && _pendingSyntheticFogSegmentId < availableFogOriginCount)
			{
				if (_activeSyntheticFogSegmentId >= 0)
				{
					ClearSyntheticFogStage();
				}
				return;
			}
			int num2 = -1;
			if (_pendingSyntheticFogSegmentId >= availableFogOriginCount && num >= _pendingSyntheticFogSegmentId)
			{
				num2 = _pendingSyntheticFogSegmentId;
				_pendingSyntheticFogSegmentId = -1;
			}
			else if (num >= availableFogOriginCount)
			{
				num2 = num;
			}
			else if (_activeSyntheticFogSegmentId >= availableFogOriginCount)
			{
				num2 = _activeSyntheticFogSegmentId;
			}
			if (num2 < availableFogOriginCount)
			{
				return;
			}
			Segment val = (Segment)(byte)num2;
			if (!ShouldUseCustomFogPositionForSegment(val))
			{
				if (_activeSyntheticFogSegmentId >= availableFogOriginCount)
				{
					ClearSyntheticFogStage();
				}
			}
			else
			{
				if (!TryBuildSyntheticFogStage(val, out var fogPoint, out var fogSize, out var anchorDescription))
				{
					return;
				}
				bool num3 = _activeSyntheticFogSegmentId != num2;
				bool flag = num3 || !_orbFogHandler.isMoving || _orbFogHandler.hasArrived || _syntheticFogStartSize <= 0f;
				bool flag2 = num3 || (flag && Vector3.Distance(_syntheticFogPoint, fogPoint) > 0.1f);
				bool flag3 = num3 || (flag && Mathf.Abs(_syntheticFogStartSize - fogSize) > 0.1f);
				_activeSyntheticFogSegmentId = num2;
				if (flag2)
				{
					_syntheticFogPoint = fogPoint;
				}
				if (flag3)
				{
					_syntheticFogStartSize = fogSize;
				}
				bool num4 = flag2 || flag3;
				ApplySyntheticFogStageToHandler(flag3);
				if (num4)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] Activated synthetic fog stage {1} using {2}. Point={3}, size={4:F1}, delayCompleted={5}, moving={6}.", "Fog&ColdControl", num2, anchorDescription, fogPoint, fogSize, _initialDelayCompleted, _orbFogHandler.isMoving));
					if (_initialDelayCompleted && !_orbFogHandler.isMoving)
					{
						StartFogMovement();
					}
				}
			}
		}

		private void ApplySyntheticFogStageToHandler(bool resetCurrentSize)
		{
			//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)
			if ((Object)(object)_orbFogHandler == (Object)null)
			{
				return;
			}
			FogSphere val = _fogSphere ?? ResolveFogSphere(_orbFogHandler);
			if ((Object)(object)val != (Object)null)
			{
				_fogSphere = val;
				if (!((Component)val).gameObject.activeSelf)
				{
					((Component)val).gameObject.SetActive(true);
				}
				val.fogPoint = _syntheticFogPoint;
				if (resetCurrentSize)
				{
					val.currentSize = _syntheticFogStartSize;
				}
			}
			_orbFogHandler.currentStartHeight = float.NegativeInfinity;
			_orbFogHandler.currentStartForward = float.NegativeInfinity;
			if (resetCurrentSize)
			{
				_orbFogHandler.currentSize = _syntheticFogStartSize;
				_orbFogHandler.currentWaitTime = 0f;
				_orbFogHandler.hasArrived = false;
			}
		}

		private bool TryBuildSyntheticFogStage(Segment syntheticSegment, out Vector3 fogPoint, out float fogSize, out string anchorDescription)
		{
			//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_001b: 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)
			fogPoint = Vector3.zero;
			fogSize = 0f;
			anchorDescription = string.Empty;
			if (!TryResolveSyntheticFogAnchor(syntheticSegment, out fogPoint, out anchorDescription))
			{
				return false;
			}
			fogSize = ComputeSyntheticFogStartSize(syntheticSegment, fogPoint);
			return fogSize > 0f;
		}

		private bool TryBuildPeakVerticalFogStage(Segment syntheticSegment, out Vector3 fogPoint, out float fogSize, out string anchorDescription)
		{
			//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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			//IL_0021: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			fogPoint = Vector3.zero;
			fogSize = 0f;
			anchorDescription = string.Empty;
			if ((int)syntheticSegment < 5)
			{
				return false;
			}
			if (!TryResolvePeakVerticalFogTargetAnchor(syntheticSegment, out var targetAnchor, out var targetDescription))
			{
				return false;
			}
			fogPoint = new Vector3(targetAnchor.x, 1830f, targetAnchor.z);
			fogSize = ComputePeakVerticalFogStartSize(fogPoint, targetAnchor);
			if (fogSize <= 0f)
			{
				return false;
			}
			anchorDescription = $"{targetDescription} vertical-up stop@{1800f:F0}";
			return true;
		}

		private bool TryResolveSyntheticTargetAnchor(Segment syntheticSegment, out Vector3 targetAnchor, out string targetDescription)
		{
			//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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Invalid comparison between Unknown and I4
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_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)
			targetAnchor = Vector3.zero;
			targetDescription = string.Empty;
			MapHandler instance = Singleton<MapHandler>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			if ((int)syntheticSegment >= 5 && (Object)(object)instance.respawnThePeak != (Object)null)
			{
				targetAnchor = instance.respawnThePeak.position;
				targetDescription = "respawnThePeak";
				return true;
			}
			if ((int)syntheticSegment >= 4)
			{
				if (instance.segments != null && instance.segments.Length > 4)
				{
					MapSegment val = instance.segments[4];
					if (val != null && (Object)(object)val.reconnectSpawnPos != (Object)null)
					{
						targetAnchor = val.reconnectSpawnPos.position;
						targetDescription = "TheKiln reconnectSpawnPos";
						return true;
					}
					if (val != null && (Object)(object)val.segmentParent != (Object)null)
					{
						targetAnchor = val.segmentParent.transform.position;
						targetDescription = "TheKiln segmentParent";
						return true;
					}
				}
				if ((Object)(object)instance.respawnTheKiln != (Object)null)
				{
					targetAnchor = instance.respawnTheKiln.position;
					targetDescription = "respawnTheKiln";
					return true;
				}
			}
			return false;
		}

		private bool TryResolveSyntheticFogAnchorFromOrigins(Segment syntheticSegment, out Vector3 fogPoint, out string anchorDescription)
		{
			//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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected I4, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			fogPoint = Vector3.zero;
			anchorDescription = string.Empty;
			FogSphereOrigin[] array = ResolveFogOrigins(_orbFogHandler);
			FogSphereOrigin val = ((IEnumerable<FogSphereOrigin>)array).LastOrDefault((Func<FogSphereOrigin, bool>)((FogSphereOrigin origin) => (Object)(object)origin != (Object)null));
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			FogSphereOrigin val2 = array.Where((FogSphereOrigin origin) => (Object)(object)origin != (Object)null).Reverse().Skip(1)
				.FirstOrDefault();
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			Vector3 val3 = ((Component)val).transform.position - ((Component)val2).transform.position;
			if (((Vector3)(ref val3)).sqrMagnitude < 1f)
			{
				return false;
			}
			int num = Mathf.Max(syntheticSegment - (array.Length - 1), 1);
			Vector3 normalized = ((Vector3)(ref val3)).normalized;
			Vector3 val4 = ((Component)val).transform.position + val3 * (float)num;
			if (TryResolveSyntheticTargetAnchor(syntheticSegment, out var targetAnchor, out var targetDescription))
			{
				float num2 = Mathf.Max(Vector3.Dot(targetAnchor - ((Component)val).transform.position, normalized) + 180f, ((Vector3)(ref val3)).magnitude * (float)num);
				val4 = ((Component)val).transform.position + normalized * num2;
				Vector3 val5 = Vector3.ProjectOnPlane(targetAnchor - val4, normalized);
				val4 += val5 * 0.25f;
				anchorDescription = "origin-extrapolated + " + targetDescription;
			}
			else
			{
				anchorDescription = "origin-extrapolated";
			}
			fogPoint = val4;
			return true;
		}

		private bool TryResolveSyntheticFogAnchor(Segment syntheticSegment, out Vector3 fogPoint, out string anchorDescription)
		{
			//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_0013: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			fogPoint = Vector3.zero;
			anchorDescription = string.Empty;
			if (TryResolveSyntheticFogAnchorFromOrigins(syntheticSegment, out fogPoint, out anchorDescription))
			{
				return true;
			}
			if ((Object)(object)Singleton<MapHandler>.Instance == (Object)null)
			{
				return false;
			}
			if (TryResolveSyntheticTargetAnchor(syntheticSegment, out fogPoint, out anchorDescription))
			{
				return true;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter != (Object)null)
			{
				fogPoint = localCharacter.Center;
				anchorDescription = "localCharacter";
				return true;
			}
			Character val = ((IEnumerable<Character>)Character.AllCharacters).FirstOrDefault((Func<Character, bool>)((Character character) => (Object)(object)character != (Object)null));
			if ((Object)(object)val != (Object)null)
			{
				fogPoint = val.Center;
				anchorDescription = "firstCharacter";
				return true;
			}
			return false;
		}

		private bool TryResolvePeakVerticalFogAnchor(Segment syntheticSegment, out Vector3 fogPoint, out string anchorDescription)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0019: 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_0033: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			fogPoint = Vector3.zero;
			anchorDescription = string.Empty;
			if ((int)syntheticSegment < 5)
			{
				return false;
			}
			if (!TryResolvePeakVerticalFogTargetAnchor(syntheticSegment, out var targetAnchor, out var targetDescription))
			{
				return false;
			}
			fogPoint = new Vector3(targetAnchor.x, 1830f, targetAnchor.z);
			anchorDescription = $"{targetDescription} vertical-up stop@{1800f:F0}";
			return true;
		}

		private bool TryResolvePeakVerticalFogTargetAnchor(Segment syntheticSegment, out Vector3 targetAnchor, out string targetDescription)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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)
			targetAnchor = Vector3.zero;
			targetDescription = string.Empty;
			if ((int)syntheticSegment < 5)
			{
				return false;
			}
			if (TryResolveSyntheticTargetAnchor(syntheticSegment, out targetAnchor, out targetDescription))
			{
				return true;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter != (Object)null)
			{
				targetAnchor = localCharacter.Center;
				targetDescription = "localCharacter";
				return true;
			}
			Character val = ((IEnumerable<Character>)Character.AllCharacters).FirstOrDefault((Func<Character, bool>)((Character character) => (Object)(object)character != (Object)null));
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			targetAnchor = val.Center;
			targetDescription = "firstCharacter";
			return true;
		}

		private float ComputeSyntheticFogStartSize(Segment syntheticSegment, Vector3 fogPoint)
		{
			//IL_0018: 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)
			float previousOriginSize = 900f;
			TryGetPreviousRealFogOriginSize(out previousOriginSize);
			float baseSize = previousOriginSize * 0.72f;
			return ComputeFogStartSizeForStage(syntheticSegment, fogPoint, baseSize, 650f, 1400f, 130f, 95f);
		}

		private float ComputePeakVerticalFogStartSize(Vector3 fogPoint, Vector3 targetAnchor)
		{
			//IL_0021: 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_00d9: 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_0073: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			float previousOriginSize = 900f;
			TryGetPreviousRealFogOriginSize(out previousOriginSize);
			float num = Mathf.Max(previousOriginSize * 0.68f, 650f);
			float num2 = Mathf.Min(targetAnchor.y, 1620f);
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter.data == (Object)null) && !allCharacter.data.dead)
				{
					num2 = Mathf.Min(num2, allCharacter.Center.y);
					num = Mathf.Max(num, Vector3.Distance(fogPoint, allCharacter.Center) + 70f);
				}
			}
			num = Mathf.Max(num, fogPoint.y - num2 + 120f);
			if (TryResolveFogStageCoverageAnchor((Segment)5, out var stageAnchor, out var _))
			{
				num = Mathf.Max(num, Vector3.Distance(fogPoint, stageAnchor) + 90f);
			}
			return Mathf.Clamp(num, 650f, 1400f);
		}

		private void TryAutoStartCustomRunFogIfNeeded()
		{
			if (!((Object)(object)_orbFogHandler == (Object)null) && HasFogAuthority() && !_fogPaused && RunSettings.IsCustomRun && !ShouldHoldFogUntilCampfireActivation(_orbFogHandler) && !_orbFogHandler.isMoving && !_orbFogHandler.hasArrived && !(_orbFogHandler.currentWaitTime > 0.2f))
			{
				StartFogMovement();
			}
		}

		private void TryAutoResumeStalledFogMovement()
		{
			if (!((Object)(object)_orbFogHandler == (Object)null) && HasFogAuthority() && !_fogPaused && _initialDelayCompleted && !ShouldHoldFogUntilCampfireActivation(_orbFogHandler) && _orbFogHandler.currentID > 0 && !_orbFogHandler.isMoving && !_orbFogHandler.hasArrived && TryGetTargetFogOriginId(out var expectedOriginId) && expectedOriginId == _orbFogHandler.currentID)
			{
				float stalledFogResumeDelaySeconds = GetStalledFogResumeDelaySeconds(_orbFogHandler);
				if (!(_orbFogHandler.currentWaitTime < stalledFogResumeDelaySeconds))
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] Resuming stalled fog at origin {1} after waiting {2:F1}s.", "Fog&ColdControl", _orbFogHandler.currentID, _orbFogHandler.currentWaitTime));
					StartFogMovement();
				}
			}
		}

		private static float GetStalledFogResumeDelaySeconds(OrbFogHandler fogHandler)
		{
			if ((Object)(object)fogHandler == (Object)null)
			{
				return 8f;
			}
			return Mathf.Clamp(fogHandler.maxWaitTime * 0.02f, 2f, 8f);
		}

		private void UpdateTrackedFogOrigin()
		{
			if ((Object)(object)_orbFogHandler == (Object)null || _trackedFogOriginId == _orbFogHandler.currentID)
			{
				return;
			}
			bool flag = _orbFogHandler.currentID == 0 && _trackedFogOriginId > 0;
			_trackedFogOriginId = _orbFogHandler.currentID;
			if (_trackedFogOriginId > 0)
			{
				if (IsCampfireDelayPendingForOrigin(_trackedFogOriginId))
				{
					_fogHiddenBufferTimer = 0f;
					_fogDelayTimer = 0f;
					_initialDelayCompleted = false;
					if (_initialDelayCompleted)
					{
						ClearPendingCampfireDelayForOrigin(_trackedFogOriginId);
						if (!_orbFogHandler.isMoving)
						{
							StartFogMovement();
						}
					}
				}
				else
				{
					bool flag2 = (_initialDelayCompleted = _orbFogHandler.isMoving || _orbFogHandler.hasArrived || _orbFogHandler.currentWaitTime > 0.2f);
					_fogHiddenBufferTimer = (flag2 ? 10f : 0f);
					_fogDelayTimer = ((!flag2) ? 0f : (FogDelay?.Value ?? 0f));
				}
			}
			else if (flag)
			{
				_fogHiddenBufferTimer = 0f;
				_fogDelayTimer = 0f;
				_initialDelayCompleted = ShouldSkipInitialDelay(_orbFogHandler);
			}
		}

		private void StartFogMovement()
		{
			if ((Object)(object)_orbFogHandler == (Object)null || _fogPaused || IsFogRemovedInCurrentScene())
			{
				return;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] Starting fog movement. currentOrigin={1}, syntheticStage={2}, pendingOrigin={3}, currentSize={4:F1}.", "Fog&ColdControl", _orbFogHandler.currentID, _activeSyntheticFogSegmentId, _delayedFogOriginId, _orbFogHandler.currentSize));
			ClearPendingCampfireDelayForOrigin(_orbFogHandler.currentID);
			bool flag = !_initialCompassGranted && _orbFogHandler.currentID == 0;
			if (!TryInvokeFogStartMovement(_orbFogHandler, out var invocationPath))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] Failed to start fog movement because no compatible OrbFogHandler start method was found. currentOrigin={1}.", "Fog&ColdControl", _orbFogHandler.currentID));
				return;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("[Fog&ColdControl] Fog movement invoked via " + invocationPath + "."));
			if (PhotonNetwork.InRoom)
			{
				ForceSyncFogStateToGuests();
			}
			InitializeFogArrivalEstimate(_orbFogHandler.currentID, GetObservedFogEtaSize(), Time.unscaledTime);
			if (flag && !HasRemotePlayersInJoinGracePeriod())
			{
				_initialCompassGranted = true;
				GrantCompassToAllPlayers("initial-delay-ended");
			}
		}

		private bool TryInvokeFogStartMovement(OrbFogHandler fogHandler, out string invocationPath)
		{
			//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)
			invocationPath = string.Empty;
			if ((Object)(object)fogHandler == (Object)null)
			{
				return false;
			}
			Type type = ((object)fogHandler).GetType();
			MethodInfo method = type.GetMethod("StartMovingRPC", InstanceBindingFlags, null, Type.EmptyTypes, null);
			if (TryInvokeFogStartMethod(fogHandler, method, Array.Empty<object>()))
			{
				invocationPath = "StartMovingRPC()";
				return true;
			}
			MethodInfo method2 = type.GetMethod("StartMovingRPC", InstanceBindingFlags, null, new Type[1] { typeof(PhotonMessageInfo) }, null);
			if (TryInvokeFogStartMethod(fogHandler, method2, new object[1] { (object)default(PhotonMessageInfo) }))
			{
				invocationPath = "StartMovingRPC(PhotonMessageInfo)";
				return true;
			}
			MethodInfo method3 = type.GetMethod("WaitToMove", InstanceBindingFlags, null, Type.EmptyTypes, null);
			if (TryInvokeFogStartMethod(fogHandler, method3, Array.Empty<object>()))
			{
				invocationPath = "WaitToMove()";
				return true;
			}
			return false;
		}

		private bool TryInvokeFogStartMethod(OrbFogHandler fogHandler, MethodInfo method, object[] arguments)
		{
			if ((Object)(object)fogHandler == (Object)null || method == null)
			{
				return false;
			}
			try
			{
				method.Invoke(fogHandler, arguments);
				return true;
			}
			catch (TargetInvocationException ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[Fog&ColdControl] Fog start method " + method.Name + " failed: " + (ex.InnerException?.Message ?? ex.Message)));
				return false;
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[Fog&ColdControl] Fog start method " + method.Name + " failed: " + ex2.Message));
				return false;
			}
		}

		private void ApplyPausedFogState(bool syncImmediately)
		{
			if (!((Object)(object)_orbFogHandler == (Object)null))
			{
				_orbFogHandler.speed = 0f;
				_orbFogHandler.isMoving = false;
				if (syncImmediately)
				{
					ForceSyncFogStateToGuests();
				}
			}
		}

		private void ForceSyncFogStateToGuests()
		{
			if (!((Object)(object)_orbFogHandler == (Object)null) && HasRemotePlayers() && PhotonNetwork.IsMasterClient && !HasRemotePlayersInJoinGracePeriod())
			{
				_lastFogStateSyncTime = -0.18f;
				ResetFogStateSyncSnapshot();
				SyncFogStateToGuestsIfNeeded();
			}
		}

		private void UpdateFogArrivalEstimate()
		{
			if ((Object)(object)_orbFogHandler == (Object)null || _fogPaused || IsFogRemovedInCurrentScene() || !_orbFogHandler.isMoving || _orbFogHandler.hasArrived)
			{
				ResetFogArrivalEstimate();
				return;
			}
			float observedFogEtaSize = GetObservedFogEtaSize();
			float unscaledTime = Time.unscaledTime;
			int currentID = _orbFogHandler.currentID;
			if (_fogEtaTrackedOriginId != currentID || float.IsNaN(_fogEtaLastObservedSize) || _fogEtaLastObservedTime < 0f)
			{
				InitializeFogArrivalEstimate(currentID, observedFogEtaSize, unscaledTime);
				return;
			}
			float num = unscaledTime - _fogEtaLastObservedTime;
			if (num < 0.1f)
			{
				return;
			}
			float num2 = _fogEtaLastObservedSize - observedFogEtaSize;
			if (num2 <= -0.05f)
			{
				InitializeFogArrivalEstimate(currentID, observedFogEtaSize, unscaledTime);
			}
			else if (!(Mathf.Abs(num2) < 0.05f))
			{
				_fogEtaLastObservedSize = observedFogEtaSize;
				_fogEtaLastObservedTime = unscaledTime;
				float num3 = num2 / num;
				if (num3 < 0.02f)
				{
					UpdateFogArrivalMetricsCache(force: false);
					return;
				}
				_fogEtaEstimatedUnitsPerSecond = (_fogEtaHasReliableRate ? Mathf.Lerp(_fogEtaEstimatedUnitsPerSecond, num3, 0.35f) : num3);
				_fogEtaHasReliableRate = true;
				UpdateFogArrivalMetricsCache(force: false);
			}
		}

		private bool TryGetFogArrivalEtaSeconds(out float etaSeconds)
		{
			etaSeconds = 0f;
			UpdateFogArrivalMetricsCache(force: false);
			if (!_fogDistanceEtaHasSnapshot)
			{
				return false;
			}
			if (_fogDistanceEtaRemainingDistance <= 0.05f)
			{
				etaSeconds = 0f;
				return true;
			}
			if (!_fogDistanceEtaHasEta)
			{
				return false;
			}
			etaSeconds = _fogDistanceEtaSeconds;
			return true;
		}

		private bool TryGetFogArrivalRemainingDistance(out float remainingDistance)
		{
			remainingDistance = 0f;
			UpdateFogArrivalMetricsCache(force: false);
			if (!_fogDistanceEtaHasSnapshot)
			{
				return false;
			}
			remainingDistance = _fogDistanceEtaRemainingDistance;
			return true;
		}

		private bool TryGetDisplayedFogEtaGeometry(out float currentSize, out Vector3 fogPoint, out Vector3 playerPoint)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or