Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CombinedMeltdownPlaylist v1.4.1
CombinedMeltdownPlaylistSync.dll
Decompiled an hour 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.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FacilityMeltdown.API; using FacilityMeltdown.MeltdownSequence.Behaviours; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using PizzaTowerEscapeMusic; using PizzaTowerEscapeMusic.Scripting; using PizzaTowerEscapeMusic.Scripting.ScriptEvents; using TMPro; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.Networking; using UnityEngine.TextCore; using UnityEngine.TextCore.LowLevel; using UnityEngine.UI; [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("CombinedMeltdownPlaylistSync")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.4.1.0")] [assembly: AssemblyInformationalVersion("1.4.1")] [assembly: AssemblyProduct("CombinedMeltdownPlaylistSync")] [assembly: AssemblyTitle("CombinedMeltdownPlaylistSync")] [assembly: AssemblyVersion("1.4.1.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 CombinedMeltdownPlaylistSync { [Serializable] internal sealed class SyncedConfigSnapshot { public float ExtraStaminaPercent; public float ExtraStaminaRegenPercent; public bool EnableHud; public float HudScale; public float HudOpacity; public string BaseColor = "#FF2020"; public string FlashColor = "#FFD21A"; public bool ShowReactorTimer; public bool ShowHundredths; public bool ShowTimerPanel; public float TimerPanelOpacity; public bool ShowDistance; public bool ShowSelectedTrack; public bool ShowTrackAuthor; public bool ShowDisc; public DistanceUnit DistanceUnits; public int DistanceDecimals; public float DiscSpinSpeed; public bool EnableFlashing; public bool UseTrackBpm; public HudBeatCadence BeatCadence; public float FixedFlashIntervalSeconds; public float FlashFadeSeconds; public float TimerTransitionSpeed; public float OutsideTimerOffsetX; public float OutsideTimerOffsetY; public float InsideTimerOffsetX; public float InsideTimerOffsetY; public float SpectatorTimerOffsetX; public float SpectatorTimerOffsetY; public float DistanceOffsetX; public float DistanceOffsetY; public float TrackOffsetX; public float TrackOffsetY; internal static SyncedConfigSnapshot CaptureLocal() { return new SyncedConfigSnapshot { ExtraStaminaPercent = Plugin.ExtraStaminaPercent.Value, ExtraStaminaRegenPercent = Plugin.ExtraStaminaRegenPercent.Value, EnableHud = HudConfig.EnableHud.Value, HudScale = HudConfig.HudScale.Value, HudOpacity = HudConfig.HudOpacity.Value, BaseColor = HudConfig.BaseColor.Value, FlashColor = HudConfig.FlashColor.Value, ShowReactorTimer = HudConfig.ShowReactorTimer.Value, ShowHundredths = HudConfig.ShowHundredths.Value, ShowTimerPanel = HudConfig.ShowTimerPanel.Value, TimerPanelOpacity = HudConfig.TimerPanelOpacity.Value, ShowDistance = HudConfig.ShowDistance.Value, ShowSelectedTrack = HudConfig.ShowSelectedTrack.Value, ShowTrackAuthor = HudConfig.ShowTrackAuthor.Value, ShowDisc = HudConfig.ShowDisc.Value, DistanceUnits = HudConfig.DistanceUnits.Value, DistanceDecimals = HudConfig.DistanceDecimals.Value, DiscSpinSpeed = HudConfig.DiscSpinSpeed.Value, EnableFlashing = HudConfig.EnableFlashing.Value, UseTrackBpm = HudConfig.UseTrackBpm.Value, BeatCadence = HudConfig.BeatCadence.Value, FixedFlashIntervalSeconds = HudConfig.FixedFlashIntervalSeconds.Value, FlashFadeSeconds = HudConfig.FlashFadeSeconds.Value, TimerTransitionSpeed = HudConfig.TimerTransitionSpeed.Value, OutsideTimerOffsetX = HudConfig.OutsideTimerOffsetX.Value, OutsideTimerOffsetY = HudConfig.OutsideTimerOffsetY.Value, InsideTimerOffsetX = HudConfig.InsideTimerOffsetX.Value, InsideTimerOffsetY = HudConfig.InsideTimerOffsetY.Value, SpectatorTimerOffsetX = HudConfig.SpectatorTimerOffsetX.Value, SpectatorTimerOffsetY = HudConfig.SpectatorTimerOffsetY.Value, DistanceOffsetX = HudConfig.DistanceOffsetX.Value, DistanceOffsetY = HudConfig.DistanceOffsetY.Value, TrackOffsetX = HudConfig.TrackOffsetX.Value, TrackOffsetY = HudConfig.TrackOffsetY.Value }; } internal void Validate() { ExtraStaminaPercent = Mathf.Clamp(ExtraStaminaPercent, 0f, 1000f); ExtraStaminaRegenPercent = Mathf.Clamp(ExtraStaminaRegenPercent, 0f, 1000f); HudScale = Mathf.Clamp(HudScale, 0.5f, 2.5f); HudOpacity = Mathf.Clamp01(HudOpacity); TimerPanelOpacity = Mathf.Clamp01(TimerPanelOpacity); DistanceDecimals = Mathf.Clamp(DistanceDecimals, 0, 2); DiscSpinSpeed = Mathf.Clamp(DiscSpinSpeed, -720f, 720f); FixedFlashIntervalSeconds = Mathf.Clamp(FixedFlashIntervalSeconds, 0.25f, 30f); FlashFadeSeconds = Mathf.Clamp(FlashFadeSeconds, 0.05f, 5f); TimerTransitionSpeed = Mathf.Clamp(TimerTransitionSpeed, 0.5f, 30f); if (!Enum.IsDefined(typeof(DistanceUnit), DistanceUnits)) { DistanceUnits = DistanceUnit.Meters; } if (!Enum.IsDefined(typeof(HudBeatCadence), BeatCadence)) { BeatCadence = HudBeatCadence.EveryFourBeats; } if (BaseColor == null) { BaseColor = "#FF2020"; } if (FlashColor == null) { FlashColor = "#FFD21A"; } } } internal static class HostConfigSynchronizer { private const float RefreshIntervalSeconds = 0.5f; private static SyncedConfigSnapshot? _local; private static SyncedConfigSnapshot? _host; private static string? _lastSentJson; private static int _lastClientCount = -1; private static float _nextRefreshTime; internal static SyncedConfigSnapshot Current { get { NetworkManager registeredNetworkManager = Plugin.RegisteredNetworkManager; if ((Object)(object)registeredNetworkManager != (Object)null && registeredNetworkManager.IsListening && !registeredNetworkManager.IsServer && _host != null) { return _host; } return _local ?? (_local = CaptureValidatedLocal()); } } internal static void Tick() { if (Time.unscaledTime < _nextRefreshTime) { return; } _nextRefreshTime = Time.unscaledTime + 0.5f; _local = CaptureValidatedLocal(); NetworkManager registeredNetworkManager = Plugin.RegisteredNetworkManager; if (!((Object)(object)registeredNetworkManager == (Object)null) && registeredNetworkManager.IsListening && registeredNetworkManager.IsServer) { string text = JsonUtility.ToJson((object)_local); int count = registeredNetworkManager.ConnectedClientsIds.Count; if (!string.Equals(text, _lastSentJson, StringComparison.Ordinal) || count != _lastClientCount) { Broadcast(text); _lastSentJson = text; _lastClientCount = count; } } } internal static void ForceBroadcast() { _local = CaptureValidatedLocal(); NetworkManager registeredNetworkManager = Plugin.RegisteredNetworkManager; if (!((Object)(object)registeredNetworkManager == (Object)null) && registeredNetworkManager.IsListening && registeredNetworkManager.IsServer) { string text = JsonUtility.ToJson((object)_local); Broadcast(text); _lastSentJson = text; _lastClientCount = registeredNetworkManager.ConnectedClientsIds.Count; } } internal static void Receive(ulong senderClientId, FastBufferReader reader) { NetworkManager registeredNetworkManager = Plugin.RegisteredNetworkManager; if ((Object)(object)registeredNetworkManager == (Object)null || registeredNetworkManager.IsServer) { return; } if (senderClientId != 0L) { Plugin.ModLog.LogWarning((object)$"Ignored configuration from non-host client {senderClientId}."); return; } try { string text = default(string); ((FastBufferReader)(ref reader)).ReadValueSafe(ref text, true); SyncedConfigSnapshot obj = JsonUtility.FromJson<SyncedConfigSnapshot>(text) ?? throw new InvalidOperationException("The host snapshot was empty."); obj.Validate(); _host = obj; Plugin.ModLog.LogInfo((object)"Applied the host's meltdown stamina and HUD configuration for this lobby."); } catch (Exception arg) { Plugin.ModLog.LogError((object)$"Could not read the host's configuration: {arg}"); } } internal static void Reset() { _local = CaptureValidatedLocal(); _host = null; _lastSentJson = null; _lastClientCount = -1; _nextRefreshTime = 0f; } private static SyncedConfigSnapshot CaptureValidatedLocal() { SyncedConfigSnapshot syncedConfigSnapshot = SyncedConfigSnapshot.CaptureLocal(); syncedConfigSnapshot.Validate(); return syncedConfigSnapshot; } private unsafe static void Broadcast(string json) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) NetworkManager registeredNetworkManager = Plugin.RegisteredNetworkManager; if ((Object)(object)registeredNetworkManager == (Object)null) { return; } try { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(4096, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe(json, true); registeredNetworkManager.CustomMessagingManager.SendNamedMessageToAll("CombinedMeltdownPlaylist.Config.v1", val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } catch (Exception arg) { Plugin.ModLog.LogError((object)$"Could not broadcast the host's configuration: {arg}"); } } } internal enum DistanceUnit { Meters, Feet, GameUnits } internal enum HudBeatCadence { EveryBeat, EveryFourBeats } internal static class HudConfig { internal static ConfigEntry<bool> EnableHud { get; private set; } internal static ConfigEntry<float> HudScale { get; private set; } internal static ConfigEntry<float> HudOpacity { get; private set; } internal static ConfigEntry<string> BaseColor { get; private set; } internal static ConfigEntry<string> FlashColor { get; private set; } internal static ConfigEntry<bool> ShowReactorTimer { get; private set; } internal static ConfigEntry<bool> ShowHundredths { get; private set; } internal static ConfigEntry<bool> ShowTimerPanel { get; private set; } internal static ConfigEntry<float> TimerPanelOpacity { get; private set; } internal static ConfigEntry<bool> ShowDistance { get; private set; } internal static ConfigEntry<bool> ShowSelectedTrack { get; private set; } internal static ConfigEntry<bool> ShowTrackAuthor { get; private set; } internal static ConfigEntry<bool> ShowDisc { get; private set; } internal static ConfigEntry<DistanceUnit> DistanceUnits { get; private set; } internal static ConfigEntry<int> DistanceDecimals { get; private set; } internal static ConfigEntry<float> DiscSpinSpeed { get; private set; } internal static ConfigEntry<bool> EnableFlashing { get; private set; } internal static ConfigEntry<bool> UseTrackBpm { get; private set; } internal static ConfigEntry<HudBeatCadence> BeatCadence { get; private set; } internal static ConfigEntry<float> FixedFlashIntervalSeconds { get; private set; } internal static ConfigEntry<float> FlashFadeSeconds { get; private set; } internal static ConfigEntry<float> TimerTransitionSpeed { get; private set; } internal static ConfigEntry<float> OutsideTimerOffsetX { get; private set; } internal static ConfigEntry<float> OutsideTimerOffsetY { get; private set; } internal static ConfigEntry<float> InsideTimerOffsetX { get; private set; } internal static ConfigEntry<float> InsideTimerOffsetY { get; private set; } internal static ConfigEntry<float> SpectatorTimerOffsetX { get; private set; } internal static ConfigEntry<float> SpectatorTimerOffsetY { get; private set; } internal static ConfigEntry<float> DistanceOffsetX { get; private set; } internal static ConfigEntry<float> DistanceOffsetY { get; private set; } internal static ConfigEntry<float> TrackOffsetX { get; private set; } internal static ConfigEntry<float> TrackOffsetY { get; private set; } internal static void Bind(ConfigFile config) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Expected O, but got Unknown //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Expected O, but got Unknown //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Expected O, but got Unknown //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Expected O, but got Unknown //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Expected O, but got Unknown //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Expected O, but got Unknown AcceptableValueRange<float> val = new AcceptableValueRange<float>(0.5f, 2.5f); AcceptableValueRange<float> val2 = new AcceptableValueRange<float>(0.1f, 1f); AcceptableValueRange<float> range = new AcceptableValueRange<float>(-2000f, 2000f); EnableHud = config.Bind<bool>("Meltdown HUD - General", "EnableHud", true, "Enable all custom meltdown HUD elements."); HudScale = config.Bind<float>("Meltdown HUD - General", "HudScale", 1f, new ConfigDescription("Global scale for every custom HUD element.", (AcceptableValueBase)(object)val, Array.Empty<object>())); HudOpacity = config.Bind<float>("Meltdown HUD - General", "HudOpacity", 1f, new ConfigDescription("Global opacity for every custom HUD element.", (AcceptableValueBase)(object)val2, Array.Empty<object>())); BaseColor = config.Bind<string>("Meltdown HUD - General", "BaseColor", "#FF2020", "Normal HUD color in HTML hex format."); FlashColor = config.Bind<string>("Meltdown HUD - General", "FlashColor", "#FFD21A", "Beat-flash HUD color in HTML hex format."); ShowReactorTimer = config.Bind<bool>("Meltdown HUD - Elements", "ShowReactorTimer", true, "Show the CRITICAL FAILURE countdown."); ShowHundredths = config.Bind<bool>("Meltdown HUD - Elements", "ShowHundredths", true, "Show small hundredths next to the large total-seconds countdown."); ShowTimerPanel = config.Bind<bool>("Meltdown HUD - Elements", "ShowTimerPanel", true, "Show the rounded translucent reactor enclosure and separator line."); TimerPanelOpacity = config.Bind<float>("Meltdown HUD - Elements", "TimerPanelOpacity", 0.32f, new ConfigDescription("Opacity of the rounded reactor panel background.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); ShowDistance = config.Bind<bool>("Meltdown HUD - Elements", "ShowDistance", true, "Show distance to the ship outside and main entrance inside."); ShowSelectedTrack = config.Bind<bool>("Meltdown HUD - Elements", "ShowSelectedTrack", true, "Show the selected track on the right side."); ShowTrackAuthor = config.Bind<bool>("Meltdown HUD - Elements", "ShowTrackAuthor", true, "Show confirmed track authors when available."); ShowDisc = config.Bind<bool>("Meltdown HUD - Elements", "ShowDisc", true, "Show the spinning transparent music disc."); DistanceUnits = config.Bind<DistanceUnit>("Meltdown HUD - Elements", "DistanceUnits", DistanceUnit.Meters, "Distance units: Meters, Feet, or GameUnits."); DistanceDecimals = config.Bind<int>("Meltdown HUD - Elements", "DistanceDecimals", 0, new ConfigDescription("Number of decimal places in distance values.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>())); DiscSpinSpeed = config.Bind<float>("Meltdown HUD - Elements", "DiscSpinSpeed", 90f, new ConfigDescription("Disc rotation speed in degrees per second. Negative values reverse it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-720f, 720f), Array.Empty<object>())); EnableFlashing = config.Bind<bool>("Meltdown HUD - Flash", "EnableFlashing", true, "Enable red-to-yellow HUD pulses."); UseTrackBpm = config.Bind<bool>("Meltdown HUD - Flash", "UseTrackBpm", true, "Use the current track BPM. If disabled, use FixedFlashIntervalSeconds."); BeatCadence = config.Bind<HudBeatCadence>("Meltdown HUD - Flash", "BeatCadence", HudBeatCadence.EveryFourBeats, "Pulse on EveryBeat or EveryFourBeats."); FixedFlashIntervalSeconds = config.Bind<float>("Meltdown HUD - Flash", "FixedFlashIntervalSeconds", 4f, new ConfigDescription("Pulse interval when BPM sync is disabled or metadata is unavailable.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 30f), Array.Empty<object>())); FlashFadeSeconds = config.Bind<float>("Meltdown HUD - Flash", "FlashFadeSeconds", 0.45f, new ConfigDescription("Seconds for yellow to fade back to red. It is shortened automatically when needed so every pulse has red resting time.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 5f), Array.Empty<object>())); TimerTransitionSpeed = config.Bind<float>("Meltdown HUD - Layout", "TimerTransitionSpeed", 8f, new ConfigDescription("How quickly the reactor panel glides between its inside, outside, ship, and spectator positions. Higher values move faster.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 30f), Array.Empty<object>())); OutsideTimerOffsetX = BindOffset(config, "OutsideTimerOffsetX", "Horizontal adjustment for the timer beside the outside clock.", range); OutsideTimerOffsetY = BindOffset(config, "OutsideTimerOffsetY", "Vertical adjustment for the timer beside the outside clock.", range); InsideTimerOffsetX = BindOffset(config, "InsideTimerOffsetX", "Horizontal adjustment for the inside top-center timer.", range); InsideTimerOffsetY = BindOffset(config, "InsideTimerOffsetY", "Vertical adjustment for the inside top-center timer.", range); SpectatorTimerOffsetX = BindOffset(config, "SpectatorTimerOffsetX", "Horizontal adjustment for the spectator bottom-left timer.", range); SpectatorTimerOffsetY = BindOffset(config, "SpectatorTimerOffsetY", "Vertical adjustment for the spectator bottom-left timer.", range); DistanceOffsetX = BindOffset(config, "DistanceOffsetX", "Horizontal adjustment for the bottom-left distance.", range); DistanceOffsetY = BindOffset(config, "DistanceOffsetY", "Vertical adjustment for the lowered bottom-left distance.", range); TrackOffsetX = BindOffset(config, "TrackOffsetX", "Horizontal adjustment for the right-center track panel.", range); TrackOffsetY = BindOffset(config, "TrackOffsetY", "Vertical adjustment for the right-center track panel.", range); } private static ConfigEntry<float> BindOffset(ConfigFile config, string key, string description, AcceptableValueRange<float> range) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown return config.Bind<float>("Meltdown HUD - Layout", key, 0f, new ConfigDescription(description, (AcceptableValueBase)(object)range, Array.Empty<object>())); } } internal static class StaminaBoostController { private static bool _wasActive; internal static bool IsActive { get { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && instance.shipHasLanded && !instance.inShipPhase) { return MeltdownAPI.MeltdownStarted; } return false; } } internal static void Tick() { bool isActive = IsActive; if (isActive != _wasActive) { _wasActive = isActive; if (isActive) { SyncedConfigSnapshot current = HostConfigSynchronizer.Current; Plugin.ModLog.LogInfo((object)("Meltdown stamina boosts enabled: " + $"+{current.ExtraStaminaPercent:0.##}% effective stamina, " + $"+{current.ExtraStaminaRegenPercent:0.##}% regeneration.")); } else { Plugin.ModLog.LogInfo((object)"Meltdown stamina boosts disabled."); } } } internal static void ForceDeactivate(string reason) { if (_wasActive) { Plugin.ModLog.LogInfo((object)("Meltdown stamina boosts disabled (" + reason + ").")); } _wasActive = false; } internal static StaminaSnapshot Capture(PlayerControllerB player) { if (!IsLocalPlayer(player) || !IsActive) { return default(StaminaSnapshot); } return new StaminaSnapshot(tracked: true, player.sprintMeter); } internal static void ApplyFrameDelta(PlayerControllerB player, StaminaSnapshot snapshot, bool includeRegeneration) { if (!snapshot.Tracked || !IsLocalPlayer(player) || !IsActive) { return; } float sprintMeter = player.sprintMeter; float num = sprintMeter - snapshot.Before; if (num < 0f) { SyncedConfigSnapshot current = HostConfigSynchronizer.Current; float num2 = 1f + current.ExtraStaminaPercent / 100f; float num3 = 0f - num; player.sprintMeter = snapshot.Before - num3 / num2; } else if (includeRegeneration && num > 0f) { SyncedConfigSnapshot current2 = HostConfigSynchronizer.Current; float num4 = num * current2.ExtraStaminaRegenPercent / 100f; float num5 = sprintMeter + num4; if (snapshot.Before > 1f || sprintMeter > 1f) { player.sprintMeter = num5; } else { player.sprintMeter = Mathf.Min(1f, num5); } } if ((Object)(object)player.sprintMeterUI != (Object)null) { player.sprintMeterUI.fillAmount = player.sprintMeter; } } private static bool IsLocalPlayer(PlayerControllerB player) { if ((Object)(object)GameNetworkManager.Instance != (Object)null) { return player == GameNetworkManager.Instance.localPlayerController; } return false; } } internal readonly struct StaminaSnapshot { internal bool Tracked { get; } internal float Before { get; } internal StaminaSnapshot(bool tracked, float before) { Tracked = tracked; Before = before; } } [HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")] internal static class PlayerStaminaLateUpdatePatch { [HarmonyPrefix] [HarmonyPriority(800)] private static void Prefix(PlayerControllerB __instance, out StaminaSnapshot __state) { __state = StaminaBoostController.Capture(__instance); } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(PlayerControllerB __instance, StaminaSnapshot __state) { StaminaBoostController.ApplyFrameDelta(__instance, __state, includeRegeneration: true); } } [HarmonyPatch(typeof(PlayerControllerB), "Jump_performed")] internal static class PlayerJumpStaminaPatch { [HarmonyPrefix] [HarmonyPriority(800)] private static void Prefix(PlayerControllerB __instance, out StaminaSnapshot __state) { __state = StaminaBoostController.Capture(__instance); } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(PlayerControllerB __instance, StaminaSnapshot __state) { StaminaBoostController.ApplyFrameDelta(__instance, __state, includeRegeneration: false); } } [HarmonyPatch(typeof(MeltdownHandler), "HandleEnemies")] internal static class FacilityMeltdownEnemyCompatibilityPatch { [HarmonyFinalizer] private static Exception? Finalizer(Exception? __exception) { if (__exception == null) { return null; } Plugin.ModLog.LogError((object)("FacilityMeltdown's optional enemy handling failed. The exception was contained so host-side meltdown initialization and forced takeoff can continue. " + $"Original error: {__exception}")); return null; } } [HarmonyPatch(typeof(MeltdownHandler), "Update")] internal static class FacilityMeltdownUpdatePatch { [HarmonyPostfix] private static void Postfix(MeltdownHandler __instance) { ForcedTakeoffFailsafe.Observe(__instance); MeltdownHudController.Observe(__instance); } } [HarmonyPatch(typeof(MeltdownHandler), "OnDisable")] internal static class FacilityMeltdownCleanupPatch { [HarmonyPrefix] private static void Prefix() { StaminaBoostController.ForceDeactivate("meltdown handler cleanup"); ForcedTakeoffFailsafe.Reset(); LazyMusicPlayer.Stop(); MeltdownHudController.ResetSession(); } } [HarmonyPatch(typeof(StartOfRound), "ShipLeave")] internal static class ShipLeaveCleanupPatch { [HarmonyPrefix] private static void Prefix() { StaminaBoostController.ForceDeactivate("ship departure"); LazyMusicPlayer.Stop(); MeltdownHudController.ResetSession(); } } [HarmonyPatch(typeof(StartOfRound), "EndOfGame")] internal static class EndOfGameCleanupPatch { [HarmonyPrefix] private static void Prefix() { StaminaBoostController.ForceDeactivate("end of round"); LazyMusicPlayer.Stop(); MeltdownHudController.ResetSession(); } } internal static class ForcedTakeoffFailsafe { private const float GraceSecondsAfterOriginalTakeoff = 7f; private const float RetryDelaySeconds = 2f; private const int MaximumAttempts = 3; private static readonly MethodInfo? ShipLeaveMethod = AccessTools.Method(typeof(StartOfRound), "ShipLeave", (Type[])null, (Type[])null); private static bool _armed; private static float _nextAttemptTime; private static int _attempts; internal static void Observe(MeltdownHandler handler) { if (!_armed && IsHost() && !(handler.TimeLeftUntilMeltdown > 3f)) { _armed = true; _attempts = 0; _nextAttemptTime = Time.realtimeSinceStartup + 7f; Plugin.ModLog.LogDebug((object)"Armed the host forced-takeoff failsafe."); } } internal static void Tick() { if (!_armed) { return; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || instance.inShipPhase || !MeltdownAPI.MeltdownStarted) { Reset(); } else { if (!IsHost() || !instance.shipHasLanded || Time.realtimeSinceStartup < _nextAttemptTime || _attempts >= 3) { return; } _attempts++; _nextAttemptTime = Time.realtimeSinceStartup + 2f; if (!(ShipLeaveMethod == null)) { try { Plugin.ModLog.LogWarning((object)("FacilityMeltdown's host departure did not complete; running takeoff " + $"failsafe attempt {_attempts}/{3}.")); instance.shipLeftAutomatically = true; instance.shipIsLeaving = true; ShipLeaveMethod.Invoke(instance, Array.Empty<object>()); return; } catch (Exception arg) { Plugin.ModLog.LogError((object)$"Forced-takeoff failsafe attempt {_attempts} failed: {arg}"); return; } } Plugin.ModLog.LogError((object)"Could not locate StartOfRound.ShipLeave for the forced-takeoff failsafe."); _attempts = 3; } } internal static void Reset() { _armed = false; _nextAttemptTime = 0f; _attempts = 0; } private static bool IsHost() { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && singleton.IsListening) { return singleton.IsHost; } return false; } } internal static class MeltdownHudController { private const float DistanceUpdateInterval = 0.1f; private static MeltdownHandler? _handler; private static HUDManager? _hudManager; private static GameObject? _root; private static RectTransform? _rootRect; private static CanvasGroup? _canvasGroup; private static Canvas? _hudCanvas; private static RectTransform? _timerRoot; private static Image? _timerPanel; private static Image? _timerHighlight; private static TextMeshProUGUI? _timerHeader; private static TextMeshProUGUI? _timerSeconds; private static TextMeshProUGUI? _timerHundredths; private static RectTransform? _distanceRoot; private static TextMeshProUGUI? _distanceText; private static RectTransform? _trackRoot; private static TextMeshProUGUI? _trackHeader; private static TextMeshProUGUI? _trackTitle; private static TextMeshProUGUI? _trackAuthor; private static RectTransform? _discRect; private static Image? _discImage; private static Image? _tonearmImage; private static Texture2D? _discTexture; private static Sprite? _discSprite; private static Texture2D? _tonearmTexture; private static Sprite? _tonearmSprite; private static Texture2D? _timerPanelTexture; private static Sprite? _timerPanelSprite; private static Texture2D? _timerHighlightTexture; private static Sprite? _timerHighlightSprite; private static TrackInfo? _currentTrack; private static double _trackStartDsp; private static double _sessionStartDsp; private static double _lastPulseDsp = double.NegativeInfinity; private static long _lastPulseIndex = long.MinValue; private static float _lastPulseInterval = -1f; private static float _lastPulseOffset = -1f; private static bool _wasActive; private static float _nextDistanceUpdate; private static bool _hasEntrancePosition; private static Vector3 _entrancePosition; private static float _discAngle; private static bool _timerPositionInitialized; private static string? _cachedBaseColorText; private static string? _cachedFlashColorText; private static Color _cachedBaseColor = new Color(1f, 0.125f, 0.125f, 1f); private static Color _cachedFlashColor = new Color(1f, 0.824f, 0.102f, 1f); internal static void Observe(MeltdownHandler handler) { _handler = handler; } internal static void OnTrackStarted(string filename) { _currentTrack = TrackMetadata.Resolve(filename); _trackStartDsp = AudioSettings.dspTime; _lastPulseDsp = double.NegativeInfinity; _lastPulseIndex = long.MinValue; _lastPulseInterval = -1f; _lastPulseOffset = -1f; UpdateTrackText(); Plugin.ModLog.LogInfo((object)("HUD track metadata: '" + _currentTrack.Title + "', " + (_currentTrack.HasBpm ? $"{_currentTrack.Bpm:0.###} BPM." : "fixed-interval pulse fallback."))); } internal static void Tick() { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) SyncedConfigSnapshot current = HostConfigSynchronizer.Current; if (!current.EnableHud || !IsMeltdownActive()) { if (_wasActive) { Hide(); } _wasActive = false; return; } if (!_wasActive) { _sessionStartDsp = AudioSettings.dspTime; _lastPulseIndex = long.MinValue; _lastPulseDsp = double.NegativeInfinity; } _wasActive = true; HUDManager instance = HUDManager.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.HUDContainer == (Object)null) { return; } EnsureCreated(instance); if (!((Object)(object)_root == (Object)null)) { if (!instance.HUDContainer.activeInHierarchy) { Hide(); return; } _root.SetActive(true); UpdateVisibilityAndLayout(current); UpdateTimer(); UpdateDistance(current); UpdateDisc(current); ApplySharedColor(CalculatePulseColor(current), current); } } internal static void ResetSession() { _handler = null; _currentTrack = null; _trackStartDsp = 0.0; _sessionStartDsp = 0.0; _lastPulseDsp = double.NegativeInfinity; _lastPulseIndex = long.MinValue; _lastPulseInterval = -1f; _lastPulseOffset = -1f; _nextDistanceUpdate = 0f; _hasEntrancePosition = false; _timerPositionInitialized = false; _wasActive = false; Hide(); UpdateTrackText(); } internal static void Destroy() { ResetSession(); if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } if ((Object)(object)_discSprite != (Object)null) { Object.Destroy((Object)(object)_discSprite); } if ((Object)(object)_discTexture != (Object)null) { Object.Destroy((Object)(object)_discTexture); } if ((Object)(object)_tonearmSprite != (Object)null) { Object.Destroy((Object)(object)_tonearmSprite); } if ((Object)(object)_tonearmTexture != (Object)null) { Object.Destroy((Object)(object)_tonearmTexture); } if ((Object)(object)_timerPanelSprite != (Object)null) { Object.Destroy((Object)(object)_timerPanelSprite); } if ((Object)(object)_timerPanelTexture != (Object)null) { Object.Destroy((Object)(object)_timerPanelTexture); } if ((Object)(object)_timerHighlightSprite != (Object)null) { Object.Destroy((Object)(object)_timerHighlightSprite); } if ((Object)(object)_timerHighlightTexture != (Object)null) { Object.Destroy((Object)(object)_timerHighlightTexture); } _root = null; _rootRect = null; _canvasGroup = null; _hudCanvas = null; _timerRoot = null; _timerPanel = null; _timerHighlight = null; _timerHeader = null; _timerSeconds = null; _timerHundredths = null; _distanceRoot = null; _distanceText = null; _trackRoot = null; _trackHeader = null; _trackTitle = null; _trackAuthor = null; _discRect = null; _discImage = null; _tonearmImage = null; _discTexture = null; _discSprite = null; _tonearmTexture = null; _tonearmSprite = null; _timerPanelTexture = null; _timerPanelSprite = null; _timerHighlightTexture = null; _timerHighlightSprite = null; _hudManager = null; VcrFontFactory.Destroy(); } private static bool IsMeltdownActive() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && instance.shipHasLanded && !instance.inShipPhase) { return MeltdownAPI.MeltdownStarted; } return false; } private static void EnsureCreated(HUDManager hudManager) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown if (!((Object)(object)_root != (Object)null) || _hudManager != hudManager) { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _hudManager = hudManager; TMP_FontAsset orCreate = VcrFontFactory.GetOrCreate(); _root = new GameObject("CombinedMeltdownPlaylist HUD", new Type[2] { typeof(RectTransform), typeof(CanvasGroup) }); Canvas componentInParent = hudManager.HUDContainer.GetComponentInParent<Canvas>(); Canvas val = (_hudCanvas = ((componentInParent != null) ? componentInParent.rootCanvas : null)); Transform val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform : hudManager.HUDContainer.transform); _root.transform.SetParent(val2, false); _root.transform.SetAsLastSibling(); _rootRect = (RectTransform)_root.transform; StretchToParent(_rootRect); _canvasGroup = _root.GetComponent<CanvasGroup>(); _canvasGroup.interactable = false; _canvasGroup.blocksRaycasts = false; BuildTimer(orCreate); BuildDistance(orCreate); BuildTrackPanel(orCreate); UpdateTrackText(); Plugin.ModLog.LogInfo((object)"Created the meltdown HUD."); } } private static void BuildTimer(TMP_FontAsset font) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00ce: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) _timerRoot = CreateRect(_rootRect, "Reactor Timer", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(202f, 94f), Vector2.zero); _timerPanel = ((Component)CreateRect(_timerRoot, "Rounded Reactor Enclosure", Vector2.zero, Vector2.zero, Vector2.zero, new Vector2(202f, 94f), Vector2.zero)).gameObject.AddComponent<Image>(); ((Graphic)_timerPanel).raycastTarget = false; _timerPanelSprite = CreateTimerPanelSprite(); _timerPanel.sprite = _timerPanelSprite; _timerHighlight = ((Component)CreateRect(_timerRoot, "Reactor Border And Separator", Vector2.zero, Vector2.zero, Vector2.zero, new Vector2(202f, 94f), Vector2.zero)).gameObject.AddComponent<Image>(); ((Graphic)_timerHighlight).raycastTarget = false; _timerHighlightSprite = CreateTimerHighlightSprite(); _timerHighlight.sprite = _timerHighlightSprite; _timerHeader = CreateText(_timerRoot, "Critical Failure Label", font, 17f, (TextAlignmentOptions)514, new Vector2(9f, 66f), new Vector2(184f, 23f)); ((TMP_Text)_timerHeader).text = "CRITICAL FAILURE"; _timerSeconds = CreateText(_timerRoot, "Reactor Seconds", font, 56f, (TextAlignmentOptions)4100, new Vector2(8f, 5f), new Vector2(132f, 58f)); ((TMP_Text)_timerSeconds).text = "150"; _timerHundredths = CreateText(_timerRoot, "Reactor Hundredths", font, 23f, (TextAlignmentOptions)1025, new Vector2(143f, 10f), new Vector2(50f, 34f)); ((TMP_Text)_timerHundredths).text = "00"; } private static void BuildDistance(TMP_FontAsset font) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) _distanceRoot = CreateRect(_rootRect, "Distance", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), new Vector2(380f, 44f), Vector2.zero); _distanceText = CreateText(_distanceRoot, "Distance Text", font, 25f, (TextAlignmentOptions)1025, Vector2.zero, new Vector2(380f, 44f)); } private static void BuildTrackPanel(TMP_FontAsset font) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) _trackRoot = CreateRect(_rootRect, "Now Playing", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(1f, 0.5f), new Vector2(382f, 94f), Vector2.zero); _discRect = CreateRect(_trackRoot, "Spinning Disc", new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(61f, 61f), new Vector2(32f, 0f)); _discImage = ((Component)_discRect).gameObject.AddComponent<Image>(); ((Graphic)_discImage).raycastTarget = false; _discImage.preserveAspect = true; _discSprite = CreateDiscSprite(); _discImage.sprite = _discSprite; _tonearmImage = ((Component)CreateRect(_trackRoot, "Record Player Tonearm", new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(61f, 61f), new Vector2(35f, 5f))).gameObject.AddComponent<Image>(); ((Graphic)_tonearmImage).raycastTarget = false; _tonearmImage.preserveAspect = true; _tonearmSprite = CreateTonearmSprite(); _tonearmImage.sprite = _tonearmSprite; _trackHeader = CreateText(_trackRoot, "Now Playing Label", font, 15f, (TextAlignmentOptions)1025, new Vector2(70f, 62f), new Vector2(305f, 23f)); ((TMP_Text)_trackHeader).text = "NOW PLAYING"; _trackTitle = CreateText(_trackRoot, "Track Title", font, 23f, (TextAlignmentOptions)4097, new Vector2(70f, 31f), new Vector2(305f, 35f)); _trackAuthor = CreateText(_trackRoot, "Track Author", font, 15f, (TextAlignmentOptions)257, new Vector2(70f, 5f), new Vector2(305f, 26f)); } private static void UpdateVisibilityAndLayout(SyncedConfigSnapshot config) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_rootRect == (Object)null) && !((Object)(object)_timerRoot == (Object)null) && !((Object)(object)_distanceRoot == (Object)null) && !((Object)(object)_trackRoot == (Object)null) && !((Object)(object)_timerHundredths == (Object)null) && !((Object)(object)_canvasGroup == (Object)null)) { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; bool flag = (Object)(object)val == (Object)null || val.isPlayerDead; bool flag2 = (Object)(object)val != (Object)null && val.isInsideFactory; bool flag3 = (Object)(object)val != (Object)null && val.isInHangarShipRoom; float hudScale = config.HudScale; Vector3 localScale = Vector3.one * hudScale; ((Transform)_timerRoot).localScale = localScale; ((Transform)_distanceRoot).localScale = localScale; ((Transform)_trackRoot).localScale = localScale; _canvasGroup.alpha = config.HudOpacity; ((Component)_timerRoot).gameObject.SetActive(config.ShowReactorTimer); ((Component)_timerHundredths).gameObject.SetActive(config.ShowHundredths); if ((Object)(object)_timerPanel != (Object)null) { ((Component)_timerPanel).gameObject.SetActive(config.ShowTimerPanel); } if ((Object)(object)_timerHighlight != (Object)null) { ((Component)_timerHighlight).gameObject.SetActive(config.ShowTimerPanel); } bool active = config.ShowDistance && (Object)(object)val != (Object)null && !flag && !flag3; ((Component)_distanceRoot).gameObject.SetActive(active); bool flag4 = config.ShowSelectedTrack && _currentTrack != null; ((Component)_trackRoot).gameObject.SetActive(flag4); if ((Object)(object)_trackAuthor != (Object)null) { ((Component)_trackAuthor).gameObject.SetActive(flag4 && config.ShowTrackAuthor && !string.IsNullOrWhiteSpace(_currentTrack?.Author)); } if ((Object)(object)_discRect != (Object)null) { ((Component)_discRect).gameObject.SetActive(flag4 && config.ShowDisc); } if ((Object)(object)_tonearmImage != (Object)null) { ((Component)_tonearmImage).gameObject.SetActive(flag4 && config.ShowDisc); } Vector2 topCenterTimerTarget = GetTopCenterTimerTarget(config, hudScale); Vector2 val2 = (flag ? (ScreenToRootLocal(new Vector2(35f, 110f)) + new Vector2(_timerRoot.sizeDelta.x * hudScale * 0.5f + config.SpectatorTimerOffsetX, _timerRoot.sizeDelta.y * hudScale * 0.5f + config.SpectatorTimerOffsetY)) : ((!(flag2 || flag3) && IsOutsideClockVisible()) ? GetOutsideTimerTarget(config, hudScale) : topCenterTimerTarget)); SetAnchoredLayout(_timerRoot, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), _timerRoot.anchoredPosition); if (!_timerPositionInitialized) { _timerRoot.anchoredPosition = topCenterTimerTarget; _timerPositionInitialized = true; } float num = 1f - Mathf.Exp((0f - config.TimerTransitionSpeed) * Time.unscaledDeltaTime); _timerRoot.anchoredPosition = Vector2.Lerp(_timerRoot.anchoredPosition, val2, num); Vector2 anchoredPosition = ScreenToRootLocal(new Vector2(35f, 22f)) + new Vector2(config.DistanceOffsetX, config.DistanceOffsetY); SetAnchoredLayout(_distanceRoot, new Vector2(0.5f, 0.5f), Vector2.zero, anchoredPosition); Vector2 anchoredPosition2 = ScreenToRootLocal(new Vector2((float)Screen.width - 22f, (float)Screen.height * 0.5f)) + new Vector2(config.TrackOffsetX, config.TrackOffsetY); SetAnchoredLayout(_trackRoot, new Vector2(0.5f, 0.5f), new Vector2(1f, 0.5f), anchoredPosition2); } } private static Vector2 GetTopCenterTimerTarget(SyncedConfigSnapshot config, float scale) { //IL_002b: 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_0040: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_timerRoot == (Object)null) { return Vector2.zero; } return ScreenToRootLocal(new Vector2((float)Screen.width * 0.5f, (float)Screen.height - 24f)) + new Vector2(config.InsideTimerOffsetX, (0f - _timerRoot.sizeDelta.y) * scale * 0.5f + config.InsideTimerOffsetY); } private static Vector2 GetOutsideTimerTarget(SyncedConfigSnapshot config, float scale) { //IL_000f: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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) if ((Object)(object)_timerRoot == (Object)null) { return GetTopCenterTimerTarget(config, scale); } HUDManager? hudManager = _hudManager; object obj; if (hudManager == null) { obj = null; } else { TextMeshProUGUI clockNumber = hudManager.clockNumber; obj = ((clockNumber != null) ? ((TMP_Text)clockNumber).rectTransform : null); } RectTransform val = (RectTransform)obj; if ((Object)(object)val == (Object)null) { return GetTopCenterTimerTarget(config, scale); } Rect rect = val.rect; float xMax = ((Rect)(ref rect)).xMax; rect = val.rect; Vector3 val2 = ((Transform)val).TransformPoint(new Vector3(xMax, ((Rect)(ref rect)).center.y, 0f)); return ScreenToRootLocal(RectTransformUtility.WorldToScreenPoint(GetHudCamera(), val2)) + new Vector2(50f + _timerRoot.sizeDelta.x * scale * 0.5f + config.OutsideTimerOffsetX, config.OutsideTimerOffsetY); } private static bool IsOutsideClockVisible() { TextMeshProUGUI val = _hudManager?.clockNumber; if ((Object)(object)val != (Object)null && ((Behaviour)val).enabled) { return ((Component)val).gameObject.activeInHierarchy; } return false; } private static Vector2 ScreenToRootLocal(Vector2 screenPosition) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) Vector2 result = default(Vector2); if ((Object)(object)_rootRect != (Object)null && RectTransformUtility.ScreenPointToLocalPointInRectangle(_rootRect, screenPosition, GetHudCamera(), ref result)) { return result; } return Vector2.zero; } private static Camera? GetHudCamera() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_hudCanvas == (Object)null || (int)_hudCanvas.renderMode == 0) { return null; } return _hudCanvas.worldCamera; } private static void UpdateTimer() { if (!((Object)(object)_timerSeconds == (Object)null) && !((Object)(object)_timerHundredths == (Object)null)) { int num = Mathf.FloorToInt((((Object)(object)_handler == (Object)null) ? 0f : Mathf.Max(0f, _handler.TimeLeftUntilMeltdown)) * 100f + 0.001f); int num2 = num / 100; int num3 = num % 100; ((TMP_Text)_timerSeconds).text = num2.ToString(CultureInfo.InvariantCulture); ((TMP_Text)_timerHundredths).text = num3.ToString("00", CultureInfo.InvariantCulture); } } private static void UpdateDistance(SyncedConfigSnapshot config) { //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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_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) if ((Object)(object)_distanceRoot == (Object)null || !((Component)_distanceRoot).gameObject.activeSelf || (Object)(object)_distanceText == (Object)null || Time.unscaledTime < _nextDistanceUpdate) { return; } _nextDistanceUpdate = Time.unscaledTime + 0.1f; PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val == (Object)null) { return; } Vector3 val2; string text; if (val.isInsideFactory) { if (!_hasEntrancePosition) { _entrancePosition = RoundManager.FindMainEntrancePosition(true, false); _hasEntrancePosition = _entrancePosition != Vector3.zero; } if (!_hasEntrancePosition) { ((TMP_Text)_distanceText).text = "ENTRANCE --"; return; } val2 = _entrancePosition; text = "ENTRANCE"; } else { Transform val3 = StartOfRound.Instance?.shipDoorNode; if ((Object)(object)val3 == (Object)null) { ((TMP_Text)_distanceText).text = "SHIP --"; return; } val2 = val3.position; text = "SHIP"; } float num = Vector3.Distance(((Component)val).transform.position, val2); string text2; switch (config.DistanceUnits) { case DistanceUnit.Feet: num *= 3.28084f; text2 = "FT"; break; case DistanceUnit.GameUnits: text2 = "U"; break; default: text2 = "M"; break; } int distanceDecimals = config.DistanceDecimals; string text3 = "F" + distanceDecimals.ToString(CultureInfo.InvariantCulture); ((TMP_Text)_distanceText).text = text + " " + num.ToString(text3, CultureInfo.InvariantCulture) + " " + text2; } private static void UpdateDisc(SyncedConfigSnapshot config) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_discRect == (Object)null) && ((Component)_discRect).gameObject.activeSelf) { _discAngle = Mathf.Repeat(_discAngle - config.DiscSpinSpeed * Time.unscaledDeltaTime, 360f); ((Transform)_discRect).localRotation = Quaternion.Euler(0f, 0f, _discAngle); } } private static Color CalculatePulseColor(SyncedConfigSnapshot config) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) Color val = ResolveConfiguredColor(config.BaseColor, ref _cachedBaseColorText, ref _cachedBaseColor, new Color(1f, 0.125f, 0.125f, 1f), "BaseColor"); Color val2 = ResolveConfiguredColor(config.FlashColor, ref _cachedFlashColorText, ref _cachedFlashColor, new Color(1f, 0.824f, 0.102f, 1f), "FlashColor"); if (!config.EnableFlashing) { return val; } float num2; float num3; double num4; if (config.UseTrackBpm && _currentTrack != null && _currentTrack.HasBpm) { int num = ((config.BeatCadence != HudBeatCadence.EveryFourBeats) ? 1 : 4); num2 = 60f / _currentTrack.Bpm * (float)num; num3 = Mathf.Max(0f, _currentTrack.BeatOffsetSeconds); num4 = _trackStartDsp; } else { num2 = Mathf.Clamp(config.FixedFlashIntervalSeconds, 0.25f, 30f); num3 = 0f; num4 = ((_trackStartDsp > 0.0) ? _trackStartDsp : _sessionStartDsp); } if (!Mathf.Approximately(num2, _lastPulseInterval) || !Mathf.Approximately(num3, _lastPulseOffset)) { _lastPulseInterval = num2; _lastPulseOffset = num3; _lastPulseIndex = long.MinValue; _lastPulseDsp = double.NegativeInfinity; } double dspTime = AudioSettings.dspTime; double num5 = dspTime - num4 - (double)num3; if (num5 >= 0.0) { long num6 = (long)Math.Floor(num5 / (double)num2); if (num6 != _lastPulseIndex) { _lastPulseIndex = num6; _lastPulseDsp = num4 + (double)num3 + (double)((float)num6 * num2); } } float num7 = Mathf.Min(config.FlashFadeSeconds, num2 * 0.75f); float num8 = (float)(dspTime - _lastPulseDsp); if (num8 < 0f || num8 >= num7) { return val; } return Color.Lerp(val2, val, Mathf.Clamp01(num8 / num7)); } private static Color ResolveConfiguredColor(string configuredValue, ref string? cachedText, ref Color cachedColor, Color fallback, string settingName) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_003b: 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) if (string.Equals(cachedText, configuredValue, StringComparison.Ordinal)) { return cachedColor; } cachedText = configuredValue; Color val = default(Color); if (ColorUtility.TryParseHtmlString(configuredValue.StartsWith("#", StringComparison.Ordinal) ? configuredValue : ("#" + configuredValue), ref val)) { cachedColor = val; return val; } cachedColor = fallback; Plugin.ModLog.LogWarning((object)("Invalid HUD " + settingName + " '" + configuredValue + "'; using the default.")); return fallback; } private static void ApplySharedColor(Color color, SyncedConfigSnapshot config) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00e8: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) ApplyTextColor(_timerHeader, color); ApplyTextColor(_timerSeconds, color); ApplyTextColor(_timerHundredths, color); ApplyTextColor(_distanceText, color); ApplyTextColor(_trackHeader, color); ApplyTextColor(_trackTitle, color); ApplyTextColor(_trackAuthor, color); if ((Object)(object)_discImage != (Object)null) { ((Graphic)_discImage).color = new Color(color.r, color.g, color.b, color.a * 0.78f); } if ((Object)(object)_tonearmImage != (Object)null) { ((Graphic)_tonearmImage).color = new Color(color.r, color.g, color.b, color.a * 0.88f); } if ((Object)(object)_timerPanel != (Object)null) { ((Graphic)_timerPanel).color = new Color(0f, 0f, 0f, config.TimerPanelOpacity); } if ((Object)(object)_timerHighlight != (Object)null) { ((Graphic)_timerHighlight).color = new Color(color.r, color.g, color.b, color.a * 0.9f); } } private static void ApplyTextColor(TextMeshProUGUI? text, Color color) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)text != (Object)null) { ((Graphic)text).color = color; } } private static void UpdateTrackText() { if (!((Object)(object)_trackTitle == (Object)null) && !((Object)(object)_trackAuthor == (Object)null)) { if (_currentTrack == null) { ((TMP_Text)_trackTitle).text = string.Empty; ((TMP_Text)_trackAuthor).text = string.Empty; } else { ((TMP_Text)_trackTitle).text = _currentTrack.Title; ((TMP_Text)_trackAuthor).text = (string.IsNullOrWhiteSpace(_currentTrack.Author) ? string.Empty : ("BY " + _currentTrack.Author)); } } } private static TextMeshProUGUI CreateText(RectTransform parent, string name, TMP_FontAsset font, float fontSize, TextAlignmentOptions alignment, Vector2 anchoredPosition, Vector2 size) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI obj = ((Component)CreateRect(parent, name, Vector2.zero, Vector2.zero, Vector2.zero, size, anchoredPosition)).gameObject.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).font = font; ((TMP_Text)obj).fontSize = fontSize; ((TMP_Text)obj).fontStyle = (FontStyles)0; ((TMP_Text)obj).alignment = alignment; ((TMP_Text)obj).enableWordWrapping = false; ((TMP_Text)obj).overflowMode = (TextOverflowModes)1; ((Graphic)obj).raycastTarget = false; ((TMP_Text)obj).outlineWidth = 0.12f; ((TMP_Text)obj).outlineColor = new Color32((byte)20, (byte)0, (byte)0, (byte)210); ((TMP_Text)obj).margin = Vector4.zero; return obj; } private static RectTransform CreateRect(RectTransform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 size, Vector2 anchoredPosition) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown RectTransform val = (RectTransform)new GameObject(name, new Type[1] { typeof(RectTransform) }).transform; ((Transform)val).SetParent((Transform)(object)parent, false); val.anchorMin = anchorMin; val.anchorMax = anchorMax; val.pivot = pivot; val.sizeDelta = size; val.anchoredPosition = anchoredPosition; return val; } private static void StretchToParent(RectTransform rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.pivot = new Vector2(0.5f, 0.5f); rect.offsetMin = Vector2.zero; rect.offsetMax = Vector2.zero; } private static void SetAnchoredLayout(RectTransform rect, Vector2 anchor, Vector2 pivot, Vector2 anchoredPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = anchor; rect.anchorMax = anchor; rect.pivot = pivot; rect.anchoredPosition = anchoredPosition; } private static Sprite CreateDiscSprite() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_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_0085: 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_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) _discTexture = new Texture2D(64, 64, (TextureFormat)4, false) { name = "Combined Meltdown Music Disc", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1, hideFlags = (HideFlags)61 }; Color[] array = (Color[])(object)new Color[4096]; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(31.5f, 31.5f); float num = 30.08f; float num2 = 7.68f; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { Vector2 val2 = new Vector2((float)j, (float)i) - val; float magnitude = ((Vector2)(ref val2)).magnitude; Color clear = Color.clear; if (magnitude <= num && magnitude >= num2) { float num3 = Mathf.SmoothStep(0f, 1f, (num - magnitude) / 1.5f); float num4 = 0.48f + 0.18f * Mathf.Sin(magnitude * 1.35f); float num5 = Mathf.Clamp01((val2.x - val2.y + 8f) / 18f) * 0.18f; ((Color)(ref clear))..ctor(1f, 1f, 1f, Mathf.Clamp01((num4 + num5) * num3)); } array[i * 64 + j] = clear; } } _discTexture.SetPixels(array); _discTexture.Apply(false, true); Sprite obj = Sprite.Create(_discTexture, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 64f); ((Object)obj).name = "Combined Meltdown Music Disc"; ((Object)obj).hideFlags = (HideFlags)61; return obj; } private static Sprite CreateTonearmSprite() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) _tonearmTexture = new Texture2D(64, 64, (TextureFormat)4, false) { name = "Combined Meltdown Record Player Tonearm", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1, hideFlags = (HideFlags)61 }; Color[] array = (Color[])(object)new Color[4096]; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(54f, 55f); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(45f, 43f); Vector2 end = default(Vector2); ((Vector2)(ref end))..ctor(39f, 37f); for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { Vector2 val3 = new Vector2((float)j, (float)i); float num = Vector2.Distance(val3, val); float num2 = DistanceToSegment(val3, val, val2); float num3 = DistanceToSegment(val3, val2, end); float num4 = 0f; if (num <= 5.5f) { num4 = ((num >= 2.4f) ? 0.95f : 0.32f); } if (num2 <= 1.8f) { num4 = Mathf.Max(num4, 0.92f); } if (num3 <= 3.1f) { num4 = Mathf.Max(num4, 1f); } array[i * 64 + j] = new Color(1f, 1f, 1f, num4); } } _tonearmTexture.SetPixels(array); _tonearmTexture.Apply(false, true); Sprite obj = Sprite.Create(_tonearmTexture, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 64f); ((Object)obj).name = "Combined Meltdown Record Player Tonearm"; ((Object)obj).hideFlags = (HideFlags)61; return obj; } private static Sprite CreateTimerPanelSprite() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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) _timerPanelTexture = new Texture2D(202, 94, (TextureFormat)4, false) { name = "Combined Meltdown Rounded Reactor Panel", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1, hideFlags = (HideFlags)61 }; Color[] array = (Color[])(object)new Color[18988]; Vector2 center = default(Vector2); ((Vector2)(ref center))..ctor(100.5f, 46.5f); Vector2 halfSize = default(Vector2); ((Vector2)(ref halfSize))..ctor(100.5f, 46.5f); for (int i = 0; i < 94; i++) { for (int j = 0; j < 202; j++) { float num = ((RoundedRectangleDistance(j, i, center, halfSize, 11f) <= -1f) ? 0.95f : 0f); array[i * 202 + j] = new Color(1f, 1f, 1f, num); } } _timerPanelTexture.SetPixels(array); _timerPanelTexture.Apply(false, true); Sprite obj = Sprite.Create(_timerPanelTexture, new Rect(0f, 0f, 202f, 94f), new Vector2(0.5f, 0.5f), 100f); ((Object)obj).name = "Combined Meltdown Rounded Reactor Panel"; ((Object)obj).hideFlags = (HideFlags)61; return obj; } private static Sprite CreateTimerHighlightSprite() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) _timerHighlightTexture = new Texture2D(202, 94, (TextureFormat)4, false) { name = "Combined Meltdown Reactor Highlight", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1, hideFlags = (HideFlags)61 }; Color[] array = (Color[])(object)new Color[18988]; Vector2 center = default(Vector2); ((Vector2)(ref center))..ctor(100.5f, 46.5f); Vector2 halfSize = default(Vector2); ((Vector2)(ref halfSize))..ctor(100.5f, 46.5f); for (int i = 0; i < 94; i++) { for (int j = 0; j < 202; j++) { float num = RoundedRectangleDistance(j, i, center, halfSize, 11f); bool num2 = num <= 0f && num >= -2f; bool flag = Mathf.Abs((float)i - 63f) <= 1f && j >= 9 && j < 193; float num3 = ((num2 || flag) ? 0.96f : 0f); array[i * 202 + j] = new Color(1f, 1f, 1f, num3); } } _timerHighlightTexture.SetPixels(array); _timerHighlightTexture.Apply(false, true); Sprite obj = Sprite.Create(_timerHighlightTexture, new Rect(0f, 0f, 202f, 94f), new Vector2(0.5f, 0.5f), 100f); ((Object)obj).name = "Combined Meltdown Reactor Highlight"; ((Object)obj).hideFlags = (HideFlags)61; return obj; } private static float RoundedRectangleDistance(float x, float y, Vector2 center, Vector2 halfSize, float cornerRadius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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) Vector2 val = new Vector2(Mathf.Abs(x - center.x), Mathf.Abs(y - center.y)) - (halfSize - Vector2.one * cornerRadius); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(Mathf.Max(val.x, 0f), Mathf.Max(val.y, 0f)); return Mathf.Min(Mathf.Max(val.x, val.y), 0f) + ((Vector2)(ref val2)).magnitude - cornerRadius; } private static float DistanceToSegment(Vector2 point, Vector2 start, Vector2 end) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Vector2 val = end - start; float sqrMagnitude = ((Vector2)(ref val)).sqrMagnitude; if (sqrMagnitude <= Mathf.Epsilon) { return Vector2.Distance(point, start); } float num = Mathf.Clamp01(Vector2.Dot(point - start, val) / sqrMagnitude); return Vector2.Distance(point, start + val * num); } private static void Hide() { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } } } [BepInPlugin("combinedmeltdownplaylist.sync", "Combined Meltdown Playlist Sync", "1.4.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("Lethal Company.exe")] public sealed class Plugin : BaseUnityPlugin { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__HandleSelectionMessage; public static HandleNamedMessageDelegate <1>__Receive; } public const string PluginGuid = "combinedmeltdownplaylist.sync"; public const string PluginName = "Combined Meltdown Playlist Sync"; public const string PluginVersion = "1.4.1"; internal const string PlaylistTag = "CombinedMeltdownPlaylist"; internal const string SelectionMessageName = "CombinedMeltdownPlaylist.Selection.v1"; internal const string ConfigMessageName = "CombinedMeltdownPlaylist.Config.v1"; private Harmony? _harmony; internal static Plugin Instance { get; private set; } internal static ManualLogSource ModLog { get; private set; } internal static NetworkManager? RegisteredNetworkManager { get; private set; } internal static ConfigEntry<float> ExtraStaminaPercent { get; private set; } internal static ConfigEntry<float> ExtraStaminaRegenPercent { get; private set; } private void Awake() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown Instance = this; ModLog = ((BaseUnityPlugin)this).Logger; AcceptableValueRange<float> val = new AcceptableValueRange<float>(0f, 1000f); ExtraStaminaPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Meltdown Stamina", "ExtraStaminaPercent", 20f, new ConfigDescription("Percentage of extra effective stamina capacity during a meltdown. For example, 20 means 20% more stamina. Applied to the final stamina drain so upgrades from other mods remain included.", (AcceptableValueBase)(object)val, Array.Empty<object>())); ExtraStaminaRegenPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Meltdown Stamina", "ExtraStaminaRegenPercent", 50f, new ConfigDescription("Percentage of extra stamina regeneration during a meltdown. For example, 50 means regeneration is 50% faster. Applied to the final regeneration produced by the game and other mods.", (AcceptableValueBase)(object)val, Array.Empty<object>())); HudConfig.Bind(((BaseUnityPlugin)this).Config); HostConfigSynchronizer.Reset(); _harmony = new Harmony("combinedmeltdownplaylist.sync"); _harmony.PatchAll(); ModLog.LogInfo((object)"Combined Meltdown Playlist Sync 1.4.1 loaded."); } private void Update() { EnsureNetworkRegistration(); HostConfigSynchronizer.Tick(); LazyMusicPlayer.Tick(); StaminaBoostController.Tick(); ForcedTakeoffFailsafe.Tick(); MeltdownHudController.Tick(); } private void OnDestroy() { StaminaBoostController.ForceDeactivate("plugin shutdown"); ForcedTakeoffFailsafe.Reset(); LazyMusicPlayer.Stop(); UnregisterMessageHandlers(); SelectionCoordinator.Reset(); HostConfigSynchronizer.Reset(); MeltdownHudController.Destroy(); Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private static void EnsureNetworkRegistration() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown NetworkManager singleton = NetworkManager.Singleton; if (singleton == RegisteredNetworkManager && ((Object)(object)singleton == (Object)null || singleton.IsListening)) { return; } UnregisterMessageHandlers(); SelectionCoordinator.Reset(); HostConfigSynchronizer.Reset(); MeltdownHudController.ResetSession(); if ((Object)(object)singleton == (Object)null || !singleton.IsListening) { return; } try { CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager; object obj = <>O.<0>__HandleSelectionMessage; if (obj == null) { HandleNamedMessageDelegate val = HandleSelectionMessage; <>O.<0>__HandleSelectionMessage = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler("CombinedMeltdownPlaylist.Selection.v1", (HandleNamedMessageDelegate)obj); CustomMessagingManager customMessagingManager2 = singleton.CustomMessagingManager; object obj2 = <>O.<1>__Receive; if (obj2 == null) { HandleNamedMessageDelegate val2 = HostConfigSynchronizer.Receive; <>O.<1>__Receive = val2; obj2 = (object)val2; } customMessagingManager2.RegisterNamedMessageHandler("CombinedMeltdownPlaylist.Config.v1", (HandleNamedMessageDelegate)obj2); RegisteredNetworkManager = singleton; HostConfigSynchronizer.ForceBroadcast(); ModLog.LogDebug((object)"Registered the synchronized playlist and host-config message handlers."); } catch (Exception arg) { ModLog.LogError((object)$"Could not register the synchronization message handlers: {arg}"); } } private static void UnregisterMessageHandlers() { if ((Object)(object)RegisteredNetworkManager == (Object)null) { return; } try { RegisteredNetworkManager.CustomMessagingManager.UnregisterNamedMessageHandler("CombinedMeltdownPlaylist.Selection.v1"); RegisteredNetworkManager.CustomMessagingManager.UnregisterNamedMessageHandler("CombinedMeltdownPlaylist.Config.v1"); } catch (Exception ex) { ModLog.LogDebug((object)("Message handlers were already unavailable: " + ex.Message)); } finally { RegisteredNetworkManager = null; } } private static void HandleSelectionMessage(ulong senderClientId, FastBufferReader reader) { NetworkManager registeredNetworkManager = RegisteredNetworkManager; if ((Object)(object)registeredNetworkManager == (Object)null || registeredNetworkManager.IsServer) { return; } if (senderClientId != 0L) { ModLog.LogWarning((object)$"Ignored a playlist selection from non-host client {senderClientId}."); return; } try { string selectedTrack = default(string); ((FastBufferReader)(ref reader)).ReadValueSafe(ref selectedTrack, true); SelectionCoordinator.ReceiveHostSelection(selectedTrack); } catch (Exception arg) { ModLog.LogError((object)$"Could not read the host's playlist selection: {arg}"); } } internal unsafe static bool BroadcastSelection(string selectedTrack) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) NetworkManager registeredNetworkManager = RegisteredNetworkManager; if ((Object)(object)registeredNetworkManager == (Object)null || !registeredNetworkManager.IsListening || !registeredNetworkManager.IsServer) { return false; } try { HostConfigSynchronizer.ForceBroadcast(); FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(512, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe(selectedTrack, true); registeredNetworkManager.CustomMessagingManager.SendNamedMessageToAll("CombinedMeltdownPlaylist.Selection.v1", val, (NetworkDelivery)3); return true; } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } catch (Exception arg) { ModLog.LogError((object)$"Could not broadcast the playlist selection: {arg}"); return false; } } } [HarmonyPatch(typeof(MusicManager), "LoadMusicClip")] internal static class MusicManagerLoadMusicClipPatch { private static bool Prefix(string musicFileName, ref Task<AudioClip?> __result) { if (!TrackMetadata.Contains(musicFileName)) { return true; } __result = Task.FromResult<AudioClip>(null); return false; } } [HarmonyPatch(typeof(MusicManager), "PlayMusic")] internal static class MusicManagerPlayMusicPatch { private static bool Prefix(MusicManager __instance, Script script, ScriptEvent_PlayMusic musicEvent) { if (!string.Equals(musicEvent.tag, "CombinedMeltdownPlaylist", StringComparison.Ordinal)) { return true; } SelectionCoordinator.Intercept(__instance, script, musicEvent); return false; } } [HarmonyPatch(typeof(MusicManager), "StopMusic")] internal static class MusicManagerStopMusicPatch { private static void Postfix(string? targetTag = null) { if (targetTag == null || string.Equals(targetTag, "CombinedMeltdownPlaylist", StringComparison.Ordinal)) { LazyMusicPlayer.Stop(); } } } [HarmonyPatch(typeof(MusicManager), "FadeStopMusic")] internal static class MusicManagerFadeStopMusicPatch { private static void Postfix(string? targetTag = null) { if (targetTag == null || string.Equals(targetTag, "CombinedMeltdownPlaylist", StringComparison.Ordinal)) { LazyMusicPlayer.Stop(); } } } internal static class SelectionCoordinator { private static MusicManager? _waitingManager; private static Script? _waitingScript; private static ScriptEvent_PlayMusic? _waitingEvent; private static string? _pendingSelection; internal static void Intercept(MusicManager manager, Script script, ScriptEvent_PlayMusic musicEvent) { string[] musicNames = musicEvent.musicNames; if (musicNames == null || musicNames.Length == 0) { Plugin.ModLog.LogError((object)"The combined meltdown playlist has no tracks."); return; } _waitingManager = manager; _waitingScript = script; _waitingEvent = musicEvent; NetworkManager registeredNetworkManager = Plugin.RegisteredNetworkManager; if ((Object)(object)registeredNetworkManager == (Object)null || !registeredNetworkManager.IsListening) { string selectedTrack = musicNames[Random.Range(0, musicNames.Length)]; Plugin.ModLog.LogWarning((object)"Networking was not ready; selecting the meltdown track locally."); StartSelectedTrack(manager, script, musicEvent, selectedTrack); Reset(); } else if (registeredNetworkManager.IsServer) { string text = musicNames[Random.Range(0, musicNames.Length)]; if (!Plugin.BroadcastSelection(text)) { Plugin.ModLog.LogWarning((object)"The host selection could not be broadcast; playing it locally."); } Plugin.ModLog.LogInfo((object)("Host selected meltdown track: " + text)); StartSelectedTrack(manager, script, musicEvent, text); Reset(); } else if (!registeredNetworkManager.IsClient) { Reset(); } else if (_pendingSelection == null) { Plugin.ModLog.LogDebug((object)"Waiting for the host's meltdown track selection."); } else { string pendingSelection = _pendingSelection; _pendingSelection = null; PlayReceivedSelection(manager, script, musicEvent, pendingSelection); } } internal static void ReceiveHostSelection(string selectedTrack) { if (string.IsNullOrWhiteSpace(selectedTrack)) { Plugin.ModLog.LogWarning((object)"Ignored an empty playlist selection from the host."); } else if ((Object)(object)_waitingManager == (Object)null || _waitingScript == null || _waitingEvent == null) { _pendingSelection = selectedTrack; Plugin.ModLog.LogDebug((object)("Stored the host's early playlist selection: " + selectedTrack)); } else { PlayReceivedSelection(_waitingManager, _waitingScript, _waitingEvent, selectedTrack); } } internal static void Reset() { _waitingManager = null; _waitingScript = null; _waitingEvent = null; _pendingSelection = null; } private static void PlayReceivedSelection(MusicManager manager, Script script, ScriptEvent_PlayMusic musicEvent, string selectedTrack) { if (!ContainsChoice(musicEvent.musicNames, selectedTrack)) { Plugin.ModLog.LogError((object)("The host selected '" + selectedTrack + "', but it is not in this client's playlist. All players must install the same package version.")); Reset(); } else { Plugin.ModLog.LogInfo((object)("Streaming host-selected meltdown track: " + selectedTrack)); StartSelectedTrack(manager, script, musicEvent, selectedTrack); Reset(); } } private static void StartSelectedTrack(MusicManager manager, Script script, ScriptEvent_PlayMusic musicEvent, string selectedTrack) { //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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected I4, but got Unknown OverlapHandling overlapHandling = musicEvent.overlapHandling; switch (overlapHandling - 2) { case 0: manager.StopMusic((string)null); break; case 1: manager.StopMusic(musicEvent.tag); break; case 2: manager.FadeStopMusic((string)null); break; case 3: manager.FadeStopMusic(musicEvent.tag); break; } LazyMusicPlayer.Play(script, musicEvent, selectedTrack); } private static bool ContainsChoice(string[] choices, string selectedTrack) { for (int i = 0; i < choices.Length; i++) { if (string.Equals(choices[i], selectedTrack, StringComparison.Ordinal)) { return true; } } return false; } } internal static class LazyMusicPlayer { private static readonly FieldInfo? MasterVolumeField = AccessTools.Field(typeof(Configuration), "volumeMaster"); private static Coroutine? _loadCoroutine; private static AudioSource? _audioSource; private static AudioClip? _audioClip; private static float _scriptVolume = 1f; private static bool _silenceGameMusic; private static int _playGeneration; internal static void Play(Script script, ScriptEvent_PlayMusic musicEvent, string filename) { Stop(); _playGeneration++; int playGeneration = _playGeneration; _scriptVolume = script.TryGetVolumeGroupOrDefault(musicEvent.tag).GetVolume(script); _silenceGameMusic = musicEvent.silenceGameMusic; _loadCoroutine = ((MonoBehaviour)Plugin.Instance).StartCoroutine(LoadAndPlay(filename, musicEvent, playGeneration)); } internal static void Tick() { if ((Object)(object)_audioSource == (Object)null || !_audioSource.isPlaying) { return; } _audioSource.volume = _scriptVolume * GetMasterVolume(); if (_silenceGameMusic) { if ((Object)(object)SoundManager.Instance != (Object)null && SoundManager.Instance.playingOutsideMusic) { SoundManager.Instance.playingOutsideMusic = false; } if ((Object)(object)TimeOfDay.Instance != (Object)null && (Object)(object)TimeOfDay.Instance.TimeOfDayMusic != (Object)null && TimeOfDay.Instance.TimeOfDayMusic.isPlaying) { TimeOfDay.Instance.TimeOfDayMusic.Stop(); } } } internal static void Stop() { _playGeneration++; if (_loadCoroutine != null && (Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StopCoroutine(_loadCoroutine); _loadCoroutine = null; } if ((Object)(object)_audioSource != (Object)null) { _audioSource.Stop(); Object.Destroy((Object)(object)_audioSource); _audioSource = null; } if ((Object)(object)_audioClip != (Object)null) { _audioClip.UnloadAudioData(); Object.Destroy((Object)(object)_audioClip); _audioClip = null; } _silenceGameMusic = false; } private static IEnumerator LoadAndPlay(string filename, ScriptEvent_PlayMusic musicEvent, int generation) { string text = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location) ?? Paths.PluginPath, "BGN-PizzaTowerEscapeMusic", "Music", filename); if (!File.Exists(text)) { Plugin.ModLog.LogError((object)("Cannot stream meltdown music because the file is missing: " + text)); yield break; } string absoluteUri = new Uri(text).AbsoluteUri; UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(absoluteUri, (AudioType)14); try { DownloadHandler downloadHandler = request.downloadHandler; DownloadHandlerAudioClip val = (DownloadHandlerAudioClip)(object)((downloadHandler is DownloadHandlerAudioClip) ? downloadHandler : null); if (val != null) { val.streamAudio = true; } request.SendWebRequest();