Decompiled source of FogDistance v1.5.5
plugins/PeakFogDistance.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; 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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("BroneKot")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Configurable client-side PEAK HUD for fog, lava, Gloom, and lost-soul clearance, hazard timing, and campfire fuel.")] [assembly: AssemblyFileVersion("1.5.5.0")] [assembly: AssemblyInformationalVersion("1.5.5+57af20a0b2944a822a0843e978b05b6fa90816fd")] [assembly: AssemblyProduct("PeakFogDistance")] [assembly: AssemblyTitle("PeakFogDistance")] [assembly: AssemblyVersion("1.5.5.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PeakFogDistance { internal static class HazardMath { internal const float MinimumSpeed = 0.001f; internal const double SphereStopRadius = 30.0; internal static double RisingClearance(double centerY, double headY, double surfaceY, bool usesHeadProbe) { return (usesHeadProbe ? headY : (centerY - 0.5)) - surfaceY; } internal static double StatusFieldClearance(double headY, double bottomY, double topY, double horizontalInset, double protectionClearance) { return Math.Max(Math.Max(Math.Max(headY - topY, bottomY - headY), 0.0 - horizontalInset), protectionClearance); } internal static bool CampfireBurnedOut(bool wasLit, bool isLit) { if (wasLit) { return !isLit; } return false; } internal static bool CountdownPaused(HazardKind kind, bool? readyToStart) { if (kind == HazardKind.Gloom) { return readyToStart == false; } return false; } internal static double AdvanceCountdown(HazardKind kind, bool? readyToStart, double estimate, double previousObserved, double observed, double elapsed, bool authoritative, double maximum) { return HudMath.ReconcileSyncedElapsedTimer(estimate, previousObserved, observed, elapsed, kind == HazardKind.Gloom && readyToStart != true, authoritative || (kind == HazardKind.Gloom && !readyToStart.HasValue), maximum); } internal static HazardState Moving(HazardKind kind, double contactClearanceUnits, double clearanceMeters, bool isDanger, double speed, double? maximumAdvance = null, bool contactAtLimit = true) { if (!HudMath.IsFinite(speed) || !HudMath.IsFinite(contactClearanceUnits) || (maximumAdvance.HasValue && !HudMath.IsFinite(maximumAdvance.Value))) { return new HazardState(kind, HazardPhase.Unavailable, clearanceMeters, isDanger, null); } if (speed < -0.0010000000474974513) { return new HazardState(kind, HazardPhase.Receding, clearanceMeters, isDanger, null); } if (speed <= 0.0010000000474974513) { return new HazardState(kind, HazardPhase.Stopped, clearanceMeters, isDanger, null); } if (!isDanger && maximumAdvance.HasValue && (contactClearanceUnits > maximumAdvance.Value || (!contactAtLimit && contactClearanceUnits >= maximumAdvance.Value))) { return new HazardState(kind, HazardPhase.OutOfReach, clearanceMeters, isDanger: false, null); } return new HazardState(kind, HazardPhase.Moving, clearanceMeters, isDanger, Math.Max(0.0, contactClearanceUnits) / speed); } } internal sealed class HazardMonitor { private const float InitialLookupBackoffSeconds = 0.5f; private const float MaximumLookupBackoffSeconds = 2f; private const float FirePollIntervalSeconds = 0.2f; private const float CampfireReferenceLookupIntervalSeconds = 1f; private const float MinimumSpeed = 0.001f; private const float LegacyLavaStopHeightUnits = 1150f; private static readonly FieldInfo? FlatFogWaitingField = FindInstanceField(typeof(Fog), "waiting"); private static readonly FieldInfo? FlatFogWaitTimeField = FindInstanceField(typeof(Fog), "sinceStop"); private static readonly FieldInfo? FlatFogCurrentStopField = FindInstanceField(typeof(Fog), "currentStop"); private static readonly FieldInfo? FlatFogStopsField = FindInstanceField(typeof(Fog), "stops"); private static readonly FieldInfo? LegacyLavaMovingField = FindInstanceField(typeof(MovingLava), "timeToMove"); private static readonly FieldInfo? LavaBoundsField = FindInstanceField(typeof(Lava), "bounds"); private static readonly FieldInfo? OrbFogSphereField = FindInstanceField(typeof(OrbFogHandler), "sphere"); private static readonly FieldInfo? OrbFogOriginsField = FindInstanceField(typeof(OrbFogHandler), "origins"); private static readonly FieldInfo? RisingFieldTypeField = typeof(LavaRising).GetField("risingFieldType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo? RisingFieldRequiredSegmentField = typeof(LavaRising).GetField("requiredSegment", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo? RisingFieldWaitForEventField = typeof(LavaRising).GetField("waitForEvent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly MethodInfo? RisingFieldReadyToStartMethod = typeof(LavaRising).GetMethod("ReadyToStart", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); private readonly StatusFieldReader _statusFieldReader = new StatusFieldReader(); private readonly ManualLogSource _log; private readonly HashSet<string> _reportedErrors = new HashSet<string>(StringComparer.Ordinal); private Fog? _flatFog; private FogSphere? _sphereFog; private OrbFogHandler? _sphereFogHandler; private LavaRising? _risingLava; private MovingLava? _legacyRisingLava; private LavaRising? _risingLavaRendererOwner; private MovingLava? _legacyLavaRendererOwner; private LavaRising? _risingLavaDamageOwner; private MovingLava? _legacyLavaDamageOwner; private Lava? _risingLavaDamageSource; private Lava? _legacyLavaDamageSource; private MeshRenderer? _risingLavaRenderer; private MeshRenderer? _legacyLavaRenderer; private float _nextRisingRendererLookupAt; private float _nextLegacyRendererLookupAt; private float _nextRisingDamageLookupAt; private float _nextLegacyDamageLookupAt; private LavaRising? _lavaWaitOwner; private float _lavaWaitEstimate; private float _lavaWaitLastObserved; private float _lavaWaitLastSampleAt; private bool _lavaWaitInitialized; private Segment? _lastSegment; private float _nextLookupAt; private float _lookupBackoffSeconds = 0.5f; private Campfire? _trackedCampfire; private Campfire? _currentCampfire; private Campfire? _previousCampfire; private bool _trackedCampfireWasLit; private bool _trackedCampfirePaused; private float _campfireOutMessageUntil; private float _nextFirePollAt; private float _nextCampfireReferenceLookupAt; private bool _wasInGameplay; internal HazardMonitor(ManualLogSource log) { _log = log; ReportMissingCompatibilityMembers(); } internal HudSnapshot Capture(float campfireOutMessageSeconds) { if (!GameHandler.IsInGameplayScene || !GameHandler.IsOnIsland) { if (_wasInGameplay) { ResetSceneState(); } return EmptySnapshot(); } _wasInGameplay = true; Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { return EmptySnapshot(); } Character observedCharacter = Character.observedCharacter; Character character = (((Object)(object)observedCharacter != (Object)null) ? observedCharacter : localCharacter); bool spectating = (Object)(object)observedCharacter != (Object)null && (Object)(object)observedCharacter != (Object)(object)localCharacter; RefreshReferences(); PollCampfire(Mathf.Max(0f, campfireOutMessageSeconds)); return new HudSnapshot(CaptureHazard(character), CaptureFireState(), spectating); } internal void ResetSceneState() { _flatFog = null; _sphereFog = null; _sphereFogHandler = null; _risingLava = null; _legacyRisingLava = null; _risingLavaRendererOwner = null; _legacyLavaRendererOwner = null; _risingLavaDamageOwner = null; _legacyLavaDamageOwner = null; _risingLavaDamageSource = null; _legacyLavaDamageSource = null; _risingLavaRenderer = null; _legacyLavaRenderer = null; _statusFieldReader.Reset(); ResetLavaWaitEstimate(); _lastSegment = null; _nextLookupAt = 0f; _lookupBackoffSeconds = 0.5f; ResetCampfireTracking(); _wasInGameplay = false; } private void RefreshReferences() { //IL_0045: 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_0018: Unknown result type (might be due to invalid IL or missing references) MapHandler instance = Singleton<MapHandler>.Instance; Segment? val = null; if ((Object)(object)instance != (Object)null) { try { val = instance.GetCurrentSegment(); } catch (Exception exception) { ReportOnce("map-segment", "Could not read the current PEAK segment.", exception); } } if (val != _lastSegment) { _lastSegment = val; _flatFog = null; _sphereFog = null; _sphereFogHandler = null; _risingLava = null; _legacyRisingLava = null; _risingLavaRendererOwner = null; _legacyLavaRendererOwner = null; _risingLavaDamageOwner = null; _legacyLavaDamageOwner = null; _risingLavaDamageSource = null; _legacyLavaDamageSource = null; _risingLavaRenderer = null; _legacyLavaRenderer = null; _statusFieldReader.Reset(); ResetLavaWaitEstimate(); _nextLookupAt = 0f; _lookupBackoffSeconds = 0.5f; ResetCampfireTracking(); } if (Time.unscaledTime < _nextLookupAt) { if ((Object)(object)instance != (Object)null && IsActive((Behaviour?)(object)instance.lavaRising) && IsRisingFieldForSegment(instance.lavaRising, val)) { _risingLava = instance.lavaRising; } return; } try { _sphereFogHandler = ResolveActive<OrbFogHandler>(_sphereFogHandler, (Func<OrbFogHandler?>)GetOrbFogHandler); _sphereFog = ResolveSphereFog(_sphereFogHandler, _sphereFog); bool num = IsUsableSphereFog(_sphereFogHandler, _sphereFog); if (!num) { _flatFog = ResolveActive<Fog>(_flatFog, (Func<Fog?>)(() => Object.FindAnyObjectByType<Fog>())); } bool flag = IsRisingHazardSegment(val); if (flag) { _risingLava = ResolveRisingField(_risingLava, instance, val); if (!IsActive((Behaviour?)(object)_risingLava)) { _legacyRisingLava = ResolveActive<MovingLava>(_legacyRisingLava, (Func<MovingLava?>)(() => Object.FindAnyObjectByType<MovingLava>())); } } bool flag2 = num || IsActive((Behaviour?)(object)_flatFog) || (flag && (IsActive((Behaviour?)(object)_risingLava) || IsActive((Behaviour?)(object)_legacyRisingLava))); _nextLookupAt = Time.unscaledTime + (flag2 ? 1f : _lookupBackoffSeconds); _lookupBackoffSeconds = (flag2 ? 0.5f : Mathf.Min(2f, _lookupBackoffSeconds * 2f)); } catch (Exception exception2) { ReportOnce("hazard-lookup", "PEAK hazard discovery failed; retrying with backoff.", exception2); _nextLookupAt = Time.unscaledTime + _lookupBackoffSeconds; _lookupBackoffSeconds = Mathf.Min(2f, _lookupBackoffSeconds * 2f); } } private HazardState CaptureHazard(Character character) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) Vector3 center = character.Center; if (IsRisingHazardSegment(_lastSegment)) { HazardState result = CaptureRisingLava(character); if (result.Kind != HazardKind.None) { return result; } HazardState result2 = CaptureLegacyLava(center); if (result2.Kind != HazardKind.None) { return result2; } } HazardState result3 = CaptureSphereFog(center); if (result3.Kind != HazardKind.None) { return result3; } return CaptureFlatFog(center); } private HazardState CaptureSphereFog(Vector3 playerPosition) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) OrbFogHandler sphereFogHandler = _sphereFogHandler; if ((Object)(object)sphereFogHandler == (Object)null || !((Behaviour)sphereFogHandler).isActiveAndEnabled) { return EmptyHazard(); } FogSphere sphereFog = _sphereFog; if ((Object)(object)sphereFog == (Object)null || !((Behaviour)sphereFog).isActiveAndEnabled || !Ascents.fogEnabled) { return EmptyHazard(); } float num = Mathf.Max(0f, sphereFog.currentSize); float num2 = Vector3.Distance(playerPosition, sphereFog.fogPoint); float num3 = num - num2; double clearanceMeters = ToMeters(num3); bool isDanger = num2 > num && Mathf.Approximately(sphereFog.ENABLE, 1f); if (IsFogDisabledForCurrentOrigin(sphereFogHandler)) { return EmptyHazard(); } if (!sphereFogHandler.isMoving) { if (sphereFogHandler.hasArrived) { return new HazardState(HazardKind.Fog, HazardPhase.Stopped, clearanceMeters, isDanger, null); } if (sphereFogHandler.currentID == 0) { return new HazardState(HazardKind.Fog, HazardPhase.WaitingForTeam, clearanceMeters, isDanger, null); } double value = Math.Max(0.0, sphereFogHandler.maxWaitTime - sphereFogHandler.currentWaitTime); HazardPhase phase = (sphereFogHandler.PlayersAreResting ? HazardPhase.Paused : HazardPhase.Countdown); return new HazardState(HazardKind.Fog, phase, clearanceMeters, isDanger, value); } return HazardMath.Moving(HazardKind.Fog, num3, clearanceMeters, isDanger, sphereFogHandler.speed, Math.Max(0.0, (double)num - 30.0), contactAtLimit: false); } private HazardState CaptureFlatFog(Vector3 playerPosition) { //IL_001e: 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) Fog flatFog = _flatFog; if ((Object)(object)flatFog == (Object)null || !((Behaviour)flatFog).isActiveAndEnabled) { return EmptyHazard(); } float num = playerPosition.y - ((Component)flatFog).transform.position.y; double clearanceMeters = ToMeters(num); bool isDanger = num < 0f; if (!TryRead<bool>(FlatFogWaitingField, flatFog, out var value) || !TryRead<int>(FlatFogCurrentStopField, flatFog, out var value2) || !TryRead<Transform[]>(FlatFogStopsField, flatFog, out Transform[] value3)) { return new HazardState(HazardKind.Fog, HazardPhase.Unavailable, clearanceMeters, isDanger, null); } if (value) { if (value2 <= 0) { return new HazardState(HazardKind.Fog, HazardPhase.WaitingForTeam, clearanceMeters, isDanger, null); } PhotonView component = ((Component)flatFog).GetComponent<PhotonView>(); if ((Object)(object)component != (Object)null && !component.IsMine) { return new HazardState(HazardKind.Fog, HazardPhase.WaitingForTrigger, clearanceMeters, isDanger, null); } if (!TryRead<float>(FlatFogWaitTimeField, flatFog, out var value4)) { return new HazardState(HazardKind.Fog, HazardPhase.Unavailable, clearanceMeters, isDanger, null); } double value5 = Math.Max(0.0, flatFog.maxWaitTime - value4); return new HazardState(HazardKind.Fog, HazardPhase.Countdown, clearanceMeters, isDanger, value5); } if (value3 != null && value2 >= value3.Length) { return new HazardState(HazardKind.Fog, HazardPhase.Stopped, clearanceMeters, isDanger, null); } float fogSpeed = flatFog.fogSpeed; if (!float.IsFinite(fogSpeed)) { return new HazardState(HazardKind.Fog, HazardPhase.Unavailable, clearanceMeters, isDanger, null); } if (fogSpeed < -0.001f) { return new HazardState(HazardKind.Fog, HazardPhase.Receding, clearanceMeters, isDanger, null); } if (fogSpeed <= 0.001f) { return new HazardState(HazardKind.Fog, HazardPhase.Stopped, clearanceMeters, isDanger, null); } double value6 = Math.Max(0.0, num) / (double)fogSpeed; return new HazardState(HazardKind.Fog, HazardPhase.Moving, clearanceMeters, isDanger, value6); } private static bool IsRisingHazardSegment(Segment? segment) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 if (segment.HasValue) { Segment valueOrDefault = segment.GetValueOrDefault(); if (valueOrDefault - 4 <= 2) { return true; } } return false; } private static HazardKind GetRisingHazardKind(LavaRising risingField) { try { string text = RisingFieldTypeField?.GetValue(risingField)?.ToString(); return (text == "Gloom") ? HazardKind.Gloom : ((!(text == "VoidGhosts")) ? HazardKind.Lava : HazardKind.LostSouls); } catch { return HazardKind.Lava; } } private HazardState CaptureRisingLava(Character character) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_00d8: 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_00f6: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) Vector3 center = character.Center; LavaRising risingLava = _risingLava; if ((Object)(object)risingLava == (Object)null || !((Behaviour)risingLava).isActiveAndEnabled || (Object)(object)risingLava.lava == (Object)null) { return EmptyHazard(); } if (!IsRisingFieldForCurrentSegment(risingLava)) { return EmptyHazard(); } HazardKind risingHazardKind = GetRisingHazardKind(risingLava); bool flag = risingHazardKind == HazardKind.Gloom; bool flag2 = flag || risingHazardKind == HazardKind.LostSouls; Vector3 val = (flag2 ? character.Head : center); double protectionClearance = double.NegativeInfinity; Bounds bounds; Bounds? val2 = ((!flag2) ? GetRisingFieldBounds(risingLava) : (_statusFieldReader.TryRead(risingLava, val, flag, out bounds, out protectionClearance) ? new Bounds?(bounds) : ((Bounds?)null))); bool hasValue = val2.HasValue; bool flag3 = hasValue && !IsInsideRisingFieldFootprint(val2.GetValueOrDefault(), val); Rigidbody lava = risingLava.lava; Bounds valueOrDefault = val2.GetValueOrDefault(); float num = ((flag2 && hasValue) ? ((Bounds)(ref valueOrDefault)).max.y : lava.position.y); double num2 = HazardMath.RisingClearance(center.y, val.y, num, flag2); double worldUnits = num2; bool flag4 = flag && protectionClearance >= 0.0; bool isDanger = num2 <= 0.0; if (flag2 && hasValue) { double horizontalInset = Math.Min(Math.Min(val.x - ((Bounds)(ref valueOrDefault)).min.x, ((Bounds)(ref valueOrDefault)).max.x - val.x), Math.Min(val.z - ((Bounds)(ref valueOrDefault)).min.z, ((Bounds)(ref valueOrDefault)).max.z - val.z)); worldUnits = HazardMath.StatusFieldClearance(val.y, ((Bounds)(ref valueOrDefault)).min.y, ((Bounds)(ref valueOrDefault)).max.y, horizontalInset, protectionClearance); isDanger = ((Bounds)(ref valueOrDefault)).Contains(val) && !flag4; } double clearanceMeters = ToMeters(worldUnits); if (!risingLava.started) { bool isMasterClient = PhotonNetwork.IsMasterClient; float secondsWaitedToStart = risingLava.secondsWaitedToStart; bool? readyToStart = ReadRisingReadyToStart(risingLava); bool valueOrDefault2 = readyToStart == true; if (!(secondsWaitedToStart > 0f) && !(!isMasterClient && Ascents.fogEnabled && valueOrDefault2)) { ResetLavaWaitEstimate(); return EmptyHazard(); } float num3 = EstimateLavaWaited(risingLava, secondsWaitedToStart, isMasterClient, risingHazardKind, readyToStart); if (flag3) { return EmptyHazard(); } if (!hasValue) { return UnavailableHazard(risingHazardKind); } if (flag4) { return new HazardState(risingHazardKind, HazardPhase.Protected, clearanceMeters, isDanger: false, null); } double value = Math.Max(0.0, risingLava.initialWaitTime - num3); return new HazardState(risingHazardKind, HazardMath.CountdownPaused(risingHazardKind, readyToStart) ? HazardPhase.Paused : HazardPhase.Countdown, clearanceMeters, isDanger, value); } if (flag3) { return EmptyHazard(); } if (!hasValue) { if (!risingLava.ended) { return UnavailableHazard(risingHazardKind); } return new HazardState(risingHazardKind, HazardPhase.Stopped, double.NaN, isDanger: false, null); } if (flag4) { return new HazardState(risingHazardKind, HazardPhase.Protected, clearanceMeters, isDanger: false, null); } if (risingLava.ended) { return new HazardState(risingHazardKind, HazardPhase.Stopped, clearanceMeters, isDanger, null); } if (flag2 && val.y < ((Bounds)(ref valueOrDefault)).min.y) { return new HazardState(risingHazardKind, HazardPhase.OutOfReach, clearanceMeters, isDanger: false, null); } if ((Object)(object)risingLava.topTransform == (Object)null || !float.IsFinite(risingLava.travelTime) || risingLava.travelTime <= 0f) { return new HazardState(risingHazardKind, HazardPhase.Unavailable, clearanceMeters, isDanger, null); } float num4 = Mathf.Max(0f, risingLava.travelTime - risingLava.timeTraveled); float num5 = risingLava.topTransform.position.y - lava.position.y; float num6 = ((num4 > 0.001f) ? (num5 / num4) : 0f); return HazardMath.Moving(risingHazardKind, num2, clearanceMeters, isDanger, num6, Math.Max(0.0, num5)); } private bool IsRisingFieldForCurrentSegment(LavaRising risingField) { return IsRisingFieldForSegment(risingField, _lastSegment); } private static bool? ReadRisingReadyToStart(LavaRising risingField) { if (RisingFieldReadyToStartMethod == null) { return null; } try { return RisingFieldReadyToStartMethod.Invoke(risingField, Array.Empty<object>()) as bool?; } catch { return null; } } private static bool IsFogDisabledForCurrentOrigin(OrbFogHandler handler) { if (OrbFogOriginsField == null) { return false; } if (!TryRead<FogSphereOrigin[]>(OrbFogOriginsField, handler, out FogSphereOrigin[] value) || value == null) { return false; } int currentID = handler.currentID; if (currentID < 0 || currentID >= value.Length) { return true; } FogSphereOrigin val = value[currentID]; if (!((Object)(object)val == (Object)null)) { return val.disableFog; } return true; } private HazardState CaptureLegacyLava(Vector3 playerPosition) { //IL_0046: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) MovingLava legacyRisingLava = _legacyRisingLava; if ((Object)(object)legacyRisingLava == (Object)null || !((Behaviour)legacyRisingLava).isActiveAndEnabled) { return EmptyHazard(); } Bounds? legacyLavaBounds = GetLegacyLavaBounds(legacyRisingLava); bool hasValue = legacyLavaBounds.HasValue; if (hasValue && !IsInsideRisingFieldFootprint(legacyLavaBounds.GetValueOrDefault(), playerPosition)) { return EmptyHazard(); } double num = HazardMath.RisingClearance(playerPosition.y, playerPosition.y, ((Component)legacyRisingLava).transform.position.y, usesHeadProbe: false); double clearanceMeters = ToMeters(num); bool isDanger = num <= 0.0; if (((Component)legacyRisingLava).transform.position.y > 1150f) { if (!hasValue) { return new HazardState(HazardKind.Lava, HazardPhase.Stopped, double.NaN, isDanger: false, null); } return new HazardState(HazardKind.Lava, HazardPhase.Stopped, clearanceMeters, isDanger, null); } if (!TryRead<bool>(LegacyLavaMovingField, legacyRisingLava, out var value)) { if (!hasValue) { return UnavailableHazard(HazardKind.Lava); } return new HazardState(HazardKind.Lava, HazardPhase.Unavailable, clearanceMeters, isDanger, null); } if (!value) { if (!hasValue) { return EmptyHazard(); } return new HazardState(HazardKind.Lava, HazardPhase.WaitingForTrigger, clearanceMeters, isDanger, null); } if (!hasValue) { return UnavailableHazard(HazardKind.Lava); } return HazardMath.Moving(HazardKind.Lava, num, clearanceMeters, isDanger, legacyRisingLava.speed, Math.Max(0.0, 1150f - ((Component)legacyRisingLava).transform.position.y)); } private void PollCampfire(float outMessageSeconds) { if (Time.unscaledTime < _nextFirePollAt) { return; } _nextFirePollAt = Time.unscaledTime + 0.2f; if (Time.unscaledTime >= _nextCampfireReferenceLookupAt) { _nextCampfireReferenceLookupAt = Time.unscaledTime + 1f; try { _currentCampfire = MapHandler.CurrentCampfire; _previousCampfire = MapHandler.PreviousCampfire; } catch (Exception exception) { ReportOnce("campfire-lookup", "Could not read PEAK campfire state.", exception); } } Campfire? currentCampfire = _currentCampfire; Campfire previousCampfire = _previousCampfire; if ((Object)(object)_trackedCampfire != (Object)null && ((Behaviour)_trackedCampfire).isActiveAndEnabled && _trackedCampfire.Lit) { _trackedCampfireWasLit = true; _trackedCampfirePaused = ReadCampfirePaused(_trackedCampfire); } if ((Object)(object)_trackedCampfire != (Object)null && HazardMath.CampfireBurnedOut(_trackedCampfireWasLit, _trackedCampfire.Lit)) { _campfireOutMessageUntil = Time.unscaledTime + outMessageSeconds; } Campfire val = (_trackedCampfire = ChooseLitCampfire(currentCampfire, previousCampfire)); _trackedCampfireWasLit = (Object)(object)val != (Object)null; _trackedCampfirePaused = (Object)(object)val != (Object)null && ReadCampfirePaused(val); if ((Object)(object)val != (Object)null) { _campfireOutMessageUntil = 0f; } } private FireState CaptureFireState() { if ((Object)(object)_trackedCampfire != (Object)null && ((Behaviour)_trackedCampfire).isActiveAndEnabled && _trackedCampfire.Lit) { double value = Math.Max(0.0, _trackedCampfire.burnsFor - _trackedCampfire.beenBurningFor); return new FireState(visible: true, isOut: false, _trackedCampfirePaused, value); } if (Time.unscaledTime < _campfireOutMessageUntil) { return new FireState(visible: true, isOut: true, isPaused: false, null); } return new FireState(visible: false, isOut: false, isPaused: false, null); } private bool ReadCampfirePaused(Campfire campfire) { try { return !((Behaviour)campfire).isActiveAndEnabled || !campfire.CanBurnOut; } catch (Exception exception) { ReportOnce("campfire-pause", "Could not determine whether the campfire timer is paused.", exception); return false; } } private static Campfire? ChooseLitCampfire(Campfire? currentCampfire, Campfire? previousCampfire) { bool num = (Object)(object)currentCampfire != (Object)null && ((Behaviour)currentCampfire).isActiveAndEnabled && currentCampfire.Lit; bool flag = (Object)(object)previousCampfire != (Object)null && ((Behaviour)previousCampfire).isActiveAndEnabled && previousCampfire.Lit; if (!num) { if (!flag) { return null; } return previousCampfire; } return currentCampfire; } private static OrbFogHandler? GetOrbFogHandler() { OrbFogHandler instance = Singleton<OrbFogHandler>.Instance; if (!((Object)(object)instance != (Object)null)) { return Object.FindAnyObjectByType<OrbFogHandler>(); } return instance; } private static bool IsUsableSphereFog(OrbFogHandler? handler, FogSphere? sphere) { if ((Object)(object)handler != (Object)null && ((Behaviour)handler).isActiveAndEnabled && (Object)(object)sphere != (Object)null && ((Behaviour)sphere).isActiveAndEnabled && Ascents.fogEnabled) { return !IsFogDisabledForCurrentOrigin(handler); } return false; } private static FogSphere? ResolveSphereFog(OrbFogHandler? handler, FogSphere? current) { if ((Object)(object)handler == (Object)null || !((Behaviour)handler).isActiveAndEnabled) { return null; } if (TryRead<FogSphere>(OrbFogSphereField, handler, out FogSphere value) && IsActive((Behaviour?)(object)value)) { return value; } FogSphere componentInChildren = ((Component)handler).GetComponentInChildren<FogSphere>(true); if (IsActive((Behaviour?)(object)componentInChildren)) { return componentInChildren; } if (!IsActive((Behaviour?)(object)current)) { return null; } return current; } private Bounds? GetRisingFieldBounds(LavaRising owner) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_risingLavaDamageOwner != (Object)(object)owner || ((Object)(object)_risingLavaDamageSource == (Object)null && Time.unscaledTime >= _nextRisingDamageLookupAt)) { _nextRisingDamageLookupAt = Time.unscaledTime + 1f; _risingLavaDamageOwner = owner; _risingLavaDamageSource = FindRisingFieldLava((Component)(object)owner.lava); } if ((Object)(object)_risingLavaDamageSource != (Object)null && TryRead<Bounds>(LavaBoundsField, _risingLavaDamageSource, out var value)) { Vector3 size = ((Bounds)(ref value)).size; if (((Vector3)(ref size)).sqrMagnitude > 0f) { return value; } } return GetRendererBounds(GetRisingFieldRenderer(owner)); } private Bounds? GetLegacyLavaBounds(MovingLava owner) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_legacyLavaDamageOwner != (Object)(object)owner || ((Object)(object)_legacyLavaDamageSource == (Object)null && Time.unscaledTime >= _nextLegacyDamageLookupAt)) { _nextLegacyDamageLookupAt = Time.unscaledTime + 1f; _legacyLavaDamageOwner = owner; _legacyLavaDamageSource = FindRisingFieldLava((Component)(object)owner); } if ((Object)(object)_legacyLavaDamageSource != (Object)null && TryRead<Bounds>(LavaBoundsField, _legacyLavaDamageSource, out var value)) { Vector3 size = ((Bounds)(ref value)).size; if (((Vector3)(ref size)).sqrMagnitude > 0f) { return value; } } return GetRendererBounds(GetLegacyLavaRenderer(owner)); } private MeshRenderer? GetRisingFieldRenderer(LavaRising owner) { if ((Object)(object)_risingLavaRendererOwner != (Object)(object)owner || ((Object)(object)_risingLavaRenderer == (Object)null && Time.unscaledTime >= _nextRisingRendererLookupAt)) { _nextRisingRendererLookupAt = Time.unscaledTime + 1f; _risingLavaRendererOwner = owner; _risingLavaRenderer = FindRisingFieldRenderer((Component)(object)owner.lava); } return _risingLavaRenderer; } private MeshRenderer? GetLegacyLavaRenderer(MovingLava owner) { if ((Object)(object)_legacyLavaRendererOwner != (Object)(object)owner || ((Object)(object)_legacyLavaRenderer == (Object)null && Time.unscaledTime >= _nextLegacyRendererLookupAt)) { _nextLegacyRendererLookupAt = Time.unscaledTime + 1f; _legacyLavaRendererOwner = owner; _legacyLavaRenderer = FindRisingFieldRenderer((Component)(object)owner); } return _legacyLavaRenderer; } private static Lava? FindRisingFieldLava(Component origin) { Lava val = origin.GetComponent<Lava>(); if ((Object)(object)val == (Object)null) { val = origin.GetComponentInChildren<Lava>(true); } if ((Object)(object)val == (Object)null) { val = origin.GetComponentInParent<Lava>(); } if ((Object)(object)val == (Object)null && (Object)(object)origin.transform.parent != (Object)null) { val = ((Component)origin.transform.parent).GetComponentInChildren<Lava>(true); } return val; } private static MeshRenderer? FindRisingFieldRenderer(Component origin) { Lava val = FindRisingFieldLava(origin); if ((Object)(object)val != (Object)null) { MeshRenderer componentInChildren = ((Component)val).GetComponentInChildren<MeshRenderer>(true); if ((Object)(object)componentInChildren != (Object)null) { return componentInChildren; } } MeshRenderer val2 = origin.GetComponent<MeshRenderer>(); if ((Object)(object)val2 == (Object)null) { val2 = origin.GetComponentInChildren<MeshRenderer>(true); } if ((Object)(object)val2 == (Object)null) { val2 = origin.GetComponentInParent<MeshRenderer>(); } if ((Object)(object)val2 == (Object)null && (Object)(object)origin.transform.parent != (Object)null) { val2 = ((Component)origin.transform.parent).GetComponentInChildren<MeshRenderer>(true); } return val2; } private static bool IsInsideRisingFieldFootprint(Bounds bounds, Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (position.x <= ((Bounds)(ref bounds)).max.x && position.x >= ((Bounds)(ref bounds)).min.x && position.z <= ((Bounds)(ref bounds)).max.z) { return position.z >= ((Bounds)(ref bounds)).min.z; } return false; } private static Bounds? GetRendererBounds(MeshRenderer? renderer) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)renderer == (Object)null) { return null; } Bounds bounds = ((Renderer)renderer).bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (!(((Vector3)(ref size)).sqrMagnitude > 0f)) { return null; } return bounds; } private float EstimateLavaWaited(LavaRising owner, float observedWaited, bool isMasterClient, HazardKind kind, bool? readyToStart) { float time = Time.time; float num = (float.IsFinite(observedWaited) ? Mathf.Max(0f, observedWaited) : 0f); int num2; if (_lavaWaitInitialized && !((Object)(object)_lavaWaitOwner != (Object)(object)owner)) { num2 = ((time < _lavaWaitLastSampleAt) ? 1 : 0); if (num2 == 0) { _lavaWaitEstimate = (float)HazardMath.AdvanceCountdown(kind, readyToStart, _lavaWaitEstimate, _lavaWaitLastObserved, num, Mathf.Max(0f, time - _lavaWaitLastSampleAt), isMasterClient, owner.initialWaitTime); goto IL_0098; } } else { num2 = 1; } _lavaWaitOwner = owner; _lavaWaitEstimate = num; _lavaWaitInitialized = true; goto IL_0098; IL_0098: _lavaWaitLastObserved = num; _lavaWaitLastSampleAt = time; float initialWaitTime = owner.initialWaitTime; if (num2 != 0 && float.IsFinite(initialWaitTime) && initialWaitTime >= 0f) { _lavaWaitEstimate = Mathf.Min(_lavaWaitEstimate, initialWaitTime); } return _lavaWaitEstimate; } private void ResetLavaWaitEstimate() { _lavaWaitOwner = null; _lavaWaitEstimate = 0f; _lavaWaitLastObserved = 0f; _lavaWaitLastSampleAt = 0f; _lavaWaitInitialized = false; } private void ResetCampfireTracking() { _trackedCampfire = null; _currentCampfire = null; _previousCampfire = null; _trackedCampfireWasLit = false; _trackedCampfirePaused = false; _campfireOutMessageUntil = 0f; _nextFirePollAt = 0f; _nextCampfireReferenceLookupAt = 0f; } private static T? ResolveActive<T>(T? current, Func<T?> findReplacement) where T : Behaviour { if (!IsActive((Behaviour?)(object)current)) { return findReplacement(); } return current; } private static LavaRising? ResolveRisingField(LavaRising? current, MapHandler? mapHandler, Segment? currentSegment) { if (!currentSegment.HasValue) { return null; } LavaRising val = (((Object)(object)mapHandler != (Object)null) ? mapHandler.lavaRising : null); if ((Object)(object)val != (Object)null && IsActive((Behaviour?)(object)val) && IsRisingFieldForSegment(val, currentSegment)) { return val; } if ((Object)(object)current != (Object)null && IsActive((Behaviour?)(object)current) && IsRisingFieldForSegment(current, currentSegment)) { return current; } LavaRising[] array = Object.FindObjectsByType<LavaRising>((FindObjectsSortMode)0); foreach (LavaRising val2 in array) { if (IsActive((Behaviour?)(object)val2) && IsRisingFieldForSegment(val2, currentSegment)) { return val2; } } return null; } private static bool IsRisingFieldForSegment(LavaRising risingField, Segment? currentSegment) { //IL_0029: 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) if (!currentSegment.HasValue) { return false; } if (RisingFieldRequiredSegmentField == null) { return true; } if (TryRead<Segment>(RisingFieldRequiredSegmentField, risingField, out var value)) { return value == currentSegment.Value; } return false; } private static bool IsActive(Behaviour? behaviour) { if ((Object)(object)behaviour != (Object)null) { return behaviour.isActiveAndEnabled; } return false; } private static double ToMeters(double worldUnits) { float num = CharacterStats.unitsToMeters; if (float.IsNaN(num) || float.IsInfinity(num) || num <= 0f) { num = 1f; } return worldUnits * (double)num; } private static bool TryRead<T>(FieldInfo? field, object instance, out T? value) { if (field?.GetValue(instance) is T val) { value = val; return true; } value = default(T); return false; } private static FieldInfo? FindInstanceField(Type type, string name) { return type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } private void ReportMissingCompatibilityMembers() { ReportMissingField(FlatFogWaitingField, "Fog.waiting"); ReportMissingField(FlatFogWaitTimeField, "Fog.sinceStop"); ReportMissingField(FlatFogCurrentStopField, "Fog.currentStop"); ReportMissingField(FlatFogStopsField, "Fog.stops"); ReportMissingField(LegacyLavaMovingField, "MovingLava.timeToMove"); ReportMissingField(LavaBoundsField, "Lava.bounds"); ReportMissingField(OrbFogSphereField, "OrbFogHandler.sphere"); ReportMissingField(OrbFogOriginsField, "OrbFogHandler.origins"); ReportMissingField(RisingFieldTypeField, "LavaRising.risingFieldType"); ReportMissingField(RisingFieldRequiredSegmentField, "LavaRising.requiredSegment"); ReportMissingField(RisingFieldWaitForEventField, "LavaRising.waitForEvent"); ReportMissingMethod(RisingFieldReadyToStartMethod, "LavaRising.ReadyToStart()"); } private void ReportMissingField(FieldInfo? field, string displayName) { if (field == null) { _log.LogWarning((object)("PEAK compatibility check: '" + displayName + "' is unavailable; related HUD state may be hidden or use a compatibility fallback.")); } } private void ReportMissingMethod(MethodInfo? method, string displayName) { if (method == null) { _log.LogWarning((object)("PEAK compatibility check: '" + displayName + "' is unavailable; client-side rising countdown interpolation is disabled.")); } } private void ReportOnce(string key, string message, Exception exception) { if (_reportedErrors.Add(key)) { _log.LogWarning((object)(message + " " + exception.GetType().Name + ": " + exception.Message)); } } private static HazardState EmptyHazard() { return new HazardState(HazardKind.None, HazardPhase.None, 0.0, isDanger: false, null); } private static HazardState UnavailableHazard(HazardKind kind) { return new HazardState(kind, HazardPhase.Unavailable, double.NaN, isDanger: false, null); } private static HudSnapshot EmptySnapshot() { return new HudSnapshot(EmptyHazard(), new FireState(visible: false, isOut: false, isPaused: false, null), spectating: false); } } internal enum HudAnchor { TopLeft, TopCenter, TopRight, MiddleLeft, Center, MiddleRight, BottomLeft, BottomCenter, BottomRight } internal readonly struct HudVisualSettings { internal HudAnchor Anchor { get; } internal float OffsetX { get; } internal float OffsetY { get; } internal float Scale { get; } internal float FontSize { get; } internal float OutlineWidth { get; } internal Color NeutralColor { get; } internal Color SafeColor { get; } internal Color WarningColor { get; } internal Color DangerColor { get; } internal Color MutedColor { get; } internal Color FireColor { get; } internal static HudVisualSettings Default => new HudVisualSettings(HudAnchor.TopLeft, 18f, 18f, 1f, 20f, 0.22f, new Color(1f, 1f, 1f, 0.95f), new Color(1f, 1f, 1f, 0.95f), new Color(1f, 0.72f, 0.2f, 1f), new Color(1f, 0.28f, 0.22f, 1f), new Color(0.72f, 0.74f, 0.78f, 0.88f), new Color(1f, 0.78f, 0.3f, 1f)); internal HudVisualSettings(HudAnchor anchor, float offsetX, float offsetY, float scale, float fontSize, float outlineWidth, Color neutralColor, Color safeColor, Color warningColor, Color dangerColor, Color mutedColor, Color fireColor) { //IL_002e: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) Anchor = anchor; OffsetX = offsetX; OffsetY = offsetY; Scale = scale; FontSize = fontSize; OutlineWidth = outlineWidth; NeutralColor = neutralColor; SafeColor = safeColor; WarningColor = warningColor; DangerColor = dangerColor; MutedColor = mutedColor; FireColor = fireColor; } } internal static class HudController { private const float MinimumScale = 0.1f; private const float MinimumFontSize = 8f; private const int HorizontalPadding = 0; private const int VerticalPadding = 0; private const float RowSpacing = 1f; private const string UnderlayKeyword = "UNDERLAY_ON"; private const string InnerUnderlayKeyword = "UNDERLAY_INNER"; private static readonly int UnderlayColorId = Shader.PropertyToID("_UnderlayColor"); private static readonly int UnderlayOffsetXId = Shader.PropertyToID("_UnderlayOffsetX"); private static readonly int UnderlayOffsetYId = Shader.PropertyToID("_UnderlayOffsetY"); private static readonly int UnderlayDilateId = Shader.PropertyToID("_UnderlayDilate"); private static readonly int UnderlaySoftnessId = Shader.PropertyToID("_UnderlaySoftness"); private static Canvas? attachedCanvas; private static RectTransform? safeAreaRect; private static RectTransform? panelRect; private static VerticalLayoutGroup? verticalLayout; private static TextMeshProUGUI? primaryRow; private static TextMeshProUGUI? secondaryRow; private static TextMeshProUGUI? fireRow; private static TMP_FontAsset? sourceFont; private static Material? sourceMaterial; private static Material? hudMaterial; private static float appliedOutlineWidth = float.NaN; private static int lastScreenWidth = -1; private static int lastScreenHeight = -1; private static Rect lastSafeArea = new Rect(float.NaN, float.NaN, float.NaN, float.NaN); private static bool presentationVisible; private static bool externallyVisible; private static bool hasVisibleRow; internal static void Apply(HudPresentation presentation, HudVisualSettings settings) { presentationVisible = presentation.Visible; if (EnsureHierarchy(GetHudCanvas())) { bool flag = !string.IsNullOrEmpty(presentation.PrimaryText); bool flag2 = !string.IsNullOrEmpty(presentation.SecondaryText); bool flag3 = !string.IsNullOrEmpty(presentation.FireText); int num = (int)(0u | (UpdateSafeAreaIfNeeded() ? 1u : 0u) | (ApplyVisualSettings(settings, flag, flag2) ? 1u : 0u) | (ApplyGameTextStyle() ? 1u : 0u) | (ApplyTextEffects(settings.OutlineWidth) ? 1u : 0u) | (ApplyRow(primaryRow, presentation.PrimaryText, presentation.PrimaryTone, settings, isFireRow: false) ? 1u : 0u) | (ApplyRow(secondaryRow, presentation.SecondaryText, presentation.SecondaryTone, settings, isFireRow: false) ? 1u : 0u)) | (ApplyRow(fireRow, presentation.FireText, presentation.FireTone, settings, isFireRow: true) ? 1 : 0); hasVisibleRow = flag || flag2 || flag3; ApplyVisibility(); if (num != 0 && (Object)(object)panelRect != (Object)null) { LayoutRebuilder.MarkLayoutForRebuild(panelRect); } } } internal static void SetVisible(bool visible) { externallyVisible = visible; ApplyVisibility(); } internal static void Cleanup() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)safeAreaRect != (Object)null) { ((Component)safeAreaRect).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)safeAreaRect).gameObject); } if ((Object)(object)hudMaterial != (Object)null) { Object.Destroy((Object)(object)hudMaterial); } attachedCanvas = null; safeAreaRect = null; panelRect = null; verticalLayout = null; primaryRow = null; secondaryRow = null; fireRow = null; sourceFont = null; sourceMaterial = null; hudMaterial = null; lastScreenWidth = -1; lastScreenHeight = -1; lastSafeArea = new Rect(float.NaN, float.NaN, float.NaN, float.NaN); presentationVisible = false; externallyVisible = false; hasVisibleRow = false; } private static Canvas? GetHudCanvas() { GUIManager instance = GUIManager.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.hudCanvas == (Object)null) { return null; } return instance.hudCanvas; } private static bool EnsureHierarchy(Canvas? targetCanvas) { if ((Object)(object)targetCanvas == (Object)null) { if ((Object)(object)safeAreaRect != (Object)null && ((Component)safeAreaRect).gameObject.activeSelf) { ((Component)safeAreaRect).gameObject.SetActive(false); } attachedCanvas = null; return false; } if ((Object)(object)safeAreaRect == (Object)null || (Object)(object)panelRect == (Object)null || (Object)(object)verticalLayout == (Object)null || (Object)(object)primaryRow == (Object)null || (Object)(object)secondaryRow == (Object)null || (Object)(object)fireRow == (Object)null) { CreateHierarchy(targetCanvas); } if ((Object)(object)safeAreaRect == (Object)null) { return false; } if ((Object)(object)attachedCanvas != (Object)(object)targetCanvas || (Object)(object)((Transform)safeAreaRect).parent != (Object)(object)((Component)targetCanvas).transform) { ((Transform)safeAreaRect).SetParent(((Component)targetCanvas).transform, false); ((Transform)safeAreaRect).SetAsLastSibling(); SetLayerRecursively((Transform)(object)safeAreaRect, ((Component)targetCanvas).gameObject.layer); attachedCanvas = targetCanvas; lastScreenWidth = -1; lastScreenHeight = -1; } return true; } private static void CreateHierarchy(Canvas targetCanvas) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown if ((Object)(object)safeAreaRect != (Object)null) { ((Component)safeAreaRect).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)safeAreaRect).gameObject); } if ((Object)(object)hudMaterial != (Object)null) { Object.Destroy((Object)(object)hudMaterial); hudMaterial = null; } GameObject val = new GameObject("FogDistanceSafeArea", new Type[1] { typeof(RectTransform) }); safeAreaRect = (RectTransform)val.transform; ((Transform)safeAreaRect).SetParent(((Component)targetCanvas).transform, false); safeAreaRect.anchorMin = Vector2.zero; safeAreaRect.anchorMax = Vector2.one; safeAreaRect.offsetMin = Vector2.zero; safeAreaRect.offsetMax = Vector2.zero; ((Transform)safeAreaRect).SetAsLastSibling(); GameObject val2 = new GameObject("FogDistancePanel", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter) }); panelRect = (RectTransform)val2.transform; ((Transform)panelRect).SetParent((Transform)(object)safeAreaRect, false); panelRect.sizeDelta = Vector2.zero; verticalLayout = val2.GetComponent<VerticalLayoutGroup>(); ((LayoutGroup)verticalLayout).padding = new RectOffset(0, 0, 0, 0); ((HorizontalOrVerticalLayoutGroup)verticalLayout).spacing = 1f; ((HorizontalOrVerticalLayoutGroup)verticalLayout).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)verticalLayout).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)verticalLayout).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)verticalLayout).childForceExpandHeight = false; ContentSizeFitter component = val2.GetComponent<ContentSizeFitter>(); component.horizontalFit = (FitMode)2; component.verticalFit = (FitMode)2; primaryRow = CreateRow("PrimaryText", (Transform)(object)panelRect); secondaryRow = CreateRow("SecondaryText", (Transform)(object)panelRect); fireRow = CreateRow("FireText", (Transform)(object)panelRect); attachedCanvas = targetCanvas; SetLayerRecursively((Transform)(object)safeAreaRect, ((Component)targetCanvas).gameObject.layer); lastScreenWidth = -1; lastScreenHeight = -1; sourceFont = null; sourceMaterial = null; hasVisibleRow = false; val.SetActive(false); } private static TextMeshProUGUI CreateRow(string name, Transform parent) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val.transform.SetParent(parent, false); TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>(); ((Graphic)component).raycastTarget = false; ((TMP_Text)component).enableAutoSizing = false; ((TMP_Text)component).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)component).overflowMode = (TextOverflowModes)0; ((TMP_Text)component).fontStyle = (FontStyles)1; ((TMP_Text)component).richText = false; ((TMP_Text)component).extraPadding = true; ((TMP_Text)component).text = string.Empty; val.SetActive(false); return component; } private static bool UpdateSafeAreaIfNeeded() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)safeAreaRect == (Object)null) { return false; } int width = Screen.width; int height = Screen.height; Rect safeArea = Screen.safeArea; if (width == lastScreenWidth && height == lastScreenHeight && safeArea == lastSafeArea) { return false; } lastScreenWidth = width; lastScreenHeight = height; lastSafeArea = safeArea; if (width <= 0 || height <= 0 || ((Rect)(ref safeArea)).width <= 0f || ((Rect)(ref safeArea)).height <= 0f) { safeAreaRect.anchorMin = Vector2.zero; safeAreaRect.anchorMax = Vector2.one; } else { safeAreaRect.anchorMin = new Vector2(Mathf.Clamp01(((Rect)(ref safeArea)).xMin / (float)width), Mathf.Clamp01(((Rect)(ref safeArea)).yMin / (float)height)); safeAreaRect.anchorMax = new Vector2(Mathf.Clamp01(((Rect)(ref safeArea)).xMax / (float)width), Mathf.Clamp01(((Rect)(ref safeArea)).yMax / (float)height)); } safeAreaRect.offsetMin = Vector2.zero; safeAreaRect.offsetMax = Vector2.zero; return true; } private static bool ApplyVisualSettings(HudVisualSettings settings, bool primaryVisible, bool secondaryVisible) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)panelRect == (Object)null || (Object)(object)verticalLayout == (Object)null || (Object)(object)primaryRow == (Object)null || (Object)(object)secondaryRow == (Object)null || (Object)(object)fireRow == (Object)null) { return false; } bool flag = false; Vector2 val = ResolveAnchor(settings.Anchor); if (panelRect.anchorMin != val || panelRect.anchorMax != val || panelRect.pivot != val) { panelRect.anchorMin = val; panelRect.anchorMax = val; panelRect.pivot = val; flag = true; } Vector2 val2 = ResolveAnchoredPosition(settings); if (panelRect.anchoredPosition != val2) { panelRect.anchoredPosition = val2; } float num = SanitizePositive(settings.Scale, 1f, 0.1f); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(num, num, 1f); if (((Transform)panelRect).localScale != val3) { ((Transform)panelRect).localScale = val3; } TextAnchor val4 = ResolveLayoutAlignment(settings.Anchor); if (((LayoutGroup)verticalLayout).childAlignment != val4) { ((LayoutGroup)verticalLayout).childAlignment = val4; flag = true; } TextAlignmentOptions alignment = ResolveTextAlignment(settings.Anchor); float num2 = SanitizePositive(settings.FontSize, 20f, 8f); flag |= ApplyRowTypography(primaryRow, num2, alignment); flag |= ApplyRowTypography(secondaryRow, primaryVisible ? (num2 * 0.84f) : num2, alignment); return flag | ApplyRowTypography(fireRow, (primaryVisible || secondaryVisible) ? (num2 * 0.9f) : num2, alignment); } private static bool ApplyGameTextStyle() { if ((Object)(object)primaryRow == (Object)null || (Object)(object)secondaryRow == (Object)null || (Object)(object)fireRow == (Object)null) { return false; } TextMeshProUGUI val = FindGameTextSource(); if ((Object)(object)val == (Object)null || (Object)(object)((TMP_Text)val).font == (Object)null) { return false; } TMP_FontAsset font = ((TMP_Text)val).font; Material fontSharedMaterial = ((TMP_Text)val).fontSharedMaterial; if ((Object)(object)sourceFont == (Object)(object)font && (Object)(object)sourceMaterial == (Object)(object)fontSharedMaterial) { return false; } sourceFont = font; sourceMaterial = fontSharedMaterial; ((TMP_Text)primaryRow).font = font; ((TMP_Text)secondaryRow).font = font; ((TMP_Text)fireRow).font = font; ReplaceHudMaterial(fontSharedMaterial); return true; } private static TextMeshProUGUI? FindGameTextSource() { GUIManager instance = GUIManager.instance; if ((Object)(object)instance == (Object)null) { return null; } TextMeshProUGUI interactNameText = instance.interactNameText; if ((Object)(object)interactNameText != (Object)null && (Object)(object)((TMP_Text)interactNameText).font != (Object)null) { return interactNameText; } TextMeshProUGUI itemPromptMain = instance.itemPromptMain; if (!((Object)(object)itemPromptMain != (Object)null) || !((Object)(object)((TMP_Text)itemPromptMain).font != (Object)null)) { return null; } return itemPromptMain; } private static void ReplaceHudMaterial(Material? template) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) Material val = hudMaterial; hudMaterial = ((!((Object)(object)template != (Object)null)) ? ((Material)null) : new Material(template)); appliedOutlineWidth = float.NaN; if ((Object)(object)hudMaterial != (Object)null) { ((Object)hudMaterial).name = "FogDistance HUD Material"; } if ((Object)(object)primaryRow != (Object)null) { ((TMP_Text)primaryRow).fontSharedMaterial = hudMaterial; } if ((Object)(object)secondaryRow != (Object)null) { ((TMP_Text)secondaryRow).fontSharedMaterial = hudMaterial; } if ((Object)(object)fireRow != (Object)null) { ((TMP_Text)fireRow).fontSharedMaterial = hudMaterial; } if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } private static void ApplyOutline(float requestedWidth) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)hudMaterial == (Object)null)) { float num = Mathf.Clamp01(float.IsFinite(requestedWidth) ? requestedWidth : 0f); if (hudMaterial.HasProperty(ShaderUtilities.ID_OutlineWidth) && !Mathf.Approximately(hudMaterial.GetFloat(ShaderUtilities.ID_OutlineWidth), num)) { hudMaterial.SetFloat(ShaderUtilities.ID_OutlineWidth, num); } Color val = default(Color); ((Color)(ref val))..ctor(0f, 0f, 0f, 0.96f); if (hudMaterial.HasProperty(ShaderUtilities.ID_OutlineColor) && hudMaterial.GetColor(ShaderUtilities.ID_OutlineColor) != val) { hudMaterial.SetColor(ShaderUtilities.ID_OutlineColor, val); } } } private static bool ApplyTextEffects(float requestedOutlineWidth) { float num = Mathf.Clamp01(float.IsFinite(requestedOutlineWidth) ? requestedOutlineWidth : 0f); if ((Object)(object)hudMaterial == (Object)null || appliedOutlineWidth.Equals(num)) { return false; } ApplyOutline(num); ApplyShadow(); RefreshPadding(primaryRow); RefreshPadding(secondaryRow); RefreshPadding(fireRow); appliedOutlineWidth = num; return true; } private static void RefreshPadding(TextMeshProUGUI? row) { if ((Object)(object)row != (Object)null) { ((TMP_Text)row).UpdateMeshPadding(); ((Graphic)row).SetVerticesDirty(); } } private static void ApplyShadow() { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)hudMaterial == (Object)null) && hudMaterial.HasProperty(UnderlayColorId) && hudMaterial.HasProperty(UnderlayOffsetXId) && hudMaterial.HasProperty(UnderlayOffsetYId) && hudMaterial.HasProperty(UnderlayDilateId) && hudMaterial.HasProperty(UnderlaySoftnessId)) { if (!hudMaterial.IsKeywordEnabled("UNDERLAY_ON")) { hudMaterial.EnableKeyword("UNDERLAY_ON"); } if (hudMaterial.IsKeywordEnabled("UNDERLAY_INNER")) { hudMaterial.DisableKeyword("UNDERLAY_INNER"); } SetMaterialColor(UnderlayColorId, new Color(0f, 0f, 0f, 0.68f)); SetMaterialFloat(UnderlayOffsetXId, 0.3f); SetMaterialFloat(UnderlayOffsetYId, -0.3f); SetMaterialFloat(UnderlayDilateId, 0.06f); SetMaterialFloat(UnderlaySoftnessId, 0.22f); } } private static void SetMaterialColor(int propertyId, Color value) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hudMaterial != (Object)null && hudMaterial.GetColor(propertyId) != value) { hudMaterial.SetColor(propertyId, value); } } private static void SetMaterialFloat(int propertyId, float value) { if ((Object)(object)hudMaterial != (Object)null && !Mathf.Approximately(hudMaterial.GetFloat(propertyId), value)) { hudMaterial.SetFloat(propertyId, value); } } private static bool ApplyRowTypography(TextMeshProUGUI row, float fontSize, TextAlignmentOptions alignment) { //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_0023: Unknown result type (might be due to invalid IL or missing references) bool result = false; if (!Mathf.Approximately(((TMP_Text)row).fontSize, fontSize)) { ((TMP_Text)row).fontSize = fontSize; result = true; } if (((TMP_Text)row).alignment != alignment) { ((TMP_Text)row).alignment = alignment; result = true; } return result; } private static bool ApplyRow(TextMeshProUGUI row, string? requestedText, HudTone tone, HudVisualSettings settings, bool isFireRow) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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) string text = requestedText ?? string.Empty; bool result = false; if (!string.Equals(((TMP_Text)row).text, text, StringComparison.Ordinal)) { ((TMP_Text)row).text = text; result = true; } bool flag = text.Length > 0; if (((Component)row).gameObject.activeSelf != flag) { ((Component)row).gameObject.SetActive(flag); result = true; } Color val = ResolveToneColor(tone, settings, isFireRow); if (((Graphic)row).color != val) { ((Graphic)row).color = val; } return result; } private static Color ResolveToneColor(HudTone tone, HudVisualSettings settings, bool isFireRow) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0061: Unknown result type (might be due to invalid IL or missing references) return (Color)(tone switch { HudTone.Safe => isFireRow ? settings.FireColor : settings.SafeColor, HudTone.Warning => settings.WarningColor, HudTone.Danger => settings.DangerColor, HudTone.Muted => settings.MutedColor, _ => isFireRow ? settings.FireColor : settings.NeutralColor, }); } private static Vector2 ResolveAnchor(HudAnchor anchor) { //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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) return (Vector2)(anchor switch { HudAnchor.TopLeft => new Vector2(0f, 1f), HudAnchor.TopCenter => new Vector2(0.5f, 1f), HudAnchor.TopRight => new Vector2(1f, 1f), HudAnchor.MiddleLeft => new Vector2(0f, 0.5f), HudAnchor.Center => new Vector2(0.5f, 0.5f), HudAnchor.MiddleRight => new Vector2(1f, 0.5f), HudAnchor.BottomLeft => new Vector2(0f, 0f), HudAnchor.BottomCenter => new Vector2(0.5f, 0f), HudAnchor.BottomRight => new Vector2(1f, 0f), _ => new Vector2(0f, 1f), }); } private static Vector2 ResolveAnchoredPosition(HudVisualSettings settings) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) float num = SanitizeFinite(settings.OffsetX, 0f); float num2 = SanitizeFinite(settings.OffsetY, 0f); HudAnchor anchor = settings.Anchor; float num3 = ((anchor != HudAnchor.TopRight && anchor != HudAnchor.MiddleRight && anchor != HudAnchor.BottomRight) ? num : (0f - num)); float num4 = num3; anchor = settings.Anchor; num3 = (((uint)(anchor - 6) > 2u) ? (0f - num2) : num2); float num5 = num3; return new Vector2(num4, num5); } private static TextAnchor ResolveLayoutAlignment(HudAnchor anchor) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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) switch (anchor) { case HudAnchor.TopCenter: case HudAnchor.Center: case HudAnchor.BottomCenter: return (TextAnchor)1; case HudAnchor.TopRight: case HudAnchor.MiddleRight: case HudAnchor.BottomRight: return (TextAnchor)2; default: return (TextAnchor)0; } } private static TextAlignmentOptions ResolveTextAlignment(HudAnchor anchor) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) switch (anchor) { case HudAnchor.TopCenter: case HudAnchor.Center: case HudAnchor.BottomCenter: return (TextAlignmentOptions)258; case HudAnchor.TopRight: case HudAnchor.MiddleRight: case HudAnchor.BottomRight: return (TextAlignmentOptions)260; default: return (TextAlignmentOptions)257; } } private static float SanitizePositive(float value, float fallback, float minimum) { if (!float.IsFinite(value)) { return fallback; } return Mathf.Max(minimum, value); } private static float SanitizeFinite(float value, float fallback) { if (!float.IsFinite(value)) { return fallback; } return value; } private static void ApplyVisibility() { if (!((Object)(object)safeAreaRect == (Object)null)) { bool flag = presentationVisible && externallyVisible && hasVisibleRow && (Object)(object)attachedCanvas != (Object)null; if (((Component)safeAreaRect).gameObject.activeSelf != flag) { ((Component)safeAreaRect).gameObject.SetActive(flag); } } } private static void SetLayerRecursively(Transform root, int layer) { ((Component)root).gameObject.layer = layer; for (int i = 0; i < root.childCount; i++) { SetLayerRecursively(root.GetChild(i), layer); } } } public enum HazardKind { None, Fog, Lava, Gloom, LostSouls } public enum HazardPhase { None, WaitingForTeam, WaitingForTrigger, Countdown, Moving, Receding, Paused, Stopped, Unavailable, OutOfReach, Protected } public enum HudLanguage { English, Russian } public enum HudDistanceUnit { Meters, Feet } public enum HudTone { Neutral, Safe, Warning, Danger, Muted } public readonly struct HazardState { public HazardKind Kind { get; } public HazardPhase Phase { get; } public double ClearanceMeters { get; } public bool IsDanger { get; } public double? Seconds { get; } public static HazardState None => new HazardState(HazardKind.None, HazardPhase.None, 0.0, isDanger: false, null); public HazardState(HazardKind kind, HazardPhase phase, double clearanceMeters, bool isDanger, double? seconds) { Kind = kind; Phase = phase; ClearanceMeters = clearanceMeters; IsDanger = isDanger; Seconds = seconds; } } public readonly struct FireState { public bool Visible { get; } public bool IsOut { get; } public bool IsPaused { get; } public double? Seconds { get; } public static FireState Hidden => new FireState(visible: false, isOut: false, isPaused: false, null); public FireState(bool visible, bool isOut, bool isPaused, double? seconds) { Visible = visible; IsOut = isOut; IsPaused = isPaused; Seconds = seconds; } } public readonly struct HudSnapshot { public HazardState Hazard { get; } public FireState Fire { get; } public bool Spectating { get; } public HudSnapshot(HazardState hazard, FireState fire, bool spectating) { Hazard = hazard; Fire = fire; Spectating = spectating; } } public sealed class HudPresenterOptions { public HudLanguage Language { get; set; } public HudDistanceUnit DistanceUnit { get; set; } public double WarningDistanceMeters { get; set; } = 10.0; public double WarningEtaSeconds { get; set; } = 10.0; public double DistanceHysteresisMeters { get; set; } = 1.0; public double EtaHysteresisSeconds { get; set; } = 2.0; public bool ShowPrimaryRow { get; set; } = true; public bool ShowSecondaryRow { get; set; } = true; public bool ShowFireRow { get; set; } = true; public bool ShowSpectatingIndicator { get; set; } } public readonly struct HudPresentation { public bool Visible { get; } public string PrimaryText { get; } public string SecondaryText { get; } public string FireText { get; } public HudTone PrimaryTone { get; } public HudTone SecondaryTone { get; } public HudTone FireTone { get; } public HudPresentation(bool visible, string primaryText, string secondaryText, string fireText, HudTone primaryTone, HudTone secondaryTone, HudTone fireTone) { Visible = visible; PrimaryText = primaryText; SecondaryText = secondaryText; FireText = fireText; PrimaryTone = primaryTone; SecondaryTone = secondaryTone; FireTone = fireTone; } } public static class HudMath { public const double FeetPerMeter = 3.280839895013123; public static double UnityUnitsToMeters(double unityUnits, double metersPerUnityUnit) { if (!IsFinite(metersPerUnityUnit) || metersPerUnityUnit <= 0.0) { throw new ArgumentOutOfRangeException("metersPerUnityUnit", "The Unity-units-to-meters scale must be finite and positive."); } return unityUnits * metersPerUnityUnit; } public static double MetersToFeet(double meters) { return meters * 3.280839895013123; } public static int CeilToDisplaySeconds(double seconds) { if (double.IsNaN(seconds) || seconds <= 0.0) { return 0; } if (double.IsPositiveInfinity(seconds) || seconds >= 2147483647.0) { return int.MaxValue; } return (int)Math.Ceiling(seconds); } public static double ReconcileSyncedElapsedTimer(double currentEstimate, double previousObserved, double observed, double elapsed, bool paused, bool authoritative, double maximum, double resetTolerance = 0.25) { double num = (IsFinite(currentEstimate) ? Math.Max(0.0, currentEstimate) : 0.0); double num2 = (IsFinite(previousObserved) ? Math.Max(0.0, previousObserved) : 0.0); double num3 = (IsFinite(observed) ? Math.Max(0.0, observed) : 0.0); double num4 = (IsFinite(elapsed) ? Math.Max(0.0, elapsed) : 0.0); double num5 = (IsFinite(resetTolerance) ? Math.Max(0.0, resetTolerance) : 0.0); double num6 = ((!authoritative && !(num3 + num5 < num2)) ? Math.Max(num + (paused ? 0.0 : num4), num3) : num3); if (!IsFinite(maximum) || !(maximum >= 0.0)) { return num6; } return Math.Min(num6, maximum); } public static bool IsFinite(double value) { if (!double.IsNaN(value)) { return !double.IsInfinity(value); } return false; } } public sealed class HudPresenter { private static readonly CultureInfo EnglishCulture = CultureInfo.InvariantCulture; private static readonly CultureInfo RussianCulture = CultureInfo.GetCultureInfo("ru-RU"); private HudPresenterOptions _options; private HazardKind _previousHazardKind; private HudTone _previousDistanceTone; private HudTone _previousEtaTone; private bool _hasCachedPresentation; private bool _cachedSpectating; private (HazardKind, bool, double, HudTone) _primaryKey; private (HazardKind, HazardPhase, bool, double, int, HudTone) _secondaryKey; private (bool, bool, bool, int) _fireKey; private string _primaryText = string.Empty; private string _secondaryText = string.Empty; private string _fireText = string.Empty; private HudTone _fireTone; private HudPresentation _cachedPresentation; public HudPresenterOptions Options => CopyOptions(_options); private CultureInfo Culture { get { if (_options.Language != HudLanguage.Russian) { return EnglishCulture; } return RussianCulture; } } public HudPresenter() : this(new HudPresenterOptions()) { } public HudPresenter(HudPresenterOptions options) { if (options == null) { throw new ArgumentNullException("options"); } _options = CopyOptions(options); Reset(); } public void UpdateOptions(HudPresenterOptions options) { if (options == null) { throw new ArgumentNullException("options"); } if (!SeverityOptionsEqual(_options, options)) { ResetSeverity(); } _options = CopyOptions(options); _hasCachedPresentation = false; } public HudPresentation Present(HudSnapshot snapshot) { HazardState hazard = snapshot.Hazard; if (hazard.Kind != _previousHazardKind) { ResetSeverity(); _previousHazardKind = hazard.Kind; } HudTone hudTone = CalculateDistanceTone(hazard); HudTone hudTone2 = CalculateSecondaryTone(hazard); double num = DisplayDistance(Math.Max(0.0, hazard.IsDanger ? (0.0 - hazard.ClearanceMeters) : hazard.ClearanceMeters)); (HazardKind, bool, double, HudTone) tuple = (hazard.Kind, hazard.IsDanger, hazard.IsDanger ? 0.0 : num, hudTone); (HazardKind, HazardPhase, bool, double, int, HudTone) tuple2 = (hazard.Kind, hazard.Phase, hazard.IsDanger, hazard.IsDanger ? num : 0.0, DisplaySeconds(hazard.Seconds), hudTone2); (bool, bool, bool, int) tuple3 = (snapshot.Fire.Visible, snapshot.Fire.IsOut, snapshot.Fire.IsPaused, DisplaySeconds(snapshot.Fire.Seconds)); bool flag = !_hasCachedPresentation || !_primaryKey.Equals(tuple); bool flag2 = !_hasCachedPresentation || !_secondaryKey.Equals(tuple2); bool flag3 = !_hasCachedPresentation || !_fireKey.Equals(tuple3); if (!flag && !flag2 && !flag3 && _cachedSpectating == snapshot.Spectating) { return _cachedPresentation; } if (flag) { _primaryText = (_options.ShowPrimaryRow ? FormatPrimary(hazard, hudTone) : string.Empty); _primaryKey = tuple; } if (flag2) { _secondaryText = (_options.ShowSecondaryRow ? FormatSecondary(hazard, hudTone2) : string.Empty); _secondaryKey = tuple2; } if (flag3) { _fireText = (_options.ShowFireRow ? FormatFire(snapshot.Fire, out _fireTone) : EmptyFire(out _fireTone)); _fireKey = tuple3; } string primaryText = _primaryText; string secondaryText = _secondaryText; string fireText = _fireText; if (snapshot.Spectating && _options.ShowSpectatingIndicator) { AddSpectatingPrefix(ref primaryText, ref secondaryText, ref fireText); } bool visible = primaryText.Length > 0 || secondaryText.Length > 0 || fireText.Length > 0; _cachedPresentation = new HudPresentation(visible, primaryText, secondaryText, fireText, (primaryText.Length > 0) ? hudTone : HudTone.Neutral, (secondaryText.Length > 0) ? hudTone2 : HudTone.Neutral, (fireText.Length > 0) ? _fireTone : HudTone.Neutral); _cachedSpectating = snapshot.Spectating; _hasCachedPresentation = true; return _cachedPresentation; } public void Reset() { _hasCachedPresentation = false; _previousHazardKind = HazardKind.None; ResetSeverity(); } private void ResetSeverity() { _previousDistanceTone = HudTone.Neutral; _previousEtaTone = HudTone.Neutral; } private HudTone CalculateDistanceTone(HazardState hazard) { if (hazard.Kind == HazardKind.None) { _previousDistanceTone = HudTone.Neutral; return HudTone.Neutral; } if (hazard.IsDanger) { _previousDistanceTone = HudTone.Danger; return HudTone.Danger; } if (!HudMath.IsFinite(hazard.ClearanceMeters)) { _previousDistanceTone = HudTone.Muted; return HudTone.Muted; } if (hazard.Phase == HazardPhase.Protected) { _previousDistanceTone = HudTone.Safe; return HudTone.Safe; } double num = NonNegative(_options.WarningDistanceMeters); double num2 = num + NonNegative(_options.DistanceHysteresisMeters); bool flag = _previousDistanceTone == HudTone.Warning || _previousDistanceTone == HudTone.Danger; return _previousDistanceTone = ((!(hazard.ClearanceMeters <= num) && (!flag || !(hazard.ClearanceMeters <= num2))) ? HudTone.Safe : HudTone.Warning); } private HudTone CalculateSecondaryTone(HazardState hazard) { if (hazard.Kind == HazardKind.None) { _previousEtaTone = HudTone.Neutral; return HudTone.Neutral; } if (hazard.IsDanger) { _previousEtaTone = HudTone.Neutral; return HudTone.Danger; } if (hazard.Phase != HazardPhase.Moving) { _previousEtaTone = HudTone.Neutral; if (hazard.Phase != HazardPhase.Countdown) { return HudTone.Muted; } return HudTone.Neutral; } if (!HasUsableSeconds(hazard.Seconds)) { _previousEtaTone = HudTone.Muted; return HudTone.Muted; } double valueOrDefault = hazard.Seconds.GetValueOrDefault(); double num = NonNegative(_options.WarningEtaSeconds); double num2 = num + NonNegative(_options.EtaHysteresisSeconds); bool flag = _previousEtaTone == HudTone.Warning; return _previousEtaTone = ((!(valueOrDefault <= num) && (!flag || !(valueOrDefault <= num2))) ? HudTone.Safe : HudTone.Warning); } private string FormatPrimary(HazardState hazard, HudTone tone) { if (hazard.Kind == HazardKind.None) { return string.Empty; } string text = HazardName(hazard.Kind); if (hazard.IsDanger) { return text + ": " + Text("DANGER", "ОПАСНО"); } string text2 = text + ": " + FormatDistance(Math.Max(0.0, hazard.ClearanceMeters)); if (tone != HudTone.Warning) { return text2; } return "! " + text2; } private string FormatSecondary(HazardState hazard, HudTone tone) { if (hazard.Kind == HazardKind.None) { return string.Empty; } if (hazard.IsDanger) { double meters = Math.Max(0.0, 0.0 - hazard.ClearanceMeters); return Text("TO SAFETY", "ДО БЕЗОПАСНОСТИ") + ": " + FormatDistance(meters); } string text; switch (hazard.Phase) { case HazardPhase.WaitingForTeam: text = Text("WAITING FOR TEAM", "ОЖИДАНИЕ КОМАНДЫ"); break; case HazardPhase.WaitingForTrigger: text = Text("WAITING TO START", "ОЖИДАНИЕ СТАРТА"); break; case HazardPhase.Countdown: text = Text("START", "СТАРТ") + ": " + FormatOptionalTime(hazard.Seconds); break; case HazardPhase.Moving: text = "ETA: " + FormatOptionalTime(hazard.Seconds); break; case HazardPhase.Receding: text = Text("RECEDING", "ОТСТУПАЕТ"); break; case HazardPhase.Paused: text = Text("START", "СТАРТ") + ": " + FormatOptionalTime(hazard.Seconds) + " · " + Text("PAUSED", "ПАУЗА"); break; case HazardPhase.Stopped: text = Text("STOPPED", "НЕ ДВИЖЕТСЯ"); break; case HazardPhase.Unavailable: text = "ETA: " + Text("UNKNOWN", "НЕИЗВЕСТНО"); break; case HazardPhase.OutOfReach: text = Text("NO CONTACT", "НЕ ДОСТИГНЕТ"); break; case HazardPhase.Protected: text = Text("PROTECTED", "ПОД ЗАЩИТОЙ"); break; default: return string.Empty; } if (tone != HudTone.Warning) { return text; } return "! " + text; } private string FormatFire(FireState fire, out HudTone tone) { if (!fire.Visible) { tone = HudTone.Neutral; return string.Empty; } string text = Text("FIRE", "КОСТЁР"); if (fire.IsOut) { tone = HudTone.Danger; return text + ": " + Text("OUT", "ПОГАС"); } if (fire.IsPaused) { tone = HudTone.Muted; string text2 = Text("PAUSED", "ПАУЗА"); return text + ": " + FormatOptionalTime(fire.Seconds) + " · " + text2; } if (!HasUsableSeconds(fire.Seconds)) { tone = HudTone.Muted; return text + ": --:--"; } tone = HudTone.Safe; return text + ": " + FormatTime(fire.Seconds.GetValueOrDefault()); } private static string EmptyFire(out HudTone tone) { tone = HudTone.Neutral; return string.Empty; } private void AddSpectatingPrefix(ref string primaryText, ref string secondaryText, ref string fireText) { string text = Text("SPECTATING", "НАБЛЮДЕНИЕ") + " · "; if (primaryText.Length > 0) { primaryText = text + primaryText; } else if (secondaryText.Length > 0) { secondaryText = text + secondaryText; } else if (fireText.Length > 0) { fireText = text + fireText; } } private string HazardName(HazardKind kind) { return kind switch { HazardKind.Fog => Text("FOG", "ТУМАН"), HazardKind.Lava => Text("LAVA", "ЛАВА"), HazardKind.Gloom => Text("GLOOM", "МГЛА"), HazardKind.LostSouls => Text("LOST SOULS", "ПОТЕРЯННЫЕ ДУШИ"), _ => string.Empty, }; } private double DisplayDistance(double meters) { double value = ((_options.DistanceUnit == HudDistanceUnit.Feet) ? HudMath.MetersToFeet(meters) : meters); if (!HudMath.IsFinite(value)) { return double.NaN; } return Math.Round(value, 1, MidpointRounding.AwayFromZero); } private static int DisplaySeconds(double? seconds) { if (!HasUsableSeconds(seconds)) { return -1; } return HudMath.CeilToDisplaySeconds(seconds.GetValueOrDefault()); } private string FormatDistance(double meters) { double value = DisplayDistance(meters); if (!HudMath.IsFinite(value)) { return Text("UNKNOWN", "НЕИЗВЕСТНО"); } string text = ((_options.DistanceUnit == HudDistanceUnit.Feet) ? "ft" : Text("m", "м")); return value.ToString("0.0", Culture) + " " + text; } private string FormatOptionalTime(double? seconds) { if (!HasUsableSeconds(seconds)) { return "--:--"; } return FormatTime(seconds.GetValueOrDefault()); } private static string FormatTime(double seconds) { int num = HudMath.CeilToDisplaySeconds(seconds); int num2 = num / 60; int num3 = num % 60; return num2.ToString("00", CultureInfo.InvariantCulture) + ":" + num3.ToString("00", CultureInfo.InvariantCulture); } private string Text(string english, string russian) { if (_options.Language != HudLanguage.Russian) { return english; } return russian; } private static bool HasUsableSeconds(double? seconds) { if (seconds.HasValue && HudMath.IsFinite(seconds.Value)) { return seconds.Value >= 0.0; } return false; } private static double NonNegative(double value) { if (!HudMath.IsFinite(value)) { return 0.0; } return Math.Max(0.0, value); } private static bool SeverityOptionsEqual(HudPresenterOptions left, HudPresenterOptions right) { if (left.WarningDistanceMeters.Equals(right.WarningDistanceMeters) && left.WarningEtaSeconds.Equals(right.WarningEtaSeconds) && left.DistanceHysteresisMeters.Equals(right.DistanceHysteresisMeters)) { return left.EtaHysteresisSeconds.Equals(right.EtaHysteresisSeconds); } return false; } private static HudPresenterOptions CopyOptions(HudPresenterOptions source) { return new HudPresenterOptions { Language = source.Language, DistanceUnit = source.DistanceUnit, WarningDistanceMeters = source.WarningDistanceMeters, WarningEtaSeconds = source.WarningEtaSeconds, DistanceHysteresisMeters = source.DistanceHysteresisMeters, EtaHysteresisSeconds = source.EtaHysteresisSeconds, ShowPrimaryRow = source.ShowPrimaryRow, ShowSecondaryRow = source.ShowSecondaryRow, ShowFireRow = source.ShowFireRow, ShowSpectatingIndicator = source.ShowSpectatingIndicator }; } } [BepInPlugin("com.bronekot.peak.fogdistance", "PEAK Fog Distance", "1.5.5")] [BepInProcess("PEAK.exe")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.bronekot.peak.fogdistance"; public const string PluginName = "PEAK Fog Distance"; public const string PluginVersion = "1.5.5"; private const float MinimumUpdateRateHz = 1f; private const float MaximumUpdateRateHz = 30f; private const float DefaultUpdateRateHz = 10f; private const float InitialFailureBackoffSeconds = 0.5f; private const float MaximumFailureBackoffSeconds = 8f; private readonly HashSet<string> _reportedErrors = new HashSet<string>(StringComparer.Ordinal); private PluginConfig? _settings; private HazardMonitor? _monitor; private HudPresenter? _presenter; private HudVisualSettings _visualSettings = HudVisualSettings.Default; private int _appliedConfigRevision = -1; private float _nextSampleAt; private float _failureBackoffSeconds = 0.5f; private bool _sessionVisible = true; private bool _presentationVisible; private bool _monitoringActive; private void Awake() { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) _settings = new PluginConfig(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); _monitor = new HazardMonitor(((BaseUnityPlugin)this).Logger); _presenter = new HudPresenter(_settings.CreatePresenterOptions()); _visualSettings = _settings.CreateVisualSettings(); _appliedConfigRevision = _settings.Revision; SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.sceneUnloaded += OnSceneUnloaded; ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Press {2} to toggle the HUD.", "PEAK Fog Distance", "1.5.5", _settings.ToggleKey.Value)); } private void Update() { //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) PluginConfig settings = _settings; HazardMonitor monitor = _monitor; HudPresenter presenter = _presenter; if (settings == null || monitor == null || presenter == null) { return; } KeyboardShortcut value = settings.ToggleKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { _sessionVisible = !_sessionVisible; ((BaseUnityPlugin)this).Logger.LogInfo((object)("FogDistance HUD " + (_sessionVisible ? "shown" : "hidden") + " for this session.")); } int num; int num2; if (settings.Enabled.Value && _sessionVisible) { num = (IsGameplayReady() ? 1 : 0); if (num != 0) { num2 = (IsAllowedByGameUi(settings) ? 1 : 0); goto IL_009b; } } else { num = 0; } num2 = 0; goto IL_009b; IL_009b: bool flag = (byte)num2 != 0; if (num == 0) { if (_monitoringActive) { monitor.ResetSceneState(); presenter.Reset(); _nextSampleAt = 0f; _failureBackoffSeconds = 0.5f; } _monitoringActive = false; _presentationVisible = false; HudController.SetVisible(visible: false); return; } if (!_monitoringActive) { monitor.ResetSceneState(); presenter.Reset(); _nextSampleAt = 0f; _failureBackoffSeconds = 0.5f; _presentationVisible = false; _monitoringActive = true; } HudController.SetVisible(_presentationVisible && flag); float unscaledTime = Time.unscaledTime; if (unscaledTime >= _nextSampleAt) { float value2 = settings.UpdateRateHz.Value; float num3 = Mathf.Clamp(float.IsFinite(value2) ? value2 : 10f, 1f, 30f); _nextSampleAt = unscaledTime + 1f / num3; try { int revision = settings.Revision; if (_appliedConfigRevision != revision) { presenter.UpdateOptions(settings.CreatePresenterOptions()); _visualSettings = settings.CreateVisualSettings(); _appliedConfigRevision = revision; } HudSnapshot snapshot = monitor.Capture(settings.FireOutMessageSeconds.Value); HudPresentation presentation = presenter.Present(snapshot); HudController.Apply(presentation, _visualSettings); _presentationVisible = presentation.Visible; _failureBackoffSeconds = 0.5f; } catch (Exception ex) { ReportOnce("sample:" + ex.GetType().FullName, "Could not refresh the FogDistance HUD; it will retry with backoff.", ex); _presentationVisible = false; _nextSampleAt = unscaledTime + _failureBackoffSeconds; _failureBackoffSeconds = Mathf.Min(8f, _failureBackoffSeconds * 2f); } } HudController.SetVisible(_presentationVisible && flag); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { ResetForSceneChange(); } private void OnSceneUnloaded(Scene scene) { ResetForSceneChange(); } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; SceneManager.sceneUnloaded -= OnSceneUnloaded; _settings?.Dispose(); HudController.Cleanup(); } private void ResetForSceneChange() { _monitor?.ResetSceneState(); _presenter?.Reset(); _nextSampleAt = 0f; _failureBackoffSeconds = 0.5f; _presentationVisible = false; _monitoringActive = false; HudController.SetVisible(visible: false); } private static bo