Decompiled source of Summit to Shore v1.0.0
tony4twenty-Summit to Shore.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Peak; using Photon.Pun; using UnityEngine; using UnityEngine.SceneManagement; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyTitle("Summit to Shore")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Summit to Shore")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f56ddae7-f2fc-44ba-8cd8-3e9f356dca3f")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace SummitToShore { [BepInPlugin("tony4twentys.Summit_to_Shore", "Summit to Shore", "1.0.0")] [BepInProcess("PEAK.exe")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "tony4twentys.Summit_to_Shore"; public const string PluginName = "Summit to Shore"; public const string PluginVersion = "1.0.0"; private Harmony _harmony; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static ConfigEntry<int> CrashTakeChance { get; private set; } private void Awake() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; CrashTakeChance = ((BaseUnityPlugin)this).Config.Bind<int>("End Cutscene", "CrashTakeChance", 15, new ConfigDescription("Percent chance the rescue heli explodes on the fly-away (0 = always steer 45° out, 100 = always crash).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); SceneManager.sceneLoaded += OnSceneLoaded; _harmony = new Harmony("tony4twentys.Summit_to_Shore"); _harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Summit to Shore v1.0.0 loaded."); } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private static void OnSceneLoaded(Scene scene, LoadSceneMode mode) { ReverseRun.ResetForScene(((Scene)(ref scene)).name); } } internal static class ReverseRun { private struct PlaneNodeDump { public string RelPath; public bool Active; public Vector3 LocalPos; public Quaternion LocalRot; public Vector3 LocalScale; } private const string CrashedPlaneName = "crashed plane"; private const string EmbeddedPlaneDumpName = "SummitToShore.PlaneDump.txt"; private const string EmbeddedPlayerDumpName = "SummitToShore.PlayerDump.txt"; private static readonly Quaternion DumpedPlaneRot = new Quaternion(-0.11304f, -0.33602f, 0.03631f, 0.93434f); private static readonly Vector3 CitadelFlagStanding = new Vector3(6.04f, 1233.954f, 2242.54f); private static readonly Vector3 KilnFlagStanding = new Vector3(19.34f, 1233.954f, 2242.54f); private static readonly Vector3 DumpedPlayerCenter = new Vector3(9.19f, 1221.62f, 2230.23f); private static readonly Vector3 BingBongLocalPos = new Vector3(-13.96797f, -6.62793f, -11.88213f); private static readonly Quaternion BingBongLocalRot = new Quaternion(0.37629f, -0.7051f, 0.42452f, 0.42546f); private static readonly string[] PeakPlatformNames = new string[2] { "Peak_Kiln Variant", "Peak" }; private static readonly List<Segment> ReversedOrder = new List<Segment>(8); private static readonly HashSet<int> NonProgressCampfires = new HashSet<int>(); private static bool _scanned; private static bool _layoutApplied; private static bool _started; private static bool _starting; private const float CrashSiteRadius = 50f; private static bool _openedShore; private static int _unlocksDone; private static bool _won; private static bool _heliSummoned; private static bool _endgameMoved; private static bool _flareBoxMoved; private static bool _playedPeakTitle; private static bool _playedShoreTitle; private static bool _waiting; private static Vector3 _shoreAnchor; private static bool _hasShoreAnchor; private static bool _hasShoreStinger; private static Vector3 _shoreStinger; private static bool _campfireTransition; private static List<Vector3> _spawnDeck; private static List<Vector3> _spawnPool; private static Transform _spawnedBingBong; private const float MaxBingBongFromPlane = 40f; internal static bool HasWon => _won; internal static bool IsActive { get { if (_scanned) { return ReversedOrder.Count > 0; } return false; } } internal static bool IsRunning { get { if (IsActive) { return _started; } return false; } } internal static bool IsStarting => _starting; internal static void ResetForScene(string sceneName) { ReversedOrder.Clear(); NonProgressCampfires.Clear(); _campfireTransition = false; _scanned = false; _layoutApplied = false; _started = false; _starting = false; _openedShore = false; _unlocksDone = 0; _won = false; _heliSummoned = false; _endgameMoved = false; _flareBoxMoved = false; _playedPeakTitle = false; _playedShoreTitle = false; _waiting = false; _hasShoreAnchor = false; _hasShoreStinger = false; _spawnDeck = null; _spawnPool = null; _spawnedBingBong = null; if (!string.IsNullOrEmpty(sceneName) && sceneName.StartsWith("Level_", StringComparison.OrdinalIgnoreCase) && (Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(WaitForGenerationThenApply()); } } internal static IEnumerator WaitForGenerationThenApply() { if (!_waiting) { _waiting = true; float elapsed = 0f; while (elapsed < 90f && !_scanned && !MapHandler.ExistsAndInitialized) { elapsed += Time.unscaledDeltaTime; yield return null; } yield return null; ScanIfNeeded(); ApplyStartLayout(); _waiting = false; } } internal static void ScanIfNeeded() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Invalid comparison between Unknown and I4 //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Invalid comparison between Unknown and I4 //IL_0112: 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_0092: 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) if (_scanned || !MapHandler.Exists) { return; } MapHandler instance = Singleton<MapHandler>.Instance; MapSegment[] segments = instance.segments; if (segments == null || segments.Length == 0) { return; } ReversedOrder.Clear(); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < segments.Length; i++) { MapSegment val = segments[i]; if (val == null || (Object)(object)val.segmentParent == (Object)null) { continue; } Segment val2 = (Segment)(byte)i; if ((int)val2 != 6 && (int)val2 != 5 && (int)val.biome != 17) { ReversedOrder.Add(val2); if (stringBuilder.Length > 0) { stringBuilder.Append(" -> "); } stringBuilder.Append(val2).Append(" (").Append(val.biome) .Append(')'); } } if (ReversedOrder.Count == 0) { return; } ReversedOrder.Reverse(); _scanned = true; StringBuilder stringBuilder2 = new StringBuilder(); for (int j = 0; j < ReversedOrder.Count; j++) { if (j > 0) { stringBuilder2.Append(" -> "); } stringBuilder2.Append(ReversedOrder[j]); } Plugin.Log.LogInfo((object)$"Scanned climb: {stringBuilder}"); Plugin.Log.LogInfo((object)$"Reversed run: {stringBuilder2}"); LogClimbSlots(instance); } internal static void ApplyStartLayout() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (!MapHandler.Exists) { return; } try { ScanIfNeeded(); if (IsActive) { CaptureShoreAnchor(); if (!_layoutApplied) { MoveFlareBoxToShore(); _layoutApplied = true; Plugin.Log.LogInfo((object)$"Start layout applied. Shore flare drop {_shoreAnchor}. Plane moves after Citadel/Peak load."); } } } catch (Exception ex) { Plugin.Log.LogError((object)("ApplyStartLayout failed: " + ex.GetType().Name + ": " + ex.Message)); } } internal static void TryStartFromPeak(bool timerActive) { if (!_started && !_starting && !_won && timerActive && GameHandler.IsOnIsland && MapHandler.ExistsAndInitialized && !Quicksave.ShouldUseSaveData) { ScanIfNeeded(); ApplyStartLayout(); if (IsActive && !((Object)(object)Plugin.Instance == (Object)null)) { _starting = true; ((MonoBehaviour)Plugin.Instance).StartCoroutine(StartFromPeakRoutine()); } } } private static IEnumerator StartFromPeakRoutine() { while ((Object)(object)Character.localCharacter == (Object)null) { yield return null; } yield return (object)new WaitForSeconds(2.5f); if (_won) { _starting = false; yield break; } if (_started && (int)GetCurrentSegment() != 0) { _starting = false; yield break; } Segment top = GetTopClimbSegment(); Plugin.Log.LogInfo((object)$"Starting reverse run: JumpToSegment({top}), then warp to Peak."); SuppressEndgameObjects(); if (PhotonNetwork.IsMasterClient) { try { MapHandler.JumpToSegment(top); } catch (Exception ex) { Plugin.Log.LogError((object)$"JumpToSegment({top}) failed: {ex.GetType().Name}: {ex.Message}"); _starting = false; yield break; } } float timeoutAt = Time.time + 10f; while (Time.time < timeoutAt && GetCurrentSegment() != top) { yield return (object)new WaitForSeconds(0.1f); } if (GetCurrentSegment() != top) { Plugin.Log.LogError((object)$"Timed out waiting for {top}. Staying on Shore; reverse start aborted."); _starting = false; yield break; } Plugin.Log.LogInfo((object)$"{top} is loaded. Waiting for Kiln/Citadel warp to finish, then enabling the Peak (flag) platform."); yield return (object)new WaitForSeconds(1.5f); EnablePeakPlatform(); SuppressEndgameObjects(); DisableRisingHazards(); yield return null; yield return null; Vector3 peakStandingPosition = GetPeakStandingPosition(); List<Vector3> playerSpawnPositions = GetPlayerSpawnPositions(peakStandingPosition); Plugin.Log.LogInfo((object)$"Summit flag {peakStandingPosition}. {playerSpawnPositions.Count} player spawn(s), first {playerSpawnPositions[0]}."); MoveCrashedPlaneToPosition(peakStandingPosition); MoveSpawnPointsToDumps(playerSpawnPositions); if (PhotonNetwork.IsMasterClient) { WarpEveryoneToAssignedSpawns(playerSpawnPositions); } yield return (object)new WaitForSeconds(0.35f); SuppressEndgameObjects(); try { UnlightProgressCampfires(); PatchCampfiresForDescent(); } catch (Exception ex2) { Plugin.Log.LogError((object)("Campfire setup failed: " + ex2.GetType().Name + ": " + ex2.Message)); } finally { _started = true; _starting = false; } ParkEndgameAtShore(); PlayPeakTitle(); Plugin.Log.LogInfo((object)$"Reverse run ready at {GetCurrentSegment()}. Light the Kiln/Temple fire to open the next lower biome; fog will unload the previous segment and leave its campfire leftover."); if (!PhotonNetwork.IsMasterClient) { yield break; } try { SpawnCrashedPlaneItems(); } catch (Exception ex3) { Plugin.Log.LogError((object)("Crashed-plane item spawn failed: " + ex3.GetType().Name + ": " + ex3.Message)); } } internal static bool ShouldBlockSegmentAdvance(Campfire fire) { if (!IsRunning || (Object)(object)fire == (Object)null) { return false; } return NonProgressCampfires.Contains(((Object)fire).GetInstanceID()); } internal static bool ShouldSkipAutoLight() { if (!IsActive) { return _starting; } return true; } internal static void AdvanceFromCampfire() { //IL_0061: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (!IsActive || _won || _campfireTransition || _starting) { return; } if (!TryGetNextSegment(out var next)) { if (!_openedShore && (int)GetCurrentSegment() == 0 && (Object)(object)Plugin.Instance != (Object)null) { Plugin.Log.LogWarning((object)"Still on Shore after reverse start — retrying Kiln jump + Peak warp."); ((MonoBehaviour)Plugin.Instance).StartCoroutine(StartFromPeakRoutine()); } return; } if ((int)next == 0) { _openedShore = true; } Plugin.Log.LogInfo((object)$"Campfire: {GetCurrentSegment()} -> {next}"); if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(DescendByReveal(next)); } } private static IEnumerator DescendByReveal(Segment next) { //IL_0007: 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) _campfireTransition = true; try { yield return ReverseGoToSegment(next); DisableRisingHazards(); SuppressEndgameObjects(); yield return (object)new WaitForSeconds(0.2f); PatchCampfiresForDescent(); _unlocksDone++; if ((int)next != 0) { PlaySegmentTitle(next); } Plugin.Log.LogInfo((object)$"Opened {next} for descent. Current={GetCurrentSegment()}."); } finally { _campfireTransition = false; } } private static IEnumerator ReverseGoToSegment(Segment next) { //IL_0007: 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) MapHandler instance = Singleton<MapHandler>.Instance; if ((Object)(object)instance == (Object)null || instance.segments == null) { yield break; } int startIndex = GetClimbIndex(GetCurrentSegment()); int nextIndex = GetClimbIndex(next); if (nextIndex < 0 || nextIndex >= instance.segments.Length) { Plugin.Log.LogWarning((object)$"Reverse GoToSegment: no slot for {next}."); yield break; } MapSegment startSlot = ((startIndex >= 0 && startIndex < instance.segments.Length) ? instance.segments[startIndex] : null); MapSegment nextSlot = instance.segments[nextIndex]; if (nextSlot == null || (Object)(object)nextSlot.segmentParent == (Object)null) { Plugin.Log.LogWarning((object)$"Reverse GoToSegment: {next} has no parent."); yield break; } Plugin.Log.LogInfo((object)$"Reverse GoToSegment {GetCurrentSegment()} -> {next}. Fog, unload {startIndex} mesh, keep leftover fire, enable {nextIndex}."); try { if ((Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.data != (Object)null) { Character.localCharacter.data.DestroyCheckpointFlags(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("DestroyCheckpointFlags failed: " + ex.Message)); } SetCurrentSegment(instance, nextIndex); if ((int)next == 0) { _openedShore = true; } yield return WaitForFogCatchUpSafe(); yield return (object)new WaitForSecondsRealtime(1f); UnloadSegmentKeepCampfire(startSlot, startIndex); yield return null; EnableOpenedSegment(nextSlot, next); if ((int)next == 0) { ActivateNamedCampfire("Beach_Campfire"); } Segment next2; bool flag = TryGetNextSegment(out next2); if (flag) { ArmGateCampfire(next2); } HideOlderCampfires(startSlot, nextSlot, flag ? GetClimbSlot(next2) : null); if (PhotonNetwork.IsMasterClient) { SpawnSegmentItems(nextSlot, next); } try { if ((Object)(object)nextSlot.dayNightProfile != (Object)null && (Object)(object)DayNightManager.instance != (Object)null) { DayNightManager.instance.BlendProfiles(nextSlot.dayNightProfile); } } catch (Exception ex2) { Plugin.Log.LogWarning((object)("Day/night blend failed: " + ex2.Message)); } yield return OpenFogForDescent(); try { if ((int)next != 4 && (Object)(object)Singleton<OrbFogHandler>.Instance != (Object)null) { Singleton<OrbFogHandler>.Instance.SetFogOrigin(nextIndex); } } catch (Exception ex3) { Plugin.Log.LogWarning((object)("Fog origin failed: " + ex3.Message)); } } private static void EnableOpenedSegment(MapSegment slot, Segment id) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if (slot != null && !((Object)(object)slot.segmentParent == (Object)null)) { try { MapHandler.ActivateWithoutMessageQueue(slot.segmentParent); } catch (Exception ex) { Plugin.Log.LogWarning((object)("ActivateWithoutMessageQueue failed: " + ex.Message)); ActivateInHierarchy(slot.segmentParent); } EnableBiomeRoot(slot.segmentParent); EnableSubsteps(slot.segmentParent); if ((Object)(object)slot.segmentCampfire != (Object)null) { ActivateInHierarchy(slot.segmentCampfire); slot.segmentCampfire.SetActive(true); } if ((Object)(object)slot.wallNext != (Object)null) { slot.wallNext.SetActive(true); } if ((Object)(object)slot.wallPrevious != (Object)null) { slot.wallPrevious.SetActive(true); } LogSegmentContents(slot.segmentParent, id); } } private static void ArmGateCampfire(Segment gate) { //IL_0000: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) MapSegment climbSlot = GetClimbSlot(gate); if (climbSlot == null || (Object)(object)climbSlot.segmentCampfire == (Object)null) { Plugin.Log.LogWarning((object)$"No leftover campfire to arm for {gate}."); return; } ActivateInHierarchy(climbSlot.segmentCampfire); climbSlot.segmentCampfire.SetActive(true); if ((Object)(object)climbSlot.segmentParent != (Object)null) { climbSlot.segmentParent.SetActive(false); } UnlightCampfire(climbSlot.segmentCampfire.GetComponentInChildren<Campfire>(true)); Plugin.Log.LogInfo((object)$"Armed next leftover campfire for {gate} at '{GetPath(climbSlot.segmentCampfire.transform)}' pos={climbSlot.segmentCampfire.transform.position}."); } private static void HideOlderCampfires(MapSegment startSlot, MapSegment openedSlot, MapSegment gateSlot) { MapHandler instance = Singleton<MapHandler>.Instance; if ((Object)(object)instance == (Object)null || instance.segments == null) { return; } for (int i = 0; i < instance.segments.Length; i++) { MapSegment val = instance.segments[i]; if (val != null && !((Object)(object)val.segmentCampfire == (Object)null) && !SameCampfireRoot(val, startSlot) && !SameCampfireRoot(val, openedSlot) && !SameCampfireRoot(val, gateSlot)) { val.segmentCampfire.SetActive(false); } } } private static bool SameCampfireRoot(MapSegment a, MapSegment b) { if (a != null && b != null && (Object)(object)a.segmentCampfire != (Object)null) { return (Object)(object)a.segmentCampfire == (Object)(object)b.segmentCampfire; } return false; } private static void UnloadSegmentKeepCampfire(MapSegment slot, int index) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (slot != null) { if ((Object)(object)slot.segmentCampfire != (Object)null) { ActivateInHierarchy(slot.segmentCampfire); Plugin.Log.LogInfo((object)$"Kept leftover campfire '{GetPath(slot.segmentCampfire.transform)}' at {slot.segmentCampfire.transform.position}."); } if ((Object)(object)slot.segmentParent != (Object)null && slot.segmentParent.activeSelf) { slot.segmentParent.SetActive(false); Plugin.Log.LogInfo((object)$"Unloaded previous segment parent '{((Object)slot.segmentParent).name}' (index {index}) after fog."); } if ((Object)(object)slot.wallNext != (Object)null) { slot.wallNext.SetActive(false); } if ((Object)(object)slot.wallPrevious != (Object)null) { slot.wallPrevious.SetActive(false); } } } private static MapSegment GetClimbSlot(Segment id) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) MapHandler instance = Singleton<MapHandler>.Instance; int climbIndex = GetClimbIndex(id); if ((Object)(object)instance == (Object)null || instance.segments == null || climbIndex < 0 || climbIndex >= instance.segments.Length) { return null; } return instance.segments[climbIndex]; } private static IEnumerator WaitForFogCatchUpSafe() { OrbFogHandler instance = Singleton<OrbFogHandler>.Instance; if ((Object)(object)instance == (Object)null) { yield break; } IEnumerator wait; try { wait = instance.WaitForFogCatchUp(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Fog catch-up failed to start: " + ex.Message)); yield break; } while (true) { bool flag; try { flag = wait.MoveNext(); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("Fog catch-up failed: " + ex2.Message)); break; } if (!flag) { break; } yield return wait.Current; } } private static void SpawnItemsUnder(GameObject root) { if ((Object)(object)root == (Object)null) { return; } ISpawner[] componentsInChildren = root.GetComponentsInChildren<ISpawner>(true); int num = 0; for (int i = 0; i < componentsInChildren.Length; i++) { ISpawner obj = componentsInChildren[i]; MonoBehaviour val = (MonoBehaviour)(object)((obj is MonoBehaviour) ? obj : null); if (componentsInChildren[i] != null && (!((Object)(object)val != (Object)null) || !IsUnderCrashedPlane(((Component)val).transform))) { try { num += componentsInChildren[i].TrySpawnItems()?.Count ?? 0; } catch (Exception ex) { Plugin.Log.LogWarning((object)("Spawner failed: " + ex.GetType().Name + ": " + ex.Message)); } } } Plugin.Log.LogInfo((object)$"Spawned {num} item(s) under '{((Object)root).name}'."); } private static void UnlightProgressCampfires() { Campfire[] array = Object.FindObjectsByType<Campfire>((FindObjectsInactive)1, (FindObjectsSortMode)0); int num = 0; foreach (Campfire val in array) { if (!((Object)(object)val == (Object)null) && !NonProgressCampfires.Contains(((Object)val).GetInstanceID()) && IsDescentGateCampfire(val)) { UnlightCampfire(val); num++; Plugin.Log.LogInfo((object)("Unlit progress campfire '" + ((Object)val).name + "' (" + GetPath(((Component)val).transform) + ").")); } } Plugin.Log.LogInfo((object)$"Reset {num} progress campfire(s) so they can be lit for descent."); } private static bool IsDescentGateCampfire(Campfire fire) { if ((Object)(object)fire == (Object)null) { return false; } string path = GetPath(((Component)fire).transform); string name = ((Object)((Component)fire).gameObject).name; if (path.IndexOf("crashed plane", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } if (name.IndexOf("Temple", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Kiln", StringComparison.OrdinalIgnoreCase) >= 0 || path.IndexOf("Gloom Temple", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } MapHandler instance = Singleton<MapHandler>.Instance; if ((Object)(object)instance == (Object)null || instance.segments == null) { return false; } for (int i = 0; i < instance.segments.Length; i++) { MapSegment val = instance.segments[i]; if (val != null && (Object)(object)val.segmentCampfire != (Object)null && ((Component)fire).transform.IsChildOf(val.segmentCampfire.transform)) { return true; } } return false; } private static void UnlightCampfire(Campfire fire) { if ((Object)(object)fire == (Object)null) { return; } try { fire.forceLit = false; } catch { } try { fire.beenBurningFor = 0f; fire.state = (FireState)0; } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not reset '" + ((Object)fire).name + "' state: " + ex.Message)); } } private static IEnumerator OpenFogForDescent() { OrbFogHandler instance = Singleton<OrbFogHandler>.Instance; if ((Object)(object)instance == (Object)null) { yield break; } IEnumerator reveal; try { reveal = instance.WaitForReveal(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Fog reveal failed to start: " + ex.Message)); yield break; } while (true) { bool flag; try { flag = reveal.MoveNext(); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("Fog reveal failed: " + ex2.Message)); break; } if (!flag) { break; } yield return reveal.Current; } } internal static void NotifyJumpedTo(Segment segment) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (IsRunning && !_won && (int)segment == 0) { _openedShore = true; } } internal static bool IsAtShore(Vector3 position) { //IL_0020: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (!IsRunning || !_openedShore) { return false; } MapHandler instance = Singleton<MapHandler>.Instance; if ((Object)(object)instance == (Object)null || (int)instance.GetCurrentSegment() != 0) { return false; } CacheShoreStinger(); if (_hasShoreStinger && position.z > _shoreStinger.z) { return false; } if (_hasShoreAnchor) { return Vector3.Distance(position, _shoreAnchor) <= 50f; } return _hasShoreStinger; } internal static bool IsHelicopterWinActive() { if (_heliSummoned || _won) { return true; } PeakHandler instance = Singleton<PeakHandler>.Instance; if ((Object)(object)instance != (Object)null) { return instance.summonedHelicopter; } return false; } internal static void MarkRunWon() { _won = true; } internal static bool PrepareShoreHelicopter() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!IsRunning || !_openedShore) { return false; } ParkEndgameAtShore(); _heliSummoned = true; Plugin.Log.LogInfo((object)$"Shore flare accepted at crash site {_shoreAnchor}. Vanilla helicopter / rope / countdown will run there."); return true; } internal static void TickReverseProgress() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!IsRunning || _playedShoreTitle || !_openedShore) { return; } Character localCharacter = Character.localCharacter; if (!((Object)(object)localCharacter == (Object)null) && !((Object)(object)localCharacter.data == (Object)null) && !localCharacter.data.dead) { CacheShoreStinger(); if (_hasShoreStinger && !(localCharacter.Center.z > _shoreStinger.z)) { PlayProgressPoint(FindProgressPoint((BiomeType)0, "SHORE"), "shore walk"); _playedShoreTitle = true; } } } internal static void EnableShoreForCutscene() { MapHandler instance = Singleton<MapHandler>.Instance; if ((Object)(object)instance == (Object)null || instance.segments == null || instance.segments.Length == 0) { return; } try { if (instance.segments.Length > 3 && instance.segments[3] != null && (Object)(object)instance.segments[3].segmentParent != (Object)null) { Transform parent = instance.segments[3].segmentParent.transform.parent; if ((Object)(object)parent != (Object)null) { ((Component)parent).gameObject.SetActive(false); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not hide vanilla cutscene biome 3: " + ex.Message)); } MapSegment climbSlot = GetClimbSlot((Segment)0); if (climbSlot != null && (Object)(object)climbSlot.segmentParent != (Object)null) { ActivateInHierarchy(climbSlot.segmentParent); Plugin.Log.LogInfo((object)"Enabled Shore for the end cutscene backdrop."); } ShoreCutsceneCameraHold.AttachToEndCutscenes(); ShoreCutscenePilot.AttachToEndCutscenes(); } internal static void BringLatePlayer(Character character) { if (IsRunning && !((Object)(object)character == (Object)null) && !character.isBot && PhotonNetwork.IsMasterClient && !((Object)(object)Plugin.Instance == (Object)null)) { PhotonView photonView = ((MonoBehaviourPun)character).photonView; if (!((Object)(object)photonView == (Object)null) && photonView.Owner != null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(BringLatePlayerRoutine(character)); } } } private static IEnumerator BringLatePlayerRoutine(Character character) { yield return (object)new WaitForSeconds(3f); if (!IsRunning || (Object)(object)character == (Object)null) { yield break; } Vector3 val = ClaimRandomSpawn(GetPlayerSpawnPositions(GetPeakStandingPosition())); if (GetCurrentSegment() != GetTopClimbSegment()) { Campfire currentCampfire = MapHandler.CurrentCampfire; if ((Object)(object)currentCampfire != (Object)null) { val = ((Component)currentCampfire).transform.position; } } ((MonoBehaviourPun)character).photonView.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { val, false }); } private static void RevealEntireClimb(bool spawnItems) { //IL_001e: 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_0023: Invalid comparison between Unknown and I4 //IL_008e: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Invalid comparison between Unknown and I4 //IL_00bc: 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) MapHandler instance = Singleton<MapHandler>.Instance; if ((Object)(object)instance == (Object)null || instance.segments == null) { return; } for (int i = 0; i < instance.segments.Length; i++) { Segment val = (Segment)(byte)i; if ((int)val != 6 && (int)val != 5) { MapSegment val2 = instance.segments[i]; if (val2 != null && !((Object)(object)val2.segmentParent == (Object)null) && (int)val2.biome != 17) { EnableSlotGeometry(val2, val); } } } EnablePeakExtras(instance); ActivateNamedCampfire("Campfire-Temple"); ActivateNamedCampfire("Campfire-Kiln"); ActivateNamedCampfire("Beach_Campfire"); Segment topClimbSegment = GetTopClimbSegment(); int climbIndex = GetClimbIndex(topClimbSegment); if (spawnItems && PhotonNetwork.IsMasterClient && climbIndex >= 0 && climbIndex < instance.segments.Length) { SpawnSegmentItems(instance.segments[climbIndex], topClimbSegment); } } private static void RevealSegment(Segment target, bool spawnItems, bool keepOthers) { //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Invalid comparison between Unknown and I4 //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) try { MapHandler instance = Singleton<MapHandler>.Instance; if ((Object)(object)instance == (Object)null || instance.segments == null) { return; } int climbIndex = GetClimbIndex(target); if (climbIndex < 0 || climbIndex >= instance.segments.Length) { Plugin.Log.LogWarning((object)$"RevealSegment: no climb slot for {target}."); return; } MapSegment val = instance.segments[climbIndex]; if (val == null || (Object)(object)val.segmentParent == (Object)null) { Plugin.Log.LogWarning((object)$"RevealSegment: {target} has no parent."); return; } if (!keepOthers) { DisableAllSegments(instance); } EnableSlotGeometry(val, target); if ((int)target == 4 || (int)target == 5) { EnablePeakExtras(instance); } ActivateNamedCampfire("Campfire-Temple"); ActivateNamedCampfire("Campfire-Kiln"); if ((int)target == 0) { ActivateNamedCampfire("Beach_Campfire"); } SetCurrentSegment(instance, climbIndex); if (spawnItems && PhotonNetwork.IsMasterClient) { SpawnSegmentItems(val, target); } try { if ((Object)(object)val.dayNightProfile != (Object)null && (Object)(object)DayNightManager.instance != (Object)null) { DayNightManager.instance.BlendProfiles(val.dayNightProfile); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Day/night blend failed: " + ex.Message)); } try { if ((Object)(object)Singleton<OrbFogHandler>.Instance != (Object)null) { Singleton<OrbFogHandler>.Instance.SetFogOrigin(climbIndex); } } catch (Exception ex2) { Plugin.Log.LogWarning((object)("Fog origin failed: " + ex2.Message)); } } catch (Exception ex3) { Plugin.Log.LogError((object)$"RevealSegment({target}) failed: {ex3.GetType().Name}: {ex3.Message}"); } } private static void EnableSlotGeometry(MapSegment slot, Segment id) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) if (slot != null && !((Object)(object)slot.segmentParent == (Object)null)) { ActivateInHierarchy(slot.segmentParent); EnableBiomeRoot(slot.segmentParent); EnableSubsteps(slot.segmentParent); if ((Object)(object)slot.segmentCampfire != (Object)null) { ActivateInHierarchy(slot.segmentCampfire); slot.segmentCampfire.SetActive(true); } if ((Object)(object)slot.wallNext != (Object)null) { slot.wallNext.SetActive(true); } if ((Object)(object)slot.wallPrevious != (Object)null) { slot.wallPrevious.SetActive(true); } LogSegmentContents(slot.segmentParent, id); } } private static void SpawnSegmentItems(MapSegment slot, Segment target) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0048: Unknown result type (might be due to invalid IL or missing references) try { List<ISpawner> list = new List<ISpawner>(); list.AddRange(slot.segmentParent.GetComponentsInChildren<ISpawner>(true)); if (((int)target == 4 || (int)target == 5) && (Object)(object)Singleton<PeakHandler>.Instance != (Object)null) { list.AddRange(((Component)Singleton<PeakHandler>.Instance).GetComponentsInChildren<ISpawner>(true)); } Plugin.Log.LogInfo((object)$"Spawning items in {target} from {list.Count} spawners. Parent: {((Object)slot.segmentParent).name}"); for (int i = 0; i < list.Count; i++) { try { ISpawner obj = list[i]; if (obj != null) { obj.TrySpawnItems(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)$"Spawner {i} failed: {ex.GetType().Name}: {ex.Message}"); } } if ((Object)(object)slot.segmentCampfire != (Object)null) { MapHandler.SpawnCampfireItems(slot.segmentCampfire, false); } } catch (Exception ex2) { Plugin.Log.LogError((object)("SpawnSegmentItems failed: " + ex2.GetType().Name + ": " + ex2.Message)); } } private static void EnablePeakPlatform() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) Transform val = FindPeakPlatform(); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"No Peak / Peak_Kiln Variant platform found under the top climb segment."); return; } ActivateInHierarchy(((Component)val).gameObject); Plugin.Log.LogInfo((object)$"Enabled Peak platform '{GetPath(val)}' at {val.position}."); MoveFlareBoxToShore(); } private static Transform FindChildNamed(Transform parent, string name) { if ((Object)(object)parent == (Object)null) { return null; } Transform[] componentsInChildren = ((Component)parent).GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && ((Object)componentsInChildren[i]).name.Equals(name, StringComparison.OrdinalIgnoreCase)) { return componentsInChildren[i]; } } return null; } private static Transform FindChildByRelativePath(Transform root, string relPath) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(relPath) || relPath == ".") { return root; } Transform val = root; string[] array = relPath.Split(new char[1] { '/' }); for (int i = 0; i < array.Length; i++) { Transform val2 = null; for (int j = 0; j < val.childCount; j++) { Transform child = val.GetChild(j); if (((Object)child).name == array[i]) { val2 = child; break; } } if ((Object)(object)val2 == (Object)null) { return null; } val = val2; } return val; } private static string GetRelativePath(Transform node, Transform root) { if ((Object)(object)node == (Object)null || (Object)(object)root == (Object)null || (Object)(object)node == (Object)(object)root) { return "."; } List<string> list = new List<string>(); Transform val = node; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root) { list.Add(((Object)val).name); val = val.parent; } if ((Object)(object)val != (Object)(object)root) { return null; } list.Reverse(); return string.Join("/", list); } private static void EnablePeakExtras(MapHandler map) { EnablePeakPlatform(); SuppressEndgameObjects(); } private static void SuppressEndgameObjects() { PeakGatePortal[] array = Object.FindObjectsByType<PeakGatePortal>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (PeakGatePortal val in array) { if (!((Object)(object)val == (Object)null)) { ((Behaviour)val).enabled = false; ((Component)val).gameObject.SetActive(false); } } PeakHandler instance = Singleton<PeakHandler>.Instance; if (!((Object)(object)instance == (Object)null) && !IsHelicopterWinActive()) { if ((Object)(object)instance.peakSequence != (Object)null) { instance.peakSequence.SetActive(false); } if ((Object)(object)instance.endCutscene != (Object)null) { instance.endCutscene.SetActive(false); } if ((Object)(object)instance.endCutsceneFinal != (Object)null) { instance.endCutsceneFinal.SetActive(false); } } } private static void ParkEndgameAtShore() { //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_003b: 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_0045: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_00d4: Unknown result type (might be due to invalid IL or missing references) PeakHandler instance = Singleton<PeakHandler>.Instance; if ((Object)(object)instance == (Object)null) { return; } KeepEndgameAlive(instance); if (!_endgameMoved && _hasShoreAnchor) { GameObject peakSequence = instance.peakSequence; Vector3 val = _shoreAnchor + Vector3.up * 8f; Vector3 val2 = (((Object)(object)peakSequence != (Object)null) ? peakSequence.transform.position : val); Vector3 val3 = val - val2; OffsetEndgameRoot(peakSequence, val3, "peakSequence", null); OffsetEndgameRoot(instance.endCutscene, val3, "endCutscene", peakSequence); OffsetEndgameRoot(instance.endCutsceneFinal, val3, "endCutsceneFinal", peakSequence); OffsetEndgameRoot(instance.endCutsceneFinalSpecialDay, val3, "endCutsceneFinalSpecialDay", peakSequence); if ((Object)(object)peakSequence != (Object)null) { peakSequence.SetActive(false); } _endgameMoved = true; Plugin.Log.LogInfo((object)$"Parked helicopter / end cutscene at shore crash site {val} (delta {val3})."); } } private static void KeepEndgameAlive(PeakHandler peakHandler) { if ((Object)(object)peakHandler == (Object)null) { return; } Transform transform = ((Component)peakHandler).transform; if ((Object)(object)transform.parent != (Object)null) { Plugin.Log.LogInfo((object)("Unparented PeakHandler from '" + GetPath(transform.parent) + "' so Kiln unload cannot hide the helicopter.")); transform.SetParent((Transform)null, true); } PeakSequence[] componentsInChildren = ((Component)peakHandler).GetComponentsInChildren<PeakSequence>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { ((Behaviour)componentsInChildren[i]).enabled = true; } } } private static void OffsetEndgameRoot(GameObject go, Vector3 delta, string label, GameObject alreadyMoved) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0086: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)go == (Object)null || ((Vector3)(ref delta)).sqrMagnitude < 0.01f) { return; } Transform transform = go.transform; if (!((Object)(object)alreadyMoved != (Object)null) || (!((Object)(object)transform == (Object)(object)alreadyMoved.transform) && !transform.IsChildOf(alreadyMoved.transform))) { PeakHandler instance = Singleton<PeakHandler>.Instance; if ((Object)(object)transform.parent != (Object)null && ((Object)(object)instance == (Object)null || (Object)(object)transform.parent != (Object)(object)((Component)instance).transform)) { transform.SetParent((Transform)null, true); } Vector3 position = transform.position; transform.position = position + delta; Plugin.Log.LogInfo((object)$"Moved {label} '{((Object)go).name}' {position} -> {transform.position}."); } } private static void PlayPeakTitle() { if (!_playedPeakTitle) { ProgressPoint val = FindProgressPoint((BiomeType)5, "PEAK"); if (val == null) { val = FindLastProgressPoint(); } PlayProgressPoint(val, "peak start"); _playedPeakTitle = true; } } private unsafe static void PlaySegmentTitle(Segment segment) { //IL_0000: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0018: Unknown result type (might be due to invalid IL or missing references) MapSegment climbSlot = GetClimbSlot(segment); BiomeType val = (BiomeType)((climbSlot != null) ? ((int)climbSlot.biome) : 0); if ((int)segment == 0) { val = (BiomeType)0; } PlayProgressPoint(FindProgressPoint(val, ((object)(*(Segment*)(&segment))/*cast due to .constrained prefix*/).ToString()), $"unlock {segment}"); if ((int)val == 0) { _playedShoreTitle = true; } } private static void PlayProgressPoint(ProgressPoint point, string reason) { if (point == null || (Object)(object)GUIManager.instance == (Object)null) { Plugin.Log.LogWarning((object)("No progress title to play (" + reason + ").")); return; } try { GUIManager.instance.SetHeroTitle(point.localizedTitle, point.clip, false); MountainProgressHandler.SetRichPresence(point); Plugin.Log.LogInfo((object)("Played '" + point.title + "' stinger (" + reason + ").")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not play '" + point.title + "' stinger: " + ex.Message)); } } private static ProgressPoint FindProgressPoint(BiomeType biome, string titleHint) { //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) MountainProgressHandler instance = Singleton<MountainProgressHandler>.Instance; if ((Object)(object)instance == (Object)null || instance.progressPoints == null) { return null; } ProgressPoint val = null; for (int i = 0; i < instance.progressPoints.Length; i++) { ProgressPoint val2 = instance.progressPoints[i]; if (val2 != null) { if (val2.biome == biome) { return val2; } if (val == null && !string.IsNullOrEmpty(titleHint) && !string.IsNullOrEmpty(val2.title) && val2.title.IndexOf(titleHint, StringComparison.OrdinalIgnoreCase) >= 0) { val = val2; } } } return val; } private static ProgressPoint FindLastProgressPoint() { MountainProgressHandler instance = Singleton<MountainProgressHandler>.Instance; if ((Object)(object)instance == (Object)null || instance.progressPoints == null || instance.progressPoints.Length == 0) { return null; } return instance.progressPoints[instance.progressPoints.Length - 1]; } private static void CacheShoreStinger() { //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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (!_hasShoreStinger) { ProgressPoint val = FindProgressPoint((BiomeType)0, "SHORE"); if (val != null && !((Object)(object)val.transform == (Object)null)) { _shoreStinger = val.transform.position; _hasShoreStinger = true; Plugin.Log.LogInfo((object)$"Shore stinger line at {_shoreStinger}. Crash site {_shoreAnchor} (flare only on the beach side, within {50f}m)."); } } } private static void EnableBiomeRoot(GameObject segmentParent) { if ((Object)(object)segmentParent == (Object)null || (Object)(object)segmentParent.transform.parent == (Object)null) { return; } Transform parent = segmentParent.transform.parent; ActivateInHierarchy(((Component)parent).gameObject); for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if (!((Object)(object)child == (Object)null) && !((Object)(object)((Component)child).gameObject == (Object)(object)segmentParent) && (Object)(object)((Component)child).GetComponent<EnablingSubstep>() != (Object)null) { ((Component)child).gameObject.SetActive(true); } } } private static void EnableSubsteps(GameObject parent) { if ((Object)(object)parent == (Object)null) { return; } EnablingSubstep[] componentsInChildren = parent.GetComponentsInChildren<EnablingSubstep>(true); int num = 0; for (int i = 0; i < componentsInChildren.Length; i++) { if (!((Object)(object)componentsInChildren[i] == (Object)null) && !((Component)componentsInChildren[i]).gameObject.activeSelf) { ((Component)componentsInChildren[i]).gameObject.SetActive(true); num++; } } Plugin.Log.LogInfo((object)$"Enabled {num}/{componentsInChildren.Length} EnablingSubstep(s) under {((Object)parent).name}."); } private static void DisableAllSegments(MapHandler map) { if (map.segments == null) { return; } for (int i = 0; i < map.segments.Length; i++) { MapSegment val = map.segments[i]; if (val != null) { if ((Object)(object)val.segmentParent != (Object)null) { val.segmentParent.SetActive(false); } if ((Object)(object)val.segmentCampfire != (Object)null) { val.segmentCampfire.SetActive(false); } } } } private static void DisableRisingHazards() { int num = 0; List<LavaRising> aLL_LAVA = LavaRising.ALL_LAVA; if (aLL_LAVA != null) { for (int i = 0; i < aLL_LAVA.Count; i++) { LavaRising val = aLL_LAVA[i]; if (!((Object)(object)val == (Object)null)) { ((Behaviour)val).enabled = false; val.ended = true; val.started = false; num++; } } } Plugin.Log.LogInfo((object)$"Stopped {num} rising lava/gloom field(s) for reverse descent."); } private static void PatchCampfiresForDescent() { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) Campfire[] array = Object.FindObjectsByType<Campfire>((FindObjectsInactive)1, (FindObjectsSortMode)0); int num = 0; foreach (Campfire val in array) { if ((Object)(object)val == (Object)null || NonProgressCampfires.Contains(((Object)val).GetInstanceID()) || !TryGetDescentTargetForCampfire(val, out var next)) { continue; } try { if (val.advanceToSegment != next) { val.advanceToSegment = next; num++; Plugin.Log.LogInfo((object)$"Patched campfire '{((Object)val).name}' advanceToSegment -> {next} ({GetPath(((Component)val).transform)})"); } } catch (Exception ex) { try { Traverse.Create((object)val).Field("advanceToSegment").SetValue((object)next); num++; Plugin.Log.LogInfo((object)$"Traverse-patched campfire '{((Object)val).name}' -> {next}"); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("Could not patch '" + ((Object)val).name + "': " + ex.Message + " / " + ex2.Message)); } } } Plugin.Log.LogInfo((object)$"Patched {num} campfire(s) for descent."); } private static bool TryGetDescentTargetForCampfire(Campfire fire, out Segment next) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) next = (Segment)0; if ((Object)(object)fire == (Object)null) { return false; } if (GetPath(((Component)fire).transform).IndexOf("crashed plane", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } if (!TryGetCampfireOwner(fire, out var owner)) { return false; } return TryGetNextAfter(owner, out next); } private static bool TryGetCampfireOwner(Campfire fire, out Segment owner) { //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_003c: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected I4, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected I4, but got Unknown owner = (Segment)0; if ((Object)(object)fire == (Object)null) { return false; } MapHandler instance = Singleton<MapHandler>.Instance; if ((Object)(object)instance == (Object)null || instance.segments == null) { return false; } int num = int.MaxValue; bool flag = false; for (int i = 0; i < instance.segments.Length; i++) { Segment val = (Segment)(byte)i; if ((int)val == 6 || (int)val == 5) { continue; } MapSegment val2 = instance.segments[i]; if (val2 != null && (BelongsToSlotCampfire(fire, val2) || BelongsToSlotParent(fire, val2))) { int num2 = IndexInReversed(val); if (num2 < 0) { num2 = 100 + i; } if (num2 < num) { num = num2; owner = (Segment)(int)val; flag = true; } } } if (flag) { return true; } string path = GetPath(((Component)fire).transform); string name = ((Object)((Component)fire).gameObject).name; if (name.IndexOf("Temple", StringComparison.OrdinalIgnoreCase) >= 0 || path.IndexOf("Gloom Temple", StringComparison.OrdinalIgnoreCase) >= 0 || path.IndexOf("Campfire-Temple", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Kiln", StringComparison.OrdinalIgnoreCase) >= 0) { owner = (Segment)(int)GetTopClimbSegment(); return true; } return false; } private static bool BelongsToSlotCampfire(Campfire fire, MapSegment slot) { if ((Object)(object)fire == (Object)null || slot == null || (Object)(object)slot.segmentCampfire == (Object)null) { return false; } Transform transform = slot.segmentCampfire.transform; if (!((Object)(object)((Component)fire).transform == (Object)(object)transform) && !((Component)fire).transform.IsChildOf(transform)) { return transform.IsChildOf(((Component)fire).transform); } return true; } private static bool BelongsToSlotParent(Campfire fire, MapSegment slot) { if ((Object)(object)fire != (Object)null && slot != null && (Object)(object)slot.segmentParent != (Object)null) { return ((Component)fire).transform.IsChildOf(slot.segmentParent.transform); } return false; } private static bool TryGetNextAfter(Segment current, out Segment next) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected I4, but got Unknown next = (Segment)0; int num = IndexInReversed(current); if (num < 0 || num + 1 >= ReversedOrder.Count) { return false; } next = (Segment)(int)ReversedOrder[num + 1]; return true; } private static void LogClimbSlots(MapHandler map) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)map == (Object)null || map.segments == null) { return; } for (int i = 0; i < map.segments.Length; i++) { MapSegment val = map.segments[i]; if (val != null && !((Object)(object)val.segmentParent == (Object)null)) { string text = (((Object)(object)val.segmentCampfire != (Object)null) ? $"{GetPath(val.segmentCampfire.transform)} on={val.segmentCampfire.activeSelf}/{val.segmentCampfire.activeInHierarchy} at {val.segmentCampfire.transform.position}" : "none"); Plugin.Log.LogInfo((object)$"Slot {i} {(object)(Segment)(byte)i}: parent='{((Object)val.segmentParent).name}' parentOn={val.segmentParent.activeSelf}/{val.segmentParent.activeInHierarchy}; campfire {text}"); } } } private static string GetPath(Transform transform) { if ((Object)(object)transform == (Object)null) { return ""; } List<string> list = new List<string>(); Transform val = transform; while ((Object)(object)val != (Object)null) { list.Add(((Object)val).name); val = val.parent; } list.Reverse(); return string.Join("/", list); } private static Vector3 RemapFromFlag(Vector3 dumpedWorld, Vector3 standingPos) { //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_000c: Unknown result type (might be due to invalid IL or missing references) return standingPos + (dumpedWorld - CitadelFlagStanding); } private static List<Vector3> GetPlayerSpawnPositions(Vector3 standingPos) { //IL_000f: 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_0032: Unknown result type (might be due to invalid IL or missing references) List<Vector3> list = LoadPlayerSpawnDumps(); if (list.Count == 0) { list.Add(DumpedPlayerCenter); } List<Vector3> list2 = new List<Vector3>(list.Count); for (int i = 0; i < list.Count; i++) { list2.Add(RemapFromFlag(list[i], standingPos)); } return list2; } private static void ResetSpawnDeck(List<Vector3> spots) { _spawnDeck = ((spots != null) ? new List<Vector3>(spots) : new List<Vector3>()); _spawnPool = new List<Vector3>(_spawnDeck); } private static Vector3 ClaimRandomSpawn(List<Vector3> fallbackSpots) { //IL_005d: 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) if (_spawnPool == null || _spawnPool.Count == 0) { if (_spawnDeck != null && _spawnDeck.Count > 0) { _spawnPool = new List<Vector3>(_spawnDeck); } else if (fallbackSpots != null && fallbackSpots.Count > 0) { ResetSpawnDeck(fallbackSpots); } } if (_spawnPool == null || _spawnPool.Count == 0) { return GetPeakStandingPosition(); } int index = Random.Range(0, _spawnPool.Count); Vector3 result = _spawnPool[index]; _spawnPool.RemoveAt(index); return result; } private static void MoveSpawnPointsToDumps(List<Vector3> spots) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) List<SpawnPoint> allSpawnPoints = SpawnPoint.allSpawnPoints; if (allSpawnPoints == null || spots == null || spots.Count == 0) { return; } List<Vector3> list = new List<Vector3>(spots); List<SpawnPoint> list2 = new List<SpawnPoint>(); for (int i = 0; i < allSpawnPoints.Count; i++) { if ((Object)(object)allSpawnPoints[i] != (Object)null) { list2.Add(allSpawnPoints[i]); } } list2.Sort((SpawnPoint a, SpawnPoint b) => a.index.CompareTo(b.index)); for (int num = 0; num < list2.Count; num++) { if (list.Count == 0) { list.AddRange(spots); } int index = Random.Range(0, list.Count); Vector3 position = list[index]; list.RemoveAt(index); ((Component)list2[num]).transform.SetParent((Transform)null, true); ((Component)list2[num]).transform.position = position; } Plugin.Log.LogInfo((object)$"Moved {list2.Count} scout spawn point(s) onto {spots.Count} baked spawn(s)."); } private static void WarpEveryoneToAssignedSpawns(List<Vector3> spots) { //IL_006c: 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_0082: 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) List<Character> allPlayerCharacters = PlayerHandler.GetAllPlayerCharacters(); if (allPlayerCharacters == null || spots == null || spots.Count == 0) { return; } ResetSpawnDeck(spots); Plugin.Log.LogInfo((object)$"Warping {allPlayerCharacters.Count} player(s) across {spots.Count} baked spawn(s), unique random claims."); for (int i = 0; i < allPlayerCharacters.Count; i++) { Character val = allPlayerCharacters[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)((MonoBehaviourPun)val).photonView == (Object)null)) { Vector3 val2 = ClaimRandomSpawn(spots); Plugin.Log.LogInfo((object)$"Scout '{val.characterName}' claimed spawn {val2} ({_spawnPool.Count} pad(s) left)."); ((MonoBehaviourPun)val).photonView.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { val2, false }); } } } private static bool SetCurrentSegment(MapHandler map, int index) { if ((Object)(object)map == (Object)null) { return false; } try { map.currentSegment = index; Plugin.Log.LogInfo((object)$"Set currentSegment={index} ({(object)(Segment)(byte)index})."); return true; } catch (Exception ex) { Plugin.Log.LogError((object)("Could not set currentSegment: " + ex.GetType().Name + ": " + ex.Message)); return false; } } private static Segment GetCurrentSegment() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) MapHandler instance = Singleton<MapHandler>.Instance; if ((Object)(object)instance == (Object)null) { return (Segment)0; } return instance.GetCurrentSegment(); } private static void CaptureShoreAnchor() { //IL_0008: 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) //IL_005f: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) if (_hasShoreAnchor) { return; } Vector3 val = Vector3.zero; int num = 0; List<SpawnPoint> allSpawnPoints = SpawnPoint.allSpawnPoints; if (allSpawnPoints != null) { for (int i = 0; i < allSpawnPoints.Count; i++) { if (!((Object)(object)allSpawnPoints[i] == (Object)null)) { val += ((Component)allSpawnPoints[i]).transform.position; num++; } } } if (num > 0) { _shoreAnchor = val / (float)num; _hasShoreAnchor = true; CacheShoreStinger(); return; } Transform val2 = (((Object)(object)SpawnPoint.LocalSpawnPoint != (Object)null) ? ((Component)SpawnPoint.LocalSpawnPoint).transform : null); if ((Object)(object)val2 != (Object)null) { _shoreAnchor = val2.position; _hasShoreAnchor = true; } } private static void ActivateInHierarchy(GameObject go) { if ((Object)(object)go == (Object)null) { return; } Transform val = go.transform; while ((Object)(object)val != (Object)null) { if (!((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } if (!((Object)(object)((Component)val).GetComponent<MapHandler>() != (Object)null)) { val = val.parent; continue; } break; } } private static void ActivateNamedCampfire(string name) { Transform val = FindNamedTransform(name); if (!((Object)(object)val == (Object)null)) { ActivateInHierarchy(((Component)val).gameObject); ((Component)val).gameObject.SetActive(true); } } private static void MoveCrashedPlaneToPosition(Vector3 standingPos) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_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_008a: Unknown result type (might be due to invalid IL or missing references) Transform val = FindNamedTransform("crashed plane"); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"Crashed plane not found — Peak start will still work."); return; } val.SetParent((Transform)null, true); ((Component)val).gameObject.SetActive(true); if (TryLoadEmbeddedPlaneDump(out var dump, out var rootRot)) { val.SetPositionAndRotation(standingPos, rootRot); ApplyPlaneDumpLocals(val, dump); } else { val.SetPositionAndRotation(standingPos, DumpedPlaneRot); Plugin.Log.LogWarning((object)"No plane dump available — placed wreck root on the flag with default rotation."); } HidePlanePiece(val, "Wings.004"); MarkPlaneCampfiresNonProgress(val); Plugin.Log.LogInfo((object)$"Moved crashed plane to flag {standingPos}."); } private static Transform FindPlaneCampfire(Transform plane) { Campfire componentInChildren = ((Component)plane).GetComponentInChildren<Campfire>(true); if ((Object)(object)componentInChildren != (Object)null) { return ((Component)componentInChildren).transform; } return FindChildNamed(plane, "Campfire_Flame"); } private static void GatherPlaneSpawners(Transform plane, List<Transform> dest) { for (int i = 0; i < plane.childCount; i++) { Transform child = plane.GetChild(i); if (!((Object)(object)child == (Object)null) && ((Object)child).name.IndexOf("Spawner", StringComparison.OrdinalIgnoreCase) >= 0) { ISpawner component = ((Component)child).GetComponent<ISpawner>(); if (component != null && !(component is EndgameFlareSpawner)) { dest.Add(child); } } } } private static void PlaceSpawnersAroundFire(List<Transform> spawners, Vector3 firePos) { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) int count = spawners.Count; if (count == 0) { return; } int num = 0; int num2 = 0; for (int i = 0; i < count; i++) { if (!IsBingBongName(((Object)spawners[i]).name)) { num2++; } } if (num2 < 1) { num2 = 1; } for (int j = 0; j < count; j++) { if (!IsBingBongName(((Object)spawners[j]).name)) { float num3 = (float)num * (float)Math.PI * 2f / (float)num2; num++; Vector3 val = firePos + new Vector3(Mathf.Cos(num3) * 2.25f, 0.2f, Mathf.Sin(num3) * 2.25f); spawners[j].SetPositionAndRotation(val, Quaternion.identity); } } Plugin.Log.LogInfo((object)$"Moved {count} plane item spawner(s) into a ring around the wreck campfire at {firePos}."); } private static bool TryGetSeatPose(Transform plane, out Vector3 dest, out Quaternion rot) { //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_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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) dest = Vector3.zero; rot = Quaternion.identity; Transform val = FindChildByRelativePath(plane, "Back Half/Frame.002"); if ((Object)(object)val == (Object)null) { val = FindChildNamed(plane, "Frame.002"); } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"Blue seat Frame.002 not found — leaving BingBong in the fire ring."); return false; } if (TryGetSeatTop(val, out dest)) { dest += Vector3.up * 0.25f; } else { dest = val.position + Vector3.up * 1.15f; } rot = val.rotation; return true; } private static bool TryGetBingBongPlacePose(Transform plane, out Vector3 dest, out Quaternion rot) { if (TryGetBingBongWorldPose(plane, out dest, out rot)) { return true; } return TryGetSeatPose(plane, out dest, out rot); } private static bool TryGetSeatTop(Transform seat, out Vector3 point) { //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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_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_0041: 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_0037: Unknown result type (might be due to invalid IL or missing references) point = Vector3.zero; Renderer[] componentsInChildren = ((Component)seat).GetComponentsInChildren<Renderer>(true); bool flag = false; Bounds val = default(Bounds); for (int i = 0; i < componentsInChildren.Length; i++) { if (!((Object)(object)componentsInChildren[i] == (Object)null)) { if (!flag) { val = componentsInChildren[i].bounds; flag = true; } else { ((Bounds)(ref val)).Encapsulate(componentsInChildren[i].bounds); } } } if (!flag) { return false; } point = new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).max.y, ((Bounds)(ref val)).center.z); return true; } private static void SpawnCrashedPlaneItems() { //IL_0034: 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) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_015e: Unknown result type (might be due to invalid IL or missing references) Transform val = FindNamedTransform("crashed plane"); if ((Object)(object)val == (Object)null) { return; } List<Transform> list = new List<Transform>(); GatherPlaneSpawners(val, list); Transform val2 = FindPlaneCampfire(val); if ((Object)(object)val2 != (Object)null) { PlaceSpawnersAroundFire(list, val2.position); } else { Plugin.Log.LogWarning((object)"Plane campfire not found — spawning items at their dumped spawner poses."); } Vector3 dest; Quaternion rot; bool flag = TryGetBingBongPlacePose(val, out dest, out rot); Transform val3 = FindBingBongSpawner(list); if (flag && (Object)(object)val3 != (Object)null) { val3.SetPositionAndRotation(dest, rot); Plugin.Log.LogInfo((object)$"BingBong spawner aimed at {dest}."); } Plugin.Log.LogInfo((object)"Spawning crashed-plane starter items."); int num = 0; for (int i = 0; i < list.Count; i++) { Transform val4 = list[i]; ISpawner component = ((Component)val4).GetComponent<ISpawner>(); if (component == null) { continue; } try { StripSpawnTracker(((Component)val4).gameObject); List<PhotonView> list2 = component.TrySpawnItems(); int num2 = list2?.Count ?? 0; num += num2; if (IsBingBongName(((Object)val4).name) && list2 != null) { for (int j = 0; j < list2.Count; j++) { if ((Object)(object)list2[j] != (Object)null) { _spawnedBingBong = ((Component)list2[j]).transform; break; } } } Plugin.Log.LogInfo((object)$"Plane spawner '{((Object)val4).name}' spawned {num2} item(s) at {val4.position}."); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Plane spawner '" + ((Object)val4).name + "' failed: " + ex.GetType().Name + ": " + ex.Message)); } } if (flag) { MoveBingBongItem(FindSpawnedBingBong(val), dest, rot); } Plugin.Log.LogInfo((object)$"Spawned {num} starting item(s) from the crashed plane."); } private static bool IsBingBongName(string name) { if (!string.IsNullOrEmpty(name)) { return name.IndexOf("BingBong", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static Transform FindBingBongSpawner(List<Transform> spawners) { if (spawners == null) { return null; } for (int i = 0; i < spawners.Count; i++) { if ((Object)(object)spawners[i] != (Object)null && IsBingBongName(((Object)spawners[i]).name)) { return spawners[i]; } } return null; } private static Transform FindSpawnedBingBong(Transform plane) { //IL_0021: 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_0026: 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_0082: 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) Item[] array = Object.FindObjectsByType<Item>((FindObjectsInactive)0, (FindObjectsSortMode)0); Transform val = null; float num = float.MaxValue; Vector3 val2 = (((Object)(object)plane != (Object)null) ? plane.position : Vector3.zero); foreach (Item val3 in array) { if ((Object)(object)val3 == (Object)null) { continue; } string name = ((Object)((Component)val3).gameObject).name; if (IsBingBongName(name) && name.IndexOf("Spawner", StringComparison.OrdinalIgnoreCase) < 0) { Vector3 val4 = val3.Center(); float num2 = (((Object)(object)plane != (Object)null) ? Vector3.Distance(val4, val2) : 0f); if ((Object)(object)plane != (Object)null && num2 > 40f) { Plugin.Log.LogInfo((object)$"Ignoring far BingBong '{name}' at {val4} ({num2:0.#}m from wreck)."); } else if (num2 < num) { num = num2; val = val3.transform; } } } if ((Object)(object)val != (Object)null) { _spawnedBingBong = val; } return val; } private static bool TryLoadBingBongDump(out Vector3 localPos, out Quaternion localRot) { //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_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) localPos = BingBongLocalPos; localRot = BingBongLocalRot; return true; } private static bool TryGetBingBongWorldPose(Transform plane, out Vector3 worldPos, out Quaternion worldRot) { //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_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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0040: 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) worldPos = Vector3.zero; worldRot = Quaternion.identity; if (!TryLoadBingBongDump(out var localPos, out var localRot) || (Object)(object)plane == (Object)null) { return false; } worldPos = plane.TransformPoint(localPos); worldRot = plane.rotation * localRot; return true; } private static void MoveBingBongItem(Transform bing, Vector3 dest, Quaternion rot) { //IL_000b: 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_0050: 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_002a: 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) if (!((Object)(object)bing == (Object)null)) { bing.SetPositionAndRotation(dest, rot); Rigidbody component = ((Component)bing).GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { component.position = dest; component.rotation = rot; component.linearVelocity = Vector3.zero; component.angularVelocity = Vector3.zero; } Plugin.Log.LogInfo((object)$"Moved spawned BingBong to {dest}."); } } private static void StripSpawnTracker(GameObject host) { SpawnedItemTracker component = host.GetComponent<SpawnedItemTracker>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } } private static bool IsUnderCrashedPlane(Transform t) { while ((Object)(object)t != (Object)null) { if (((Object)t).name.Equals("crashed plane", StringComparison.OrdinalIgnoreCase)) { return true; } t = t.parent; } return false; } private static void HidePlanePiece(Transform plane, string name) { Transform val = FindChildNamed(plane, name); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("Could not hide '" + name + "' — not found under crashed plane.")); return; } ((Component)val).gameObject.SetActive(false); Plugin.Log.LogInfo((object)("Hid crashed plane piece '" + name + "'.")); } private static void ApplyPlaneDumpLocals(Transform plane, List<PlaneNodeDump> dump) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) int num = 0; for (int i = 0; i < dump.Count; i++) { PlaneNodeDump planeNodeDump = dump[i]; if (!(planeNodeDump.RelPath == ".")) { Transform val = FindChildByRelativePath(plane, planeNodeDump.RelPath); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("Dump child '" + planeNodeDump.RelPath + "' not found under crashed plane.")); continue; } val.localPosition = planeNodeDump.LocalPos; val.localRotation = planeNodeDump.LocalRot; val.localScale = planeNodeDump.LocalScale; ((Component)val).gameObject.SetActive(planeNodeDump.Active); num++; } } Plugin.Log.LogInfo((object)$"Applied {num} dumped crashed-plane child pose(s)."); } private static List<Vector3> LoadPlayerSpawnDumps() { List<Vector3> list = LoadEmbeddedPlayerSpawns(); if (list.Count > 0) { Plugin.Log.LogInfo((object)$"Loaded {list.Count} baked-in player spawn(s)."); } return list; } private static List<Vector3> LoadEmbeddedPlayerSpawns() { Stream manifestResourceStream = typeof(ReverseRun).Assembly.GetManifestResourceStream("SummitToShore.PlayerDump.txt"); if (manifestResourceStream == null) { return new List<Vector3>(); } string text; using (manifestResourceStream) { using StreamReader streamReader = new StreamReader(manifestResourceStream); text = streamReader.ReadToEnd(); } return ParsePlayerSpawnLines(text.Split(new string[2] { "\r\n", "\n" }, StringSplitOptions.None)); } private static List<Vector3> ParsePlayerSpawnLines(string[] lines) { //IL_0037: 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) List<Vector3> list = new List<Vector3>(); if (lines == null) { return list; } for (int i = 0; i < lines.Length; i++) { string text = lines[i].Trim(); if (text.StartsWith("SPAWN | ", StringComparison.Ordinal) && TryParseVec3(text.Substring(8), out var value)) { list.Add(value); } } if (list.Count == 0) { for (int j = 0; j < lines.Length; j++) { string text2 = lines[j].Trim(); if (text2.StartsWith("CENTER | ", StringComparison.Ordinal) && TryParseVec3(text2.Substring(9), out var value2)) { list.Add(value2); break; } } } return list; } private static bool TryLoadEmbeddedPlaneDump(out List<PlaneNodeDump> dump, out Quaternion rootRot) { //IL_0008: 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) dump = new List<PlaneNodeDump>(); rootRot = DumpedPlaneRot; Stream manifestResourceStream = typeof(ReverseRun).Assembly.GetManifestResourceStream("SummitToShore.PlaneDump.txt"); if (manifestResourceStream == null) { Plugin.Log.LogWarning((object)"Embedded crashed-plane dump is missing from the DLL."); return false; } try { string text; using (manifestResourceStream) { using StreamReader streamReader = new StreamReader(manifestResourceStream); text = streamReader.ReadToEnd(); } return TryParsePlaneDump(text.Split(new string[2] { "\r\n", "\n" }, StringSplitOptions.None), "embedded dump", out dump, out rootRot); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not read embedded plane dump: " + ex.Message)); return false; } } private static bool TryParsePlaneDump(string[] lines, string source, out List<PlaneNodeDump> dump, out Quaternion rootRot) { //IL_0008: 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) dump = new List<PlaneNodeDump>(); rootRot = DumpedPlaneRot; bool flag = false; for (int i = 0; i < lines.Length; i++) { if (lines[i].IndexOf("dump v2", StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; break; } } if (!flag) { Plugin.Log.LogInfo((object)("Plane dump '" + source + "' is not v2. Using the baked-in layout.")); return false; } bool flag2 = false; PlaneNodeDump item = default(PlaneNodeDump); for (int j = 0; j < lines.Length; j++) { string text = lines[j].Trim(); if (text.Length == 0 || text[0] == '#') { continue; } string[] array = text.Split(new string[1] { " | " }, StringSplitOptions.None); if (array.Length == 0) { continue; } if (array[0] == "ROOT") { if (array.Length < 4 || !TryParseQuat(array[3], out rootRot)) { Plugin.Log.LogWarning((object)("Plane dump '" + source + "' has an invalid ROOT line.")); return false; } flag2 = true; continue; } if (array[0] != "CHILD" || array.Length < 6) { Plugin.Log.LogWarning((object)("Plane dump '" + source + "' has an unexpected line '" + text + "'.")); return false; } item.RelPath = array[1]; item.Active = array[2] == "1"; if (!TryParseVec3(array[3], out item.LocalPos) || !TryParseQuat(array[4], out item.LocalRot) || !TryParseVec3(array[5], out item.LocalScale)) { Plugin.Log.LogWarning((object)("Plane dump child '" + array[1] + "' has invalid numbers.")); return false; } dump.Add(item); } if (!flag2 || dump.Count == 0) { Plugin.Log.LogWarning((object)("Plane dump '" + source + "' has no ROOT/CHILD data.")); return false; } Plugin.Log.LogInfo((object)$"Loaded crashed-plane dump with {dump.Count} child pose(s) from {source}."); return true; } private static bool TryParseVec3(string text, out Vector3 value) { //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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) value = Vector3.zero; string[] array = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length != 3) { return false; } if (!float.TryParse(array[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) || !float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) || !float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3)) { return false; } value = new Vector3(result, result2, result3); return true; } private static bool TryParseQuat(string text, out Quaternion value) { //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_0086: 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) value = Quaternion.identity; string[] array = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length != 4) { return false; } if (!float.TryParse(array[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) || !float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) || !float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3) || !float.TryParse(array[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result4)) { return false; } value = new Quaternion(result, result2, result3, result4); return true; } private static void MarkPlaneCampfiresNonProgress(Transform plane) { Campfire[] componentsInChildren = ((Component)plane).GetComponentsInChildren<Campfire>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (!((Object)(object)componentsInChildren[i] == (Object)null)) { NonProgressCampfires.Add(((Object)componentsInChildren[i]).GetInstanceID()); Plugin.Log.LogInfo((object)("Plane campfire '" + ((Object)componentsInChildren[i]).name + "' will light but will not skip a biome.")); } } } private static void MoveFlareBoxToShore() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_005a: 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_0086: Unknown result type (might be due to invalid IL or missing references) if (_hasShoreAnchor && !_flareBoxMoved) { Transform val = FindPeakFlareBox(); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"Peak flare 'box' not found — flares will not sit in the crate."); return; } Vector3 position = val.position; ActivateInHierarchy(((Component)val).gameObject); val.SetParent((Transform)null, true); val.SetPositionAndRotation(_shoreAnchor, val.rotation); MoveLooseFlaresWithBox(position, _shoreAnchor); SpawnFlaresInBox(val); _flareBoxMoved = true; Plugin.Log.LogInfo((object)$"Moved flare box '{GetPath(val)}' {position} -> {_shoreAnchor}."); } } private static Transform FindPeakFlareBox() { Transform val = FindChildNamed(FindPeakPlatform(), "box"); if ((Object)(object)val != (Object)null) { return val; } for (int i = 0; i < PeakPlatformNames.Length; i++) { val = FindChildNamed(FindNamedTransform(PeakPlatformNames[i]), "box"); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static void MoveLooseFlaresWithBox(Vector3 from, Vector3 dest) { //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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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) Vector3 val = dest - from; Item[] array = Object.FindObjectsByType<Item>((FindObjectsInactive)1, (FindObjectsSortMode)0); int num = 0; foreach (Item val2 in array) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.holderCharacter != (Object)null) && ((Object)val2).name.IndexOf("Flare", StringComparison.OrdinalIgnoreCase) >= 0 && !(Vector3.Distance(val2.transform.position, from) > 20f)) { Transform transform = val2.transform; transform.position += val; num++; } } if (num > 0) { Plugin.Log.LogInfo((object)$"Moved {num} already-spawned flare(s) with the crate."); } } private static void SpawnFlaresInBox(Transform box) { if ((Object)(object)box == (Object)null || !PhotonNetwork.IsMasterClient) { return; } ISpawner[] componentsInChildren = ((Component)box).GetComponentsInChildren<ISpawner>(true); int num = 0; for (int i = 0; i < componentsInChildren.Length; i++) { if (componentsInChildren[i] == null) { continue; } try { List<PhotonView> list = componentsInChildren[i].TrySpawnItems(); if (list != null) { num += list.Count; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Flare box spawner failed: " + ex.GetType().Name + ": " + ex.Message)); } } Plugin.Log.LogInfo((object)$"Spawned {num} flare(s) in the shore crate."); } private static Vector3 GetPeakStandingPosition() { //IL_0010: 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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) bool flag = IsKilnPeakRoll(); Vector3 val = (flag ? KilnFlagStanding : CitadelFlagStanding); Plugin.Log.LogInfo((object)string.Format("Using {0} crash site {1}.", flag ? "Kiln/Caldera" : "Citadel/Gloom", val)); return val; } private static Transform FindPeakPlatform() { MapHandler instance = Singleton<MapHandler>.Instance; if ((Object)(object)instance == (Object)null || instance.segments == null) { return null; } int lastClimbIndex = GetLastClimbIndex(instance); if (lastClimbIndex < 0 || (Object)(object)instance.segments[lastClimbIndex].segmentParent == (Object)null) { return null; } return FindNamedPeakPlatform(instance.segments[lastClimbIndex].segmentParent.transform); } private static Transform FindNamedPeakPlatform(Transform parent) { if ((Object)(object)parent == (Object)null) { return null; } for (int i = 0; i < PeakPlatformNames.Length; i++) { Transform val = FindChildNamed(parent, PeakPlatformNames[i]); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static bool IsKilnPeakRoll() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 MapHandler instance = Singleton<MapHandler>.Instance; int lastClimbIndex = GetLastClimbIndex(instance); if ((Object)(object)instance == (Object)null || lastClimbIndex < 0 || instance.segments == null || lastClimbIndex >= instance.segments.Length) { return false; } MapSegment val = instance.segments[lastClimbIndex]; if (val == null) { return false; } if ((int)val.biome == 3) { return true; } if ((Object)(object)val.segmentParent != (Object)null) { return ((Object)val.segmentParent).name.IndexOf("Volcano", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static int GetLastClimbIndex(MapHandler map) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 if (map.segments == null) { return -1; } for (int num = map.segments.Length - 1; num >= 0; num--) { MapSegment val = map.segments[num]; if (val != null && !((Object)(object)val.segmentParent == (Object)null) && (byte)num != 6 && (byte)num != 5 && (int)val.biome != 17) { return num; } } return -1; } private static int GetClimbIndex(Segment segment) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected I4, but got Unknown if ((int)segment == 5) { return GetLastClimbIndex(Singleton<MapHandler>.Instance); } return (int)segment; } private static Transform