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
{
}
}
}
}