Decompiled source of FogClimb v0.0.2

BepInEx\plugins\com.github.Thanks.FogClimb.dll

Decompiled 7 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
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.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
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("com.github.Thanks.FogClimb")]
[assembly: AssemblyDescription("Standalone toxic fog mode mod for PEAK.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Thanks")]
[assembly: AssemblyProduct("FogClimb")]
[assembly: AssemblyCopyright("Copyright (c) Thanks 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f3d09c64-b194-4a16-9196-85106f2f0d01")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.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 FogClimb
{
	[HarmonyPatch(typeof(Fog), "MakePlayerCold")]
	internal static class FogMakePlayerColdPatch
	{
		private static bool Prefix()
		{
			return !Plugin.ShouldSuppressFogColdDamage();
		}
	}
	[HarmonyPatch(typeof(FogSphere), "SetSharderVars")]
	internal static class FogSphereSetShaderVarsPatch
	{
		private static void Postfix()
		{
			Plugin.ClearLocalFogColdStatus();
		}
	}
	[HarmonyPatch(typeof(OrbFogHandler), "WaitToMove")]
	internal static class OrbFogHandlerWaitToMovePatch
	{
		private static bool Prefix(OrbFogHandler __instance)
		{
			return !Plugin.ShouldBlockVanillaOrbFogWait(__instance);
		}
	}
	[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")]
	internal static class CharacterAfflictionsAddStatusPatch
	{
		private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE statusType, ref bool __result)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			if (Plugin.IsInternalColdClearInProgress() || (int)statusType != 2 || !Plugin.ShouldSuppressAmbientColdDamageFor(__instance))
			{
				return true;
			}
			Plugin.EnforceAmbientColdSuppression(__instance);
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(CharacterAfflictions), "SetStatus")]
	internal static class CharacterAfflictionsSetStatusPatch
	{
		private static void Prefix(CharacterAfflictions __instance, STATUSTYPE statusType, ref float amount)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			if (!Plugin.IsInternalColdClearInProgress() && (int)statusType == 2 && Plugin.ShouldSuppressAmbientColdDamageFor(__instance))
			{
				amount = 0f;
			}
		}

		private static void Postfix(CharacterAfflictions __instance, STATUSTYPE statusType)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			if (!Plugin.IsInternalColdClearInProgress() && (int)statusType == 2 && Plugin.ShouldSuppressAmbientColdDamageFor(__instance))
			{
				Plugin.EnforceAmbientColdSuppression(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterAfflictions), "ApplyStatusesFromFloatArray")]
	internal static class CharacterAfflictionsApplyStatusesFromFloatArrayPatch
	{
		private static void Postfix(CharacterAfflictions __instance)
		{
			if (Plugin.ShouldSuppressAmbientColdDamageFor(__instance))
			{
				Plugin.EnforceAmbientColdSuppression(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterAfflictions), "RPC_ApplyStatusesFromFloatArray")]
	internal static class CharacterAfflictionsRpcApplyStatusesFromFloatArrayPatch
	{
		private static void Postfix(CharacterAfflictions __instance)
		{
			if (Plugin.ShouldSuppressAmbientColdDamageFor(__instance))
			{
				Plugin.EnforceAmbientColdSuppression(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Campfire), "Light_Rpc")]
	internal static class CampfireLightRpcPatch
	{
		private static void Postfix(Campfire __instance)
		{
			Plugin.NotifyCampfireLit(__instance);
		}
	}
	[BepInPlugin("com.github.Thanks.FogClimb", "FogClimb", "0.0.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		private enum ConfigKey
		{
			ModEnabled,
			FogSpeed,
			FogDelay,
			FogUiEnabled,
			FogUiX,
			FogUiY,
			FogUiScale
		}

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

			private Player <>2__current;

			private int <>l__initialThreadId;

			private IEnumerator<Player> <>7__wrap1;

			private Player[] <>7__wrap2;

			private int <>7__wrap3;

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

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

			[DebuggerHidden]
			public <EnumerateTargetPlayers>d__134(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();
					}
				}
				<>7__wrap1 = null;
				<>7__wrap2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
					{
						<>1__state = -1;
						if (PhotonNetwork.InRoom)
						{
							<>7__wrap1 = PlayerHandler.GetAllPlayers().GetEnumerator();
							<>1__state = -3;
							goto IL_007a;
						}
						Player[] array = Object.FindObjectsByType<Player>((FindObjectsSortMode)0);
						<>7__wrap2 = array;
						<>7__wrap3 = 0;
						goto IL_00f0;
					}
					case 1:
						<>1__state = -3;
						goto IL_007a;
					case 2:
						{
							<>1__state = -1;
							goto IL_00e2;
						}
						IL_00f0:
						if (<>7__wrap3 < <>7__wrap2.Length)
						{
							Player val = <>7__wrap2[<>7__wrap3];
							if ((Object)(object)val != (Object)null)
							{
								<>2__current = val;
								<>1__state = 2;
								return true;
							}
							goto IL_00e2;
						}
						<>7__wrap2 = null;
						return false;
						IL_007a:
						while (<>7__wrap1.MoveNext())
						{
							Player current = <>7__wrap1.Current;
							if ((Object)(object)current != (Object)null)
							{
								<>2__current = current;
								<>1__state = 1;
								return true;
							}
						}
						<>m__Finally1();
						<>7__wrap1 = null;
						return false;
						IL_00e2:
						<>7__wrap3++;
						goto IL_00f0;
					}
				}
				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__wrap1 != null)
				{
					<>7__wrap1.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__134(0);
			}

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

		[CompilerGenerated]
		private sealed class <GetAliasDefinitions>d__104 : 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 <englishSection>5__2;

			private string <chineseSection>5__3;

			private string <englishKey>5__4;

			private string <chineseKey>5__5;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<englishSection>5__2 = null;
				<chineseSection>5__3 = null;
				<englishKey>5__4 = null;
				<chineseKey>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Expected O, but got Unknown
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: Expected O, but got Unknown
				//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cb: Expected O, but got Unknown
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f2: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<englishSection>5__2 = GetSectionName(isChineseLanguage: false);
					<chineseSection>5__3 = GetSectionName(isChineseLanguage: true);
					<englishKey>5__4 = GetKeyName(configKey, isChineseLanguage: false);
					<chineseKey>5__5 = GetKeyName(configKey, isChineseLanguage: true);
					<>2__current = new ConfigDefinition(<englishSection>5__2, <englishKey>5__4);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = new ConfigDefinition(<englishSection>5__2, <chineseKey>5__5);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<>2__current = new ConfigDefinition(<chineseSection>5__3, <englishKey>5__4);
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					<>2__current = new ConfigDefinition(<chineseSection>5__3, <chineseKey>5__5);
					<>1__state = 4;
					return true;
				case 4:
					<>1__state = -1;
					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__104 <GetAliasDefinitions>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetAliasDefinitions>d__ = this;
				}
				else
				{
					<GetAliasDefinitions>d__ = new <GetAliasDefinitions>d__104(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 = "FogClimb";

		public const string PluginVersion = "0.0.2";

		private const float DefaultVanillaFogSpeed = 0.3f;

		private const float DefaultFogSpeed = 2f;

		private const float DefaultFogDelaySeconds = 90f;

		private const float MinFogSpeed = 0.3f;

		private const float MaxFogSpeed = 5f;

		private const float MinFogDelaySeconds = 0f;

		private const float MaxFogDelaySeconds = 150f;

		private const float DefaultFogUiX = 60f;

		private const float DefaultFogUiY = 16f;

		private const float DefaultFogUiScale = 1.2f;

		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 ColdClearIntervalSeconds = 0.2f;

		private const float FogStateSyncIntervalSeconds = 0.18f;

		private const float RemoteStatusSyncIntervalSeconds = 0.25f;

		private const float BeaconRefreshIntervalSeconds = 1f;

		private const float CompassGrantSyncIntervalSeconds = 0.75f;

		private const float FogColdPerSecond = 0.0105f;

		private const float BeaconBaseHeight = 12f;

		private const float BeaconSegmentHeight = 14f;

		private const int BeaconLayerCount = 7;

		private const float BeaconRingRadius = 4.5f;

		private const float FogUiWidth = 920f;

		private const float FogUiHeight = 30f;

		private const string FogUiTitle = "FogClimb";

		private const int SimplifiedChineseLanguageIndex = 9;

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

		private static readonly string[] ColdStatusArrayFields = new string[5] { "currentStatuses", "currentIncrementalStatuses", "currentDecrementalStatuses", "lastAddedStatus", "lastAddedIncrementalStatus" };

		private static bool _isClearingColdStatus;

		private Harmony _harmony;

		private OrbFogHandler _orbFogHandler;

		private FogSphere _fogSphere;

		private bool _fogStateInitialized;

		private bool _initialDelayCompleted;

		private int _trackedFogOriginId = -1;

		private float _fogDelayTimer;

		private float _fogHandlerSearchTimer;

		private float _lastColdClearTime = -0.2f;

		private float _lastFogStateSyncTime = -0.18f;

		private float _lastRemoteStatusSyncTime = -0.25f;

		private float _lastBeaconRefreshTime = -1f;

		private float _lastCompassGrantSyncTime = -0.75f;

		private bool _lastModEnabledState;

		private bool _lastFogUiEnabledState;

		private float _lastFogUiX;

		private float _lastFogUiY;

		private float _lastFogUiScale;

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

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

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

		private Item _flareBeaconPrefab;

		private Item _compassItem;

		private int _activeBeaconSegment = -1;

		private RectTransform _fogUiRect;

		private TextMeshProUGUI _fogUiText;

		private bool _initialCompassGranted;

		private int _totalCompassGrantCount;

		internal static Plugin Instance { get; private set; }

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

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

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

		internal static ConfigEntry<bool> FogUiEnabled { 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			Instance = this;
			bool isChineseLanguage = DetectChineseLanguage();
			InitializeConfig(isChineseLanguage);
			_lastModEnabledState = IsModFeatureEnabled();
			_lastFogUiEnabledState = FogUiEnabled?.Value ?? true;
			_lastFogUiX = FogUiX?.Value ?? 60f;
			_lastFogUiY = FogUiY?.Value ?? 16f;
			_lastFogUiScale = FogUiScale?.Value ?? 1.2f;
			_harmony = new Harmony("com.github.Thanks.FogClimb");
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			SceneManager.sceneLoaded += OnSceneLoaded;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[FogClimb] Loaded.");
		}

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

		private void InitializeConfig(bool isChineseLanguage)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			string sectionName = GetSectionName(isChineseLanguage);
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(sectionName, GetKeyName(ConfigKey.ModEnabled, isChineseLanguage), true, GetConfigDescription(ConfigKey.ModEnabled, isChineseLanguage));
			FogSpeed = ((BaseUnityPlugin)this).Config.Bind<float>(sectionName, GetKeyName(ConfigKey.FogSpeed, isChineseLanguage), 2f, new ConfigDescription(GetLocalizedDescription(ConfigKey.FogSpeed, isChineseLanguage), (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 5f), Array.Empty<object>()));
			FogDelay = ((BaseUnityPlugin)this).Config.Bind<float>(sectionName, GetKeyName(ConfigKey.FogDelay, isChineseLanguage), 90f, new ConfigDescription(GetLocalizedDescription(ConfigKey.FogDelay, isChineseLanguage), (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 150f), Array.Empty<object>()));
			FogUiEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(sectionName, GetKeyName(ConfigKey.FogUiEnabled, isChineseLanguage), true, GetConfigDescription(ConfigKey.FogUiEnabled, isChineseLanguage));
			FogUiX = ((BaseUnityPlugin)this).Config.Bind<float>(sectionName, GetKeyName(ConfigKey.FogUiX, isChineseLanguage), 60f, new ConfigDescription(GetLocalizedDescription(ConfigKey.FogUiX, isChineseLanguage), (AcceptableValueBase)(object)new AcceptableValueRange<float>(-400f, 400f), Array.Empty<object>()));
			FogUiY = ((BaseUnityPlugin)this).Config.Bind<float>(sectionName, GetKeyName(ConfigKey.FogUiY, isChineseLanguage), 16f, new ConfigDescription(GetLocalizedDescription(ConfigKey.FogUiY, isChineseLanguage), (AcceptableValueBase)(object)new AcceptableValueRange<float>(-500f, 500f), Array.Empty<object>()));
			FogUiScale = ((BaseUnityPlugin)this).Config.Bind<float>(sectionName, GetKeyName(ConfigKey.FogUiScale, isChineseLanguage), 1.2f, new ConfigDescription(GetLocalizedDescription(ConfigKey.FogUiScale, isChineseLanguage), (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2.5f), Array.Empty<object>()));
			MigrateLocalizedConfigEntries();
			ClampConfigValues();
		}

		private ConfigDescription GetConfigDescription(ConfigKey configKey, bool isChineseLanguage)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			return 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)FogSpeed, ConfigKey.FogSpeed, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)FogDelay, ConfigKey.FogDelay, orphanedEntries) | TryMigrateLocalizedConfigValue((ConfigEntryBase)(object)FogUiEnabled, ConfigKey.FogUiEnabled, 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;
			}
			foreach (ConfigDefinition aliasDefinition in GetAliasDefinitions(configKey))
			{
				if (!DefinitionsEqual(aliasDefinition, entry.Definition) && orphanedEntries.Contains(aliasDefinition))
				{
					object obj = orphanedEntries[aliasDefinition];
					if (obj != null)
					{
						entry.SetSerializedValue(obj.ToString());
					}
					orphanedEntries.Remove(aliasDefinition);
					return true;
				}
			}
			return false;
		}

		[IteratorStateMachine(typeof(<GetAliasDefinitions>d__104))]
		private static IEnumerable<ConfigDefinition> GetAliasDefinitions(ConfigKey configKey)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetAliasDefinitions>d__104(-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, 5f);
			}
			if (FogDelay != null)
			{
				FogDelay.Value = Mathf.Clamp(FogDelay.Value, 0f, 150f);
			}
			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);
				if (num || flag || flag2 || flag3 || flag4)
				{
					FogUiX.Value = 60f;
					FogUiY.Value = 16f;
					FogUiScale.Value = 1.2f;
				}
			}
		}

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

		private void Update()
		{
			bool flag = IsModFeatureEnabled();
			if (flag != _lastModEnabledState)
			{
				_lastModEnabledState = flag;
				if (!flag)
				{
					RestoreVanillaFogSpeed();
					ResetFogRuntimeState();
					CleanupCampfireBeacon();
					SetFogUiVisible(visible: false);
				}
				else
				{
					_fogStateInitialized = false;
					_lastFogStateSyncTime = -0.18f;
					_lastRemoteStatusSyncTime = -0.25f;
					_lastBeaconRefreshTime = -1f;
					_lastCompassGrantSyncTime = -0.75f;
				}
			}
			TryResolveRuntimeObjects();
			HandleFogUiConfigChanges();
			if (!flag)
			{
				UpdateFogUi();
				return;
			}
			if ((Object)(object)_orbFogHandler != (Object)null && !_fogStateInitialized)
			{
				InitializeFogRuntimeState(_orbFogHandler);
			}
			if ((Object)(object)_orbFogHandler != (Object)null && HasFogAuthority())
			{
				UpdateAuthorityFogMode();
				SyncFogStateToGuestsIfNeeded();
				SyncRemoteStatusSuppressionIfNeeded();
				RefreshCampfireBeaconIfNeeded();
				SyncCompassGrantsToPlayersIfNeeded();
			}
			else if (!HasFogAuthority())
			{
				CleanupCampfireBeacon();
			}
			ClearLocalAmbientColdStatus();
			UpdateFogUi();
		}

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

		private void TryResolveRuntimeObjects()
		{
			bool flag = (Object)(object)_orbFogHandler == (Object)null;
			bool flag2 = (Object)(object)_fogSphere == (Object)null;
			if (!flag && !flag2)
			{
				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>();
			}
		}

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

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

		private void UpdateAuthorityFogMode()
		{
			if ((Object)(object)_orbFogHandler == (Object)null)
			{
				return;
			}
			ClampConfigValues();
			UpdateTrackedFogOrigin();
			if (_trackedFogOriginId != 0)
			{
				_initialDelayCompleted = true;
			}
			if (!_initialDelayCompleted)
			{
				_fogDelayTimer += Time.unscaledDeltaTime;
				_orbFogHandler.speed = 0f;
				if (_fogDelayTimer >= FogDelay.Value)
				{
					_fogDelayTimer = FogDelay.Value;
					_initialDelayCompleted = true;
					if (!_orbFogHandler.isMoving)
					{
						StartFogMovement();
					}
				}
			}
			else
			{
				_orbFogHandler.speed = FogSpeed.Value;
				TryGrantInitialCompassIfNeeded();
			}
		}

		private void UpdateTrackedFogOrigin()
		{
			if (!((Object)(object)_orbFogHandler == (Object)null) && _trackedFogOriginId != _orbFogHandler.currentID)
			{
				bool flag = _orbFogHandler.currentID == 0 && _trackedFogOriginId > 0;
				_trackedFogOriginId = _orbFogHandler.currentID;
				if (_trackedFogOriginId > 0)
				{
					_initialDelayCompleted = true;
					_fogDelayTimer = FogDelay?.Value ?? 0f;
				}
				else if (flag)
				{
					_fogDelayTimer = 0f;
					_initialDelayCompleted = ShouldSkipInitialDelay(_orbFogHandler);
				}
			}
		}

		private void StartFogMovement()
		{
			if ((Object)(object)_orbFogHandler == (Object)null)
			{
				return;
			}
			bool flag = !_initialCompassGranted && _orbFogHandler.currentID == 0;
			PhotonView component = ((Component)_orbFogHandler).GetComponent<PhotonView>();
			if (PhotonNetwork.InRoom && (Object)(object)component != (Object)null)
			{
				component.RPC("StartMovingRPC", (RpcTarget)0, Array.Empty<object>());
				if (flag)
				{
					_initialCompassGranted = true;
					GrantCompassToAllPlayers("initial-delay-ended");
				}
			}
			else
			{
				_orbFogHandler.StartMovingRPC();
				if (flag)
				{
					_initialCompassGranted = true;
					GrantCompassToAllPlayers("initial-delay-ended");
				}
			}
		}

		private void TryGrantInitialCompassIfNeeded()
		{
			if (!_initialCompassGranted && !((Object)(object)_orbFogHandler == (Object)null) && _orbFogHandler.currentID == 0 && _initialDelayCompleted && _orbFogHandler.isMoving)
			{
				_initialCompassGranted = true;
				GrantCompassToAllPlayers("initial-delay-ended");
			}
		}

		private void SyncFogStateToGuestsIfNeeded()
		{
			if ((Object)(object)_orbFogHandler == (Object)null || !PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient)
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			if (unscaledTime - _lastFogStateSyncTime < 0.18f)
			{
				return;
			}
			_lastFogStateSyncTime = unscaledTime;
			PhotonView component = ((Component)_orbFogHandler).GetComponent<PhotonView>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			try
			{
				component.RPC("RPCA_SyncFog", (RpcTarget)1, new object[2] { _orbFogHandler.currentSize, _orbFogHandler.isMoving });
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("[FogClimb] Fog sync skipped: " + ex.Message));
			}
		}

		private void SyncRemoteStatusSuppressionIfNeeded()
		{
			if (!PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient)
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			float num = ((_lastRemoteStatusSyncTime < 0f) ? 0.25f : (unscaledTime - _lastRemoteStatusSyncTime));
			if (num < 0.25f)
			{
				return;
			}
			_lastRemoteStatusSyncTime = unscaledTime;
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (!ShouldSendRemoteStatusSuppression(allCharacter))
				{
					continue;
				}
				float[] array = BuildRemoteStatusSuppressionPayload(allCharacter, num);
				if (array != null)
				{
					try
					{
						((MonoBehaviourPun)allCharacter).photonView.RPC("RPC_ApplyStatusesFromFloatArray", ((MonoBehaviourPun)allCharacter).photonView.Owner, new object[1] { array });
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogDebug((object)("[FogClimb] Remote status suppression skipped for " + allCharacter.characterName + ": " + ex.Message));
					}
				}
			}
		}

		private static bool ShouldSendRemoteStatusSuppression(Character character)
		{
			if ((Object)(object)character != (Object)null && (Object)(object)((MonoBehaviourPun)character).photonView != (Object)null && ((MonoBehaviourPun)character).photonView.Owner != null && !((MonoBehaviourPun)character).photonView.IsMine && !character.isBot && !character.isZombie)
			{
				return !character.data.dead;
			}
			return false;
		}

		private float[] BuildRemoteStatusSuppressionPayload(Character character, float elapsed)
		{
			if (!character.data.isSkeleton)
			{
				float[] array = new float[StatusTypeCount];
				array[2] = -1f;
				return array;
			}
			if (!IsCharacterOutsideCurrentFogSphere(character))
			{
				return null;
			}
			float[] array2 = new float[StatusTypeCount];
			array2[0] = 0f - Mathf.Max(0.0013125f * Mathf.Max(elapsed, 0.25f) * 1.25f, 0.001f);
			return array2;
		}

		private bool IsCharacterOutsideCurrentFogSphere(Character character)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_fogSphere != (Object)null && Mathf.Approximately(_fogSphere.ENABLE, 1f))
			{
				return Vector3.Distance(_fogSphere.fogPoint, character.Center) > _fogSphere.currentSize;
			}
			return false;
		}

		private void RefreshCampfireBeaconIfNeeded()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (!IsModFeatureEnabled() || !HasFogAuthority())
			{
				CleanupCampfireBeacon();
				return;
			}
			float unscaledTime = Time.unscaledTime;
			if (unscaledTime - _lastBeaconRefreshTime < 1f)
			{
				return;
			}
			_lastBeaconRefreshTime = unscaledTime;
			Campfire val = TryGetTargetCampfire();
			int num = ((!((Object)(object)val != (Object)null)) ? (-1) : ((int)MapHandler.CurrentSegmentNumber));
			if ((Object)(object)val == (Object)null || num != _activeBeaconSegment || _campfireBeaconObjects.Count != GetBeaconSpawnCount() || _campfireBeaconObjects.Any((GameObject obj) => (Object)(object)obj == (Object)null))
			{
				CleanupCampfireBeacon();
				if (!((Object)(object)val == (Object)null))
				{
					TrySpawnCampfireBeacon(val, num);
				}
			}
		}

		private Campfire TryGetTargetCampfire()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			try
			{
				if ((Object)(object)Singleton<MapHandler>.Instance == (Object)null)
				{
					return null;
				}
				if ((int)Singleton<MapHandler>.Instance.GetCurrentSegment() >= 5)
				{
					return null;
				}
				return MapHandler.CurrentCampfire;
			}
			catch
			{
				return null;
			}
		}

		private void TrySpawnCampfireBeacon(Campfire campfire, int segment)
		{
			//IL_0025: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)campfire == (Object)null)
			{
				return;
			}
			TryResolveFlareBeaconPrefab();
			if (!((Object)(object)_flareBeaconPrefab == (Object)null))
			{
				Vector3 val = ((Component)campfire).transform.position + Vector3.up * 12f;
				Vector3 right = ((Component)campfire).transform.right;
				Vector3 forward = ((Component)campfire).transform.forward;
				if (((Vector3)(ref right)).sqrMagnitude < 0.01f)
				{
					right = Vector3.right;
				}
				if (((Vector3)(ref forward)).sqrMagnitude < 0.01f)
				{
					forward = Vector3.forward;
				}
				right.y = 0f;
				forward.y = 0f;
				((Vector3)(ref right)).Normalize();
				((Vector3)(ref forward)).Normalize();
				for (int i = 0; i < 7; i++)
				{
					Vector3 val2 = val + Vector3.up * (14f * (float)i);
					SpawnBeaconFlareAt(val2);
					SpawnBeaconFlareAt(val2 + right * 4.5f);
					SpawnBeaconFlareAt(val2 - right * 4.5f);
					SpawnBeaconFlareAt(val2 + forward * 4.5f);
					SpawnBeaconFlareAt(val2 - forward * 4.5f);
				}
				_activeBeaconSegment = segment;
			}
		}

		private int GetBeaconSpawnCount()
		{
			return 35;
		}

		private void SpawnBeaconFlareAt(Vector3 position)
		{
			//IL_0001: 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)
			GameObject val = SpawnBeaconFlare(position);
			if (!((Object)(object)val == (Object)null))
			{
				ConfigureBeaconFlare(val, position);
				_campfireBeaconObjects.Add(val);
			}
		}

		private void TryResolveFlareBeaconPrefab()
		{
			if ((Object)(object)_flareBeaconPrefab != (Object)null)
			{
				return;
			}
			ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance;
			if ((Object)(object)instance == (Object)null || ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects == null)
			{
				return;
			}
			foreach (Item @object in ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects)
			{
				if ((Object)(object)@object != (Object)null && (Object)(object)((Component)@object).GetComponent<Flare>() != (Object)null)
				{
					_flareBeaconPrefab = @object;
					break;
				}
			}
		}

		private GameObject SpawnBeaconFlare(Vector3 position)
		{
			//IL_002b: 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_0012: 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)
			try
			{
				if (PhotonNetwork.InRoom)
				{
					return PhotonNetwork.InstantiateItemRoom(((Object)_flareBeaconPrefab).name, position, Quaternion.identity);
				}
				return Object.Instantiate<GameObject>(((Component)_flareBeaconPrefab).gameObject, position, Quaternion.identity);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[FogClimb] Failed to spawn beacon flare: " + ex.Message));
				return null;
			}
		}

		private void ConfigureBeaconFlare(GameObject beacon, Vector3 position)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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)
			if ((Object)(object)beacon == (Object)null)
			{
				return;
			}
			beacon.transform.position = position;
			beacon.transform.rotation = Quaternion.identity;
			Item component = beacon.GetComponent<Item>();
			if ((Object)(object)component != (Object)null)
			{
				Rigidbody val = default(Rigidbody);
				if (PhotonNetwork.InRoom && (Object)(object)beacon.GetComponent<PhotonView>() != (Object)null)
				{
					component.SetKinematicNetworked(true, position, Quaternion.identity);
				}
				else if (beacon.TryGetComponent<Rigidbody>(ref val))
				{
					val.isKinematic = true;
					val.linearVelocity = Vector3.zero;
					val.angularVelocity = Vector3.zero;
				}
			}
			Flare component2 = beacon.GetComponent<Flare>();
			if (!((Object)(object)component2 == (Object)null))
			{
				if (PhotonNetwork.InRoom && (Object)(object)beacon.GetComponent<PhotonView>() != (Object)null)
				{
					component2.LightFlare();
				}
				else
				{
					component2.SetFlareLitRPC();
				}
			}
		}

		private void CleanupCampfireBeacon()
		{
			bool flag = PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient;
			foreach (GameObject campfireBeaconObject in _campfireBeaconObjects)
			{
				if ((Object)(object)campfireBeaconObject == (Object)null)
				{
					continue;
				}
				try
				{
					if (flag && (Object)(object)campfireBeaconObject.GetComponent<PhotonView>() != (Object)null)
					{
						PhotonNetwork.Destroy(campfireBeaconObject);
					}
					else
					{
						Object.Destroy((Object)(object)campfireBeaconObject);
					}
				}
				catch
				{
				}
			}
			_campfireBeaconObjects.Clear();
			_activeBeaconSegment = -1;
		}

		private bool TryResolveCompassItem()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_compassItem != (Object)null)
			{
				return true;
			}
			ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance;
			if ((Object)(object)instance == (Object)null || ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects == null)
			{
				return false;
			}
			foreach (Item @object in ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects)
			{
				if (!((Object)(object)@object == (Object)null))
				{
					CompassPointer componentInChildren = ((Component)@object).GetComponentInChildren<CompassPointer>(true);
					if ((Object)(object)componentInChildren != (Object)null && (int)componentInChildren.compassType == 0)
					{
						_compassItem = @object;
						return true;
					}
				}
			}
			return false;
		}

		[IteratorStateMachine(typeof(<EnumerateTargetPlayers>d__134))]
		private IEnumerable<Player> EnumerateTargetPlayers()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnumerateTargetPlayers>d__134(-2);
		}

		private void GrantCompassToAllPlayers(string reason)
		{
			if (IsModFeatureEnabled() && HasFogAuthority())
			{
				_totalCompassGrantCount++;
				((BaseUnityPlugin)this).Logger.LogDebug((object)string.Format("[{0}] Queued compass grant #{1} ({2}).", "FogClimb", _totalCompassGrantCount, reason));
				SyncCompassGrantsToPlayers(force: true, reason);
			}
		}

		private void SyncCompassGrantsToPlayersIfNeeded()
		{
			if (IsModFeatureEnabled() && HasFogAuthority() && _totalCompassGrantCount > 0 && !(Time.unscaledTime - _lastCompassGrantSyncTime < 0.75f))
			{
				SyncCompassGrantsToPlayers(force: false, "periodic-sync");
			}
		}

		private void SyncCompassGrantsToPlayers(bool force, string reason)
		{
			if (!IsModFeatureEnabled() || !HasFogAuthority() || _totalCompassGrantCount <= 0)
			{
				return;
			}
			if (!TryResolveCompassItem())
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[FogClimb] Failed to resolve compass item while syncing grants (" + reason + ")."));
				return;
			}
			_lastCompassGrantSyncTime = Time.unscaledTime;
			HashSet<int> activePlayerKeys = new HashSet<int>();
			foreach (Player item in EnumerateTargetPlayers())
			{
				int playerCompassGrantKey = GetPlayerCompassGrantKey(item);
				activePlayerKeys.Add(playerCompassGrantKey);
				int i;
				int value;
				for (i = (_playerCompassGrantCounts.TryGetValue(playerCompassGrantKey, out value) ? value : 0); i < _totalCompassGrantCount && GrantCompassToPlayer(item, $"{reason}-{i + 1}/{_totalCompassGrantCount}"); i++)
				{
				}
				_playerCompassGrantCounts[playerCompassGrantKey] = i;
			}
			int[] array = _playerCompassGrantCounts.Keys.Where((int key) => !activePlayerKeys.Contains(key)).ToArray();
			foreach (int key2 in array)
			{
				_playerCompassGrantCounts.Remove(key2);
			}
		}

		private static int GetPlayerCompassGrantKey(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return 0;
			}
			PhotonView component = ((Component)player).GetComponent<PhotonView>();
			if (((component != null) ? component.Owner : null) != null)
			{
				return component.Owner.ActorNumber;
			}
			return ((Object)player).GetInstanceID();
		}

		private bool GrantCompassToPlayer(Player player, string reason)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)_compassItem == (Object)null)
			{
				return false;
			}
			ItemSlot val = default(ItemSlot);
			if (player.AddItem(_compassItem.itemID, (ItemInstanceData)null, ref val))
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("[FogClimb] Granted compass to " + ((Object)player).name + " (" + reason + ")."));
				return true;
			}
			return DropCompassNearPlayer(player, reason);
		}

		private bool DropCompassNearPlayer(Player player, string reason)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)_compassItem == (Object)null)
			{
				return false;
			}
			Vector3 compassDropPosition = GetCompassDropPosition(player);
			try
			{
				if (PhotonNetwork.InRoom)
				{
					PhotonNetwork.InstantiateItemRoom(((Object)_compassItem).name, compassDropPosition, Quaternion.identity);
				}
				else
				{
					Object.Instantiate<GameObject>(((Component)_compassItem).gameObject, compassDropPosition, Quaternion.identity);
				}
				((BaseUnityPlugin)this).Logger.LogDebug((object)("[FogClimb] Dropped fallback compass near " + ((Object)player).name + " (" + reason + ")."));
				return true;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[FogClimb] Failed to drop fallback compass near " + ((Object)player).name + " (" + reason + "): " + ex.Message));
				return false;
			}
		}

		private static Vector3 GetCompassDropPosition(Player player)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0043: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			Character character = player.character;
			Vector3 val = (((Object)(object)character != (Object)null) ? character.Center : ((Component)player).transform.position);
			Vector3 val2 = (((Object)(object)character != (Object)null) ? Vector3.ProjectOnPlane(((Component)character).transform.forward, Vector3.up) : Vector3.forward);
			if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
			{
				val2 = Vector3.forward;
			}
			return val + Vector3.up * 0.5f + ((Vector3)(ref val2)).normalized * 1.1f;
		}

		private void HandleFogUiConfigChanges()
		{
			bool flag = FogUiEnabled?.Value ?? true;
			float num = FogUiX?.Value ?? 60f;
			float num2 = FogUiY?.Value ?? 16f;
			float num3 = FogUiScale?.Value ?? 1.2f;
			if (flag != _lastFogUiEnabledState || !Approximately(num, _lastFogUiX) || !Approximately(num2, _lastFogUiY) || !Approximately(num3, _lastFogUiScale))
			{
				_lastFogUiEnabledState = flag;
				_lastFogUiX = num;
				_lastFogUiY = num2;
				_lastFogUiScale = num3;
				CreateFogUi();
			}
		}

		private bool ShouldShowFogUi()
		{
			if (IsModFeatureEnabled())
			{
				ConfigEntry<bool> fogUiEnabled = FogUiEnabled;
				if (fogUiEnabled == null || fogUiEnabled.Value)
				{
					return (Object)(object)ResolveHudCanvas() != (Object)null;
				}
			}
			return false;
		}

		private Canvas ResolveHudCanvas()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Invalid comparison between Unknown and I4
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			GUIManager instance = GUIManager.instance;
			if ((Object)(object)instance != (Object)null)
			{
				TextMeshProUGUI val = (((Object)(object)instance.itemPromptMain != (Object)null) ? instance.itemPromptMain : instance.interactNameText);
				if ((Object)(object)val != (Object)null)
				{
					Canvas componentInParent = ((Component)val).GetComponentInParent<Canvas>();
					if ((Object)(object)componentInParent != (Object)null)
					{
						return componentInParent;
					}
				}
			}
			Canvas[] array = Object.FindObjectsByType<Canvas>((FindObjectsSortMode)0);
			Canvas val2 = null;
			int num = int.MinValue;
			float num2 = -1f;
			Canvas[] array2 = array;
			foreach (Canvas val3 in array2)
			{
				if (!((Object)(object)val3 == (Object)null) && val3.isRootCanvas && ((Behaviour)val3).isActiveAndEnabled && ((Component)val3).gameObject.activeInHierarchy && (int)val3.renderMode != 2)
				{
					RectTransform component = ((Component)val3).GetComponent<RectTransform>();
					float num3;
					if (!((Object)(object)component != (Object)null))
					{
						num3 = 0f;
					}
					else
					{
						Rect rect = component.rect;
						float width = ((Rect)(ref rect)).width;
						rect = component.rect;
						num3 = Mathf.Abs(width * ((Rect)(ref rect)).height);
					}
					float num4 = num3;
					if ((Object)(object)val2 == (Object)null || val3.sortingOrder > num || (val3.sortingOrder == num && num4 > num2))
					{
						val2 = val3;
						num = val3.sortingOrder;
						num2 = num4;
					}
				}
			}
			return val2;
		}

		private TextMeshProUGUI ResolveFogStyleSource()
		{
			GUIManager instance = GUIManager.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			if ((Object)(object)instance.itemPromptMain != (Object)null)
			{
				return instance.itemPromptMain;
			}
			if ((Object)(object)instance.interactNameText != (Object)null)
			{
				return instance.interactNameText;
			}
			return instance.interactPromptText;
		}

		private void ApplyGameTextStyle(TextMeshProUGUI target, Color color, float sizeMultiplier = 1f)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)target == (Object)null))
			{
				TextMeshProUGUI val = ResolveFogStyleSource();
				if ((Object)(object)val != (Object)null)
				{
					((TMP_Text)target).font = ((TMP_Text)val).font;
					((TMP_Text)target).fontSharedMaterial = ((TMP_Text)val).fontSharedMaterial;
					((TMP_Text)target).fontStyle = ((TMP_Text)val).fontStyle;
					((TMP_Text)target).characterSpacing = ((TMP_Text)val).characterSpacing;
					((TMP_Text)target).wordSpacing = ((TMP_Text)val).wordSpacing;
					((TMP_Text)target).lineSpacing = ((TMP_Text)val).lineSpacing;
				}
				else if ((Object)(object)TMP_Settings.defaultFontAsset != (Object)null)
				{
					((TMP_Text)target).font = TMP_Settings.defaultFontAsset;
				}
				((TMP_Text)target).textWrappingMode = (TextWrappingModes)0;
				((TMP_Text)target).fontSize = 18f * sizeMultiplier;
				((Graphic)target).color = color;
				((TMP_Text)target).alignment = (TextAlignmentOptions)1025;
			}
		}

		private void CreateFogUi()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00c7: 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_00dd: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			CleanupFogUi();
			if (!ShouldShowFogUi())
			{
				return;
			}
			try
			{
				Canvas val = ResolveHudCanvas();
				if (!((Object)(object)val == (Object)null))
				{
					GameObject val2 = new GameObject("FogClimbUI");
					val2.transform.SetParent(((Component)val).transform, false);
					_fogUiRect = val2.AddComponent<RectTransform>();
					_fogUiRect.anchorMin = Vector2.zero;
					_fogUiRect.anchorMax = Vector2.zero;
					_fogUiRect.pivot = Vector2.zero;
					_fogUiRect.sizeDelta = new Vector2(920f, 30f);
					val2.transform.SetAsLastSibling();
					GameObject val3 = new GameObject("FogClimbUILabel");
					val3.transform.SetParent(val2.transform, false);
					RectTransform obj = val3.AddComponent<RectTransform>();
					obj.anchorMin = Vector2.zero;
					obj.anchorMax = Vector2.zero;
					obj.pivot = Vector2.zero;
					obj.anchoredPosition = Vector2.zero;
					obj.sizeDelta = new Vector2(920f, 30f);
					_fogUiText = val3.AddComponent<TextMeshProUGUI>();
					ApplyGameTextStyle(_fogUiText, Color.white);
					((TMP_Text)_fogUiText).text = "FogClimb";
					ClampFogUiToCanvas();
					SetFogUiVisible(visible: true);
				}
			}
			catch
			{
				CleanupFogUi();
			}
		}

		private void UpdateFogUi()
		{
			if (FogUiEnabled != null && !FogUiEnabled.Value)
			{
				SetFogUiVisible(visible: false);
				return;
			}
			if (!ShouldShowFogUi())
			{
				SetFogUiVisible(visible: false);
				return;
			}
			if ((Object)(object)_fogUiRect == (Object)null || (Object)(object)_fogUiText == (Object)null)
			{
				CreateFogUi();
				if ((Object)(object)_fogUiRect == (Object)null || (Object)(object)_fogUiText == (Object)null)
				{
					return;
				}
			}
			SetFogUiVisible(visible: true);
			ClampFogUiToCanvas();
			bool flag = DetectChineseLanguage();
			string text = "FogClimb";
			float num = (((Object)(object)_orbFogHandler != (Object)null) ? _orbFogHandler.speed : (FogSpeed?.Value ?? 2f));
			string fogStateLabel = GetFogStateLabel(flag);
			string fogCountdownLabel = GetFogCountdownLabel(flag);
			if ((Object)(object)_orbFogHandler == (Object)null)
			{
				float num2 = FogDelay?.Value ?? 90f;
				((TMP_Text)_fogUiText).text = (flag ? $"{text}  |  速度: {num:F2}  |  延迟: {num2:F0}s  |  状态: {fogStateLabel}" : $"{text}  |  Speed: {num:F2}  |  Delay: {num2:F0}s  |  State: {fogStateLabel}");
			}
			else
			{
				((TMP_Text)_fogUiText).text = (flag ? $"{text}  |  速度: {num:F2}  |  状态: {fogStateLabel}{fogCountdownLabel}" : $"{text}  |  Speed: {num:F2}  |  State: {fogStateLabel}{fogCountdownLabel}");
			}
		}

		private string GetFogStateLabel(bool isChinese)
		{
			if (!IsModFeatureEnabled())
			{
				if (!isChinese)
				{
					return "OFF";
				}
				return "关闭";
			}
			if ((Object)(object)_orbFogHandler == (Object)null)
			{
				if (!isChinese)
				{
					return "LOBBY";
				}
				return "大厅";
			}
			if (HasFogAuthority() && !_initialDelayCompleted && _orbFogHandler.currentID == 0)
			{
				if (!isChinese)
				{
					return "WAITING";
				}
				return "等待中";
			}
			if (_orbFogHandler.isMoving)
			{
				if (!isChinese)
				{
					return "RUNNING";
				}
				return "运行中";
			}
			if (_orbFogHandler.hasArrived)
			{
				if (!isChinese)
				{
					return "ARRIVED";
				}
				return "已到达";
			}
			if (!isChinese)
			{
				return "IDLE";
			}
			return "待机中";
		}

		private string GetFogCountdownLabel(bool isChinese)
		{
			if (!HasFogAuthority() || (Object)(object)_orbFogHandler == (Object)null || _initialDelayCompleted || _orbFogHandler.currentID != 0)
			{
				return string.Empty;
			}
			float num = Mathf.Max((FogDelay?.Value ?? 0f) - _fogDelayTimer, 0f);
			if (!isChinese)
			{
				return $"  |  Starts In: {num:F1}s";
			}
			return $"  |  倒计时: {num:F1}s";
		}

		private void ClampFogUiToCanvas()
		{
			if ((Object)(object)_fogUiRect == (Object)null)
			{
				return;
			}
			Canvas componentInParent = ((Component)_fogUiRect).GetComponentInParent<Canvas>();
			if (!((Object)(object)componentInParent == (Object)null))
			{
				Canvas.ForceUpdateCanvases();
				if ((Object)(object)((Transform)_fogUiRect).parent != (Object)(object)((Component)componentInParent).transform)
				{
					((Transform)_fogUiRect).SetParent(((Component)componentInParent).transform, false);
				}
				RectTransform component = ((Component)componentInParent).GetComponent<RectTransform>();
				if (!((Object)(object)component == (Object)null))
				{
					ApplyBottomLeftAnchoredRect(_fogUiRect, component, 920f, 30f, FogUiScale?.Value ?? 1.2f, FogUiX?.Value ?? 60f, FogUiY?.Value ?? 16f);
				}
			}
		}

		private static void ApplyBottomLeftAnchoredRect(RectTransform target, RectTransform canvasRect, float width, float height, float scale, float x, float y)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)target == (Object)null) && !((Object)(object)canvasRect == (Object)null))
			{
				((Transform)target).localScale = Vector3.one * Mathf.Max(scale, 0.5f);
				target.anchorMin = Vector2.zero;
				target.anchorMax = Vector2.zero;
				target.pivot = Vector2.zero;
				target.sizeDelta = new Vector2(width, height);
				float num = width * ((Transform)target).localScale.x;
				float num2 = height * ((Transform)target).localScale.y;
				Rect rect = canvasRect.rect;
				float num3 = Mathf.Clamp(x, 0f, Mathf.Max(0f, ((Rect)(ref rect)).width - num));
				float num4 = Mathf.Clamp(y, 0f, Mathf.Max(0f, ((Rect)(ref rect)).height - num2));
				target.anchoredPosition = new Vector2(num3, num4);
			}
		}

		private void SetFogUiVisible(bool visible)
		{
			if ((Object)(object)_fogUiRect != (Object)null)
			{
				((Component)_fogUiRect).gameObject.SetActive(visible);
			}
		}

		private void CleanupFogUi()
		{
			if ((Object)(object)_fogUiRect != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_fogUiRect).gameObject);
			}
			_fogUiRect = null;
			_fogUiText = null;
		}

		private void RestoreVanillaFogSpeed()
		{
			if ((Object)(object)_orbFogHandler != (Object)null)
			{
				_orbFogHandler.speed = 0.3f;
			}
		}

		private void ResetFogRuntimeState()
		{
			_fogStateInitialized = false;
			_initialDelayCompleted = false;
			_initialCompassGranted = false;
			_totalCompassGrantCount = 0;
			_trackedFogOriginId = -1;
			_fogDelayTimer = 0f;
			_lastFogStateSyncTime = -0.18f;
			_lastRemoteStatusSyncTime = -0.25f;
			_lastBeaconRefreshTime = -1f;
			_lastCompassGrantSyncTime = -0.75f;
			_fogHandlerSearchTimer = 0f;
			_grantedCampfireCompassIds.Clear();
			_playerCompassGrantCounts.Clear();
		}

		private static bool DetectChineseLanguage()
		{
			if (TryGetConfiguredGameLanguage(out var isChineseLanguage))
			{
				return isChineseLanguage;
			}
			if (TryGetLocalizedTextLanguageName(out var languageName))
			{
				return IsChineseLanguageName(languageName);
			}
			return false;
		}

		private static bool TryGetConfiguredGameLanguage(out bool isChineseLanguage)
		{
			isChineseLanguage = false;
			try
			{
				if (!PlayerPrefs.HasKey("LanguageSetting"))
				{
					return false;
				}
				int result = PlayerPrefs.GetInt("LanguageSetting", int.MinValue);
				if (result != int.MinValue)
				{
					isChineseLanguage = result == 9;
					return true;
				}
				string @string = PlayerPrefs.GetString("LanguageSetting", string.Empty);
				if (string.IsNullOrWhiteSpace(@string))
				{
					return false;
				}
				if (int.TryParse(@string, NumberStyles.Integer, CultureInfo.InvariantCulture, out result))
				{
					isChineseLanguage = result == 9;
					return true;
				}
				isChineseLanguage = IsChineseLanguageName(@string);
				return true;
			}
			catch
			{
				return false;
			}
		}

		private static bool TryGetLocalizedTextLanguageName(out string languageName)
		{
			languageName = string.Empty;
			try
			{
				languageName = ((object)(Language)(ref LocalizedText.CURRENT_LANGUAGE)).ToString();
				return !string.IsNullOrWhiteSpace(languageName);
			}
			catch
			{
				return false;
			}
		}

		private static bool IsChineseLanguageName(string languageName)
		{
			if (string.IsNullOrWhiteSpace(languageName))
			{
				return false;
			}
			if (languageName.IndexOf("Chinese", StringComparison.OrdinalIgnoreCase) < 0 && languageName.IndexOf("中文", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return languageName.StartsWith("zh", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private static string GetSectionName(bool isChineseLanguage)
		{
			if (!isChineseLanguage)
			{
				return "Fog";
			}
			return "毒雾";
		}

		private static string GetKeyName(ConfigKey configKey, bool isChineseLanguage)
		{
			return configKey switch
			{
				ConfigKey.ModEnabled => isChineseLanguage ? "模组开关" : "Enable Mod", 
				ConfigKey.FogSpeed => isChineseLanguage ? "毒雾移动速度" : "Fog Speed", 
				ConfigKey.FogDelay => isChineseLanguage ? "毒雾延迟时间s" : "Fog Delay (s)", 
				ConfigKey.FogUiEnabled => isChineseLanguage ? "UI启用" : "Fog UI", 
				ConfigKey.FogUiX => isChineseLanguage ? "UI X位置" : "UI X Position", 
				ConfigKey.FogUiY => isChineseLanguage ? "UI Y位置" : "UI Y Position", 
				ConfigKey.FogUiScale => isChineseLanguage ? "UI缩放" : "UI Scale", 
				_ => string.Empty, 
			};
		}

		private static string GetLocalizedDescription(ConfigKey configKey, bool isChineseLanguage)
		{
			return configKey switch
			{
				ConfigKey.ModEnabled => isChineseLanguage ? "启用独立毒雾模组。仅主机需要安装;主机会同步毒雾进度、冷伤害压制与篝火光柱指示。" : "Enable the standalone fog mod. Only the host needs it; the host synchronizes fog progress, cold suppression, and the campfire beacon.", 
				ConfigKey.FogSpeed => isChineseLanguage ? "毒雾移动速度,范围 0.3~5,默认 2。" : "Fog movement speed. Range 0.3 to 5, default 2.", 
				ConfigKey.FogDelay => isChineseLanguage ? "首段毒雾开始移动前的延迟,范围 0~150 秒,默认 90 秒。" : "Delay before the first fog segment starts moving. Range 0 to 150 seconds, default 90 seconds.", 
				ConfigKey.FogUiEnabled => isChineseLanguage ? "显示 FogClimb HUD 文本。" : "Show the FogClimb HUD text.", 
				ConfigKey.FogUiX => isChineseLanguage ? "毒雾 HUD 的 X 位置,默认 60。" : "Fog HUD X position. Default 60.", 
				ConfigKey.FogUiY => isChineseLanguage ? "毒雾 HUD 的 Y 位置,默认 16。" : "Fog HUD Y position. Default 16.", 
				ConfigKey.FogUiScale => isChineseLanguage ? "毒雾 HUD 缩放,默认 1.2。" : "Fog HUD scale. Default 1.2.", 
				_ => string.Empty, 
			};
		}

		private static bool HasFogAuthority()
		{
			if (PhotonNetwork.InRoom)
			{
				return PhotonNetwork.IsMasterClient;
			}
			return true;
		}

		internal static bool IsModFeatureEnabled()
		{
			if (ModEnabled != null)
			{
				return ModEnabled.Value;
			}
			return true;
		}

		internal static bool ShouldSuppressFogColdDamage()
		{
			return IsModFeatureEnabled();
		}

		internal static bool IsInternalColdClearInProgress()
		{
			return _isClearingColdStatus;
		}

		internal static bool ShouldSuppressAmbientColdDamageFor(CharacterAfflictions afflictions)
		{
			if ((Object)(object)afflictions != (Object)null)
			{
				return ShouldSuppressAmbientColdDamageFor(afflictions.character);
			}
			return false;
		}

		internal static bool ShouldSuppressAmbientColdDamageFor(Character character)
		{
			if (IsModFeatureEnabled() && (Object)(object)character != (Object)null && !character.isBot && !character.isZombie)
			{
				return (Object)(object)character == (Object)(object)Character.localCharacter;
			}
			return false;
		}

		internal static bool ShouldBlockVanillaOrbFogWait(OrbFogHandler fogHandler)
		{
			if (!IsModFeatureEnabled() || (Object)(object)Instance == (Object)null || (Object)(object)fogHandler == (Object)null || !HasFogAuthority())
			{
				return false;
			}
			if (!Instance._fogStateInitialized)
			{
				Instance.InitializeFogRuntimeState(fogHandler);
			}
			Instance.UpdateTrackedFogOrigin();
			if (fogHandler.currentID == 0)
			{
				return !Instance._initialDelayCompleted;
			}
			return false;
		}

		internal static void EnforceAmbientColdSuppression(CharacterAfflictions afflictions)
		{
			if (!ShouldSuppressAmbientColdDamageFor(afflictions))
			{
				return;
			}
			try
			{
				if (!_isClearingColdStatus)
				{
					_isClearingColdStatus = true;
					afflictions.SetStatus((STATUSTYPE)2, 0f, false);
				}
			}
			catch
			{
			}
			finally
			{
				_isClearingColdStatus = false;
			}
			int index = 2;
			string[] coldStatusArrayFields = ColdStatusArrayFields;
			foreach (string fieldName in coldStatusArrayFields)
			{
				ZeroColdStatusArrayField(afflictions, fieldName, index);
			}
			try
			{
				CharacterData val = afflictions.character?.data;
				FieldInfo fieldInfo = ((object)val)?.GetType().GetField("sinceAddedCold", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (fieldInfo != null && fieldInfo.FieldType == typeof(float))
				{
					fieldInfo.SetValue(val, 0f);
				}
			}
			catch
			{
			}
		}

		internal static void ClearLocalAmbientColdStatus()
		{
			if (IsModFeatureEnabled() && !((Object)(object)Instance == (Object)null) && !(Time.unscaledTime - Instance._lastColdClearTime < 0.2f))
			{
				CharacterAfflictions val = Character.localCharacter?.refs?.afflictions;
				if (!((Object)(object)val == (Object)null))
				{
					Instance._lastColdClearTime = Time.unscaledTime;
					EnforceAmbientColdSuppression(val);
				}
			}
		}

		internal static void ClearLocalFogColdStatus()
		{
			ClearLocalAmbientColdStatus();
		}

		internal static void NotifyCampfireLit(Campfire campfire)
		{
			Instance?.HandleCampfireLit(campfire);
		}

		private void HandleCampfireLit(Campfire campfire)
		{
			if (IsModFeatureEnabled() && HasFogAuthority() && !((Object)(object)campfire == (Object)null))
			{
				int instanceID = ((Object)campfire).GetInstanceID();
				if (_grantedCampfireCompassIds.Add(instanceID))
				{
					GrantCompassToAllPlayers($"campfire-{instanceID}");
				}
			}
		}

		private static void ZeroColdStatusArrayField(CharacterAfflictions afflictions, string fieldName, int index)
		{
			try
			{
				if (typeof(CharacterAfflictions).GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(afflictions) is float[] array && index >= 0 && index < array.Length)
				{
					array[index] = 0f;
				}
			}
			catch
			{
			}
		}
	}
}