Decompiled source of HazardSpam v2.0.6
plugins/com.github.tehUsual.HazardSpam.dll
Decompiled 6 days 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.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Xml; using System.Xml.Serialization; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ConsoleTools; using ConsoleTools.Patches; using HarmonyLib; using HazardSpam.Config; using HazardSpam.Hazards; using HazardSpam.Helpers; using HazardSpam.Menu; using HazardSpam.Menu.Descriptors; using HazardSpam.Menu.Settings; using HazardSpam.Menu.TabContent; using HazardSpam.Networking; using HazardSpam.Patches; using HazardSpam.Spawning; using HazardSpam.Types; using Microsoft.CodeAnalysis; using NetGameState.Events; using NetGameState.Level; using NetGameState.Level.Helpers; using NetGameState.LevelProgression; using NetGameState.LevelStructure; using NetGameState.Listeners; using NetGameState.Logging; using NetGameState.Network; using NetGameState.Patches; using NetGameState.Tests; using NetGameState.Util; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.Serialization; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("com.github.tehUsual.HazardSpam")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.0.6.0")] [assembly: AssemblyInformationalVersion("2.0.6+d767bc216ffe9e7245bf2dc1cac43667b92202d2")] [assembly: AssemblyProduct("com.github.tehUsual.HazardSpam")] [assembly: AssemblyTitle("HazardSpam")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.0.6.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace NetGameState.Util { public enum Campfire { Shore, TropicsRoots, AlpineMesa, Caldera, PeakFlagpole } public static class TeleportHandler { private static readonly Vector3 Offset = new Vector3(0f, 10f, 0f); public static void TeleportToCampfire(Campfire campfire) { //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) if (!GameStateEvents.IsRunActive) { return; } Transform val; switch (campfire) { case Campfire.Shore: { GameObject obj2 = GameObject.Find("Map/Biome_1/Beach/Beach_Campfire/Campfire/Campfire"); val = ((obj2 != null) ? obj2.transform : null); if (val == null) { val = MapObjectRefs.CampSpawnerShore; } break; } case Campfire.TropicsRoots: if (SegmentManager.IsTropics) { GameObject obj3 = GameObject.Find("Map/Biome_2/Tropics/Jungle_Campfire/Campfire/Campfire"); val = ((obj3 != null) ? obj3.transform : null); if (val == null) { val = MapObjectRefs.CampSpawnerTropics; } } else { GameObject obj4 = GameObject.Find("Map/Biome_2/Roots/Roots_Campfire/Campfire/Campfire"); val = ((obj4 != null) ? obj4.transform : null); if (val == null) { val = MapObjectRefs.CampSpawnerRoots; } } break; case Campfire.AlpineMesa: if (SegmentManager.IsAlpine) { GameObject obj5 = GameObject.Find("Map/Biome_3/Alpine/Snow_Campfire/Campfire/Campfire"); val = ((obj5 != null) ? obj5.transform : null); if (val == null) { val = MapObjectRefs.CampSpawnerAlpine; } } else { GameObject obj6 = GameObject.Find("Map/Biome_3/Mesa/Desert_Campfire/Snow_Campfire/Campfire/Campfire"); val = ((obj6 != null) ? obj6.transform : null); if (val == null) { val = MapObjectRefs.CampSpawnerMesa; } } break; case Campfire.Caldera: { GameObject obj7 = GameObject.Find("Map/Biome_4/Volcano/Volcano_Campfire/Campfire/Campfire-Kiln"); val = ((obj7 != null) ? obj7.transform : null); if (val == null) { val = MapObjectRefs.CampSpawnerCaldera; } break; } case Campfire.PeakFlagpole: { GameObject obj = GameObject.Find("Map/Biome_4/Volcano/Peak/Flag_planted_seagull/Flag Pole"); val = ((obj != null) ? obj.transform : null); break; } default: throw new ArgumentOutOfRangeException("campfire", campfire, null); } if (val == null) { return; } foreach (Character allPlayerCharacter in PlayerHandler.GetAllPlayerCharacters()) { ((MonoBehaviourPun)allPlayerCharacter).photonView.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { val.position + Offset, false }); } } } } namespace NetGameState.Tests { internal static class CallbackTests { internal static void Init(bool all = false) { GameStateEvents.OnPlayOfflineClicked += OnPlayOfflineClicked; GameStateEvents.OnPlayerEnteredRoom += OnPlayerEnteredRoom; GameStateEvents.OnPlayerLeftRoom += OnPlayerLeftRoom; GameStateEvents.OnSelfCreateLobby += OnSelfCreateLobby; GameStateEvents.OnSelfJoinLobby += OnSelfJoinLobby; GameStateEvents.OnSelfLeaveLobby += OnSelfLeaveLobby; GameStateEvents.OnPlayerRegistered += OnPlayerRegistered; GameStateEvents.OnPlayerUnregistered += OnPlayerUnregistered; GameStateEvents.OnAirportLoaded += OnAirportLoaded; GameStateEvents.OnRunStartLoading += OnRunStartLoading; if (all) { GameStateEvents.OnLocalPlayerReady += OnLocalPlayerReady; } GameStateEvents.OnPlayerReady += OnPlayerReady; GameStateEvents.OnAllPlayersReady += OnAllPlayersReady; GameStateEvents.OnRunStartLoadComplete += OnRunStartLoadComplete; SegmentManager.OnSegmentLoading += OnSegmentLoading; SegmentManager.OnSegmentLoadComplete += OnSegmentLoadComplete; } internal static void Reset() { GameStateEvents.OnPlayOfflineClicked -= OnPlayOfflineClicked; GameStateEvents.OnPlayerEnteredRoom -= OnPlayerEnteredRoom; GameStateEvents.OnPlayerLeftRoom -= OnPlayerLeftRoom; GameStateEvents.OnSelfCreateLobby -= OnSelfCreateLobby; GameStateEvents.OnSelfJoinLobby -= OnSelfJoinLobby; GameStateEvents.OnSelfLeaveLobby -= OnSelfLeaveLobby; GameStateEvents.OnPlayerRegistered -= OnPlayerRegistered; GameStateEvents.OnPlayerUnregistered -= OnPlayerUnregistered; GameStateEvents.OnAirportLoaded -= OnAirportLoaded; GameStateEvents.OnRunStartLoading -= OnRunStartLoading; GameStateEvents.OnLocalPlayerReady += OnLocalPlayerReady; GameStateEvents.OnPlayerReady -= OnPlayerReady; GameStateEvents.OnAllPlayersReady -= OnAllPlayersReady; GameStateEvents.OnRunStartLoadComplete -= OnRunStartLoadComplete; SegmentManager.OnSegmentLoading -= OnSegmentLoading; SegmentManager.OnSegmentLoadComplete -= OnSegmentLoadComplete; } private static void OnPlayOfflineClicked() { LogProvider.Log?.LogColor("Play 'offline' clicked."); } private static void OnPlayerEnteredRoom(Player player) { LogProvider.Log?.LogColor($"Player '{player.NickName}' with actor number {player.ActorNumber} entered the room."); } private static void OnPlayerLeftRoom(Player player) { LogProvider.Log?.LogColor($"Player '{player.NickName}' with actor number {player.ActorNumber} left the room."); } private static void OnSelfCreateLobby() { LogProvider.Log?.LogColor("Local player created lobby."); } private static void OnSelfJoinLobby() { LogProvider.Log?.LogColor("Local player joined lobby."); } private static void OnSelfLeaveLobby() { LogProvider.Log?.LogColor("Local player left lobby."); } private static void OnPlayerRegistered(Player player) { LogProvider.Log?.LogColor($"Player '{player.view.Owner.NickName}' with actor number {((MonoBehaviourPun)player).photonView.Owner.ActorNumber} registered."); } private static void OnPlayerUnregistered(Player player) { LogProvider.Log?.LogColor($"Player '{player.view.Owner.NickName}' with actor number {((MonoBehaviourPun)player).photonView.Owner.ActorNumber} unregistered."); } private static void OnRunStartLoading(string sceneName, int ascent) { LogProvider.Log?.LogColor($"Scene {sceneName} is loading. Ascent: {ascent}"); } private static void OnLocalPlayerReady() { LogProvider.Log?.LogColor("Local player '" + Player.localPlayer.view.Owner.NickName + "' is ready!"); } private static void OnPlayerReady(Player player) { LogProvider.Log?.LogColor("Player '" + player.view.Owner.NickName + "' is ready!"); } private static void OnAllPlayersReady() { LogProvider.Log?.LogColor("All players are ready!"); Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val in playerList) { Player player = PlayerHandler.GetPlayer(val); LogProvider.Log?.LogColor($" - '{player.view.Owner.NickName}' has actor number {((MonoBehaviourPun)player).photonView.Owner.ActorNumber}"); } } private static void OnRunStartLoadComplete(string sceneName, int ascent) { LogProvider.Log?.LogColor($"Scene {sceneName} is loaded. Ascent: {ascent}"); for (int i = 0; i < SegmentManager.CurrentRunSegments.Length; i++) { SegmentManager.SegmentInfo segmentInfo = SegmentManager.CurrentRunSegments[i]; LogProvider.Log?.LogColorS($"Segment [{i + 1}] is: [{segmentInfo.Chapter.ToString()}.{segmentInfo.Zone.ToString()}.{segmentInfo.SubZone.ToString()}]"); } } private static void OnAirportLoaded() { LogProvider.Log?.LogColor("Lobby (airport) is loaded."); } private static void OnSegmentLoading(SegmentManager.SegmentInfo prevSeg, SegmentManager.SegmentInfo nextSeg) { LogProvider.Log?.LogColor("Segment loading: [" + prevSeg.Chapter.ToString() + "." + prevSeg.Zone.ToString() + "." + prevSeg.SubZone.ToString() + "] -> [" + nextSeg.Chapter.ToString() + "." + nextSeg.Zone.ToString() + "." + nextSeg.SubZone.ToString() + "]"); } private static void OnSegmentLoadComplete(SegmentManager.SegmentInfo seg) { LogProvider.Log?.LogColor("Segment loaded: [" + seg.Chapter.ToString() + "." + seg.Zone.ToString() + "." + seg.SubZone.ToString() + "]"); } } } namespace NetGameState.Patches { [HarmonyPatch(typeof(AirportCheckInKiosk))] public static class AirportCheckInPatches { [HarmonyPatch("BeginIslandLoadRPC")] private static void Prefix(AirportCheckInKiosk __instance, string sceneName, int ascent) { GameStateEvents.RaiseOnStartLoading(sceneName, ascent); } } [HarmonyPatch(typeof(LoadingScreenHandler))] public static class LoadScenePatches { [CompilerGenerated] private sealed class <TrackLocalPlayerReady>d__1 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator original; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <TrackLocalPlayerReady>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; goto IL_0045; case 1: <>1__state = -1; goto IL_0045; case 2: { <>1__state = -1; break; } IL_0045: if (original.MoveNext()) { <>2__current = original.Current; <>1__state = 1; return true; } break; } if (!Object.op_Implicit((Object)(object)Character.localCharacter) || !PhotonNetwork.IsMessageQueueRunning) { <>2__current = null; <>1__state = 2; return true; } GameStateEvents.RaiseOnLocalPlayerReady(); Object.FindFirstObjectByType<PlayerReadyTracker>()?.Send_SetPlayerReady(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPatch("LoadSceneProcessNetworked")] private static void Postfix(IEnumerator __result, LoadingScreenHandler __instance, string sceneName, bool yieldForCharacterSpawn, float extraYieldTimeOnEnd) { ((MonoBehaviour)__instance).StartCoroutine(TrackLocalPlayerReady(__result, sceneName)); } [IteratorStateMachine(typeof(<TrackLocalPlayerReady>d__1))] private static IEnumerator TrackLocalPlayerReady(IEnumerator original, string sceneName) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <TrackLocalPlayerReady>d__1(0) { original = original }; } } [HarmonyPatch(typeof(MainMenu))] public static class MainMenuPatches { [HarmonyPatch("PlaySoloClicked")] private static void Postfix(MainMenu __instance) { GameStateEvents.RaiseOnPlayOfflineClicked(); } } [HarmonyPatch(typeof(MapHandler))] public static class MapHandlerPatches { [HarmonyPatch("GoToSegment")] private static void Prefix(MapHandler __instance, Segment s) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) SegmentManager.SetCurrentSegment(s); } } [HarmonyPatch(typeof(MountainProgressHandler))] public static class MountainProgressHandlerPatches { [HarmonyPatch("SetSegmentComplete")] private static void Postfix(MountainProgressHandler __instance, int segment) { SegmentManager.RaiseOnSegmentLoadComplete(); } } [HarmonyPatch(typeof(PlayerHandler))] public static class PlayerHandlerPatches { [HarmonyPatch("RegisterPlayer")] private static void Postfix(PlayerHandler __instance, Player player) { GameStateEvents.RaiseOnPlayerRegistered(player); } } [HarmonyPatch(typeof(RunManager))] public static class RunManagerPatches { [HarmonyPatch("Start")] private static void Prefix(RunManager __instance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); string text = ((Scene)(ref activeScene)).name.ToLower(); if (text.StartsWith("airport")) { GameStateEvents.RaiseOnAirportLoaded(); } if (text.StartsWith("level_") || text.StartsWith("wilisland")) { GameStateEvents.RaiseOnRunLoadComplete(); } } } [HarmonyPatch(typeof(SteamLobbyHandler))] public static class SteamLobbyHandlerPatches { [HarmonyPostfix] [HarmonyPatch("OnLobbyCreated")] private static void Postfix_OnLobbyCreated(SteamLobbyHandler __instance) { GameStateEvents.RaiseOnSelfCreateLobby(); } [HarmonyPostfix] [HarmonyPatch("OnLobbyEnter")] private static void Postfix_OnLobbyEnter(SteamLobbyHandler __instance) { GameStateEvents.RaiseOnSelfJoinLobby(); } [HarmonyPrefix] [HarmonyPatch("LeaveLobby")] private static void Prefix_LeaveLobby(SteamLobbyHandler __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (__instance.LobbySteamId.m_SteamID != 0L) { GameStateEvents.RaiseOnSelfLeaveLobby(); } } } } namespace NetGameState.Network { public class PlayerReadyTracker : MonoBehaviourPun { private readonly HashSet<int> _readyPlayers = new HashSet<int>(); private readonly Dictionary<int, float> _loadStartTimes = new Dictionary<int, float>(); private const float TimeoutSeconds = 15f; private bool _allIsReady; private bool _waitForAllReady; public static PlayerReadyTracker Instance { get; private set; } private void Awake() { if (Instance != null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } private void OnEnable() { GameStateEvents.OnRunStartLoading += OnRunStartLoading; ResetTracking(waitForAll: false); } private void OnDisable() { GameStateEvents.OnRunStartLoading -= OnRunStartLoading; } private void OnDestroy() { GameStateEvents.OnRunStartLoading -= OnRunStartLoading; } private void OnRunStartLoading(string sceneName, int ascent) { ResetTracking(waitForAll: true); } private void ResetTracking(bool waitForAll) { if (waitForAll) { LogProvider.Log?.LogColor("Player ready tracker waiting for all players to be ready."); } else { LogProvider.Log?.LogColor("Player ready tracker reset"); } _readyPlayers.Clear(); _loadStartTimes.Clear(); _allIsReady = false; _waitForAllReady = waitForAll; } internal void Send_SetPlayerReady() { ((MonoBehaviourPun)this).photonView.RPC("RPC_NGS_SetPlayerReady", (RpcTarget)3, new object[1] { PhotonNetwork.LocalPlayer.ActorNumber }); if (!PhotonNetwork.IsMasterClient) { ((Behaviour)this).enabled = false; } } [PunRPC] public void RPC_NGS_SetPlayerReady(int actorNumber, PhotonMessageInfo info) { if (!PhotonNetwork.IsMasterClient || !_readyPlayers.Add(actorNumber)) { return; } Player player = default(Player); if (PlayerHandler.TryGetPlayer(actorNumber, ref player)) { _loadStartTimes.Remove(actorNumber); GameStateEvents.RaiseOnPlayerReady(player); if (_readyPlayers.Count == PhotonNetwork.PlayerList.Length) { _allIsReady = true; _waitForAllReady = false; GameStateEvents.RaiseOnAllPlayersReady(); ((Behaviour)this).enabled = false; } } else { LogProvider.Log?.LogColorW($"Could not find player with actor number {actorNumber}"); } } private void Update() { if (_allIsReady || !PhotonNetwork.IsMasterClient || !PhotonNetwork.InRoom || !_waitForAllReady) { return; } Player[] playerList = PhotonNetwork.PlayerList; Player player = default(Player); foreach (Player val in playerList) { if (_readyPlayers.Contains(val.ActorNumber)) { continue; } if (!_loadStartTimes.ContainsKey(val.ActorNumber)) { _loadStartTimes[val.ActorNumber] = Time.realtimeSinceStartup; } if (Time.realtimeSinceStartup - _loadStartTimes[val.ActorNumber] > 15f) { if (PlayerHandler.TryGetPlayer(val.ActorNumber, ref player)) { _waitForAllReady = false; GameStateEvents.RaiseOnPlayerLoadTimeout(player); ((Behaviour)this).enabled = false; } else { LogProvider.Log?.LogColorW($"Could not resolve PlayerHandler for actor number {val.ActorNumber}"); } _loadStartTimes[val.ActorNumber] = float.MaxValue; } } } } } namespace NetGameState.Logging { public static class LogProvider { public static ManualLogSource? Log { get; set; } } } namespace NetGameState.Listeners { public class PhotonCallbacks : MonoBehaviourPunCallbacks { public override void OnPlayerEnteredRoom(Player newPlayer) { GameStateEvents.RaiseOnPlayerEnteredRoom(newPlayer); } public override void OnPlayerLeftRoom(Player otherPlayer) { GameStateEvents.RaiseOnPlayerLeftRoom(otherPlayer); Player player = default(Player); if (PlayerHandler.TryGetPlayer(otherPlayer.ActorNumber, ref player)) { GameStateEvents.RaiseOnPlayerUnregistered(player); } } } } namespace NetGameState.Level { public enum Chapter { Unknown = -1, One, Two, Three, Four, Five, Six } public static class ChapterExtensions { public static Chapter Start => (from Chapter c in Enum.GetValues(typeof(Chapter)) where c != Chapter.Unknown select c).Min(); public static Chapter End => Enum.GetValues(typeof(Chapter)).Cast<Chapter>().Max(); } public enum SubZone { Unknown = -1, Any = 0, Shore_Default = 10, Shore_SnakeBeach = 11, Shore_RedBeach = 12, Shore_BlueBeach = 13, Shore_JellyHell = 14, Shore_BlackSand = 15, Tropics_Default = 30, Tropics_Lava = 31, Tropics_Pillars = 32, Tropics_Thorny = 33, Tropics_Bombs = 34, Tropics_Ivy = 35, Tropics_SkyJungle = 36, Roots_Default = 40, Alpine_Default = 50, Alpine_Lava = 51, Alpine_Spiky = 52, Alpine_GeyserHell = 53, Mesa_Default = 70, Caldera_Default = 90, Kiln_Default = 110, Peak_Default = 130 } public enum ShoreZone { Unknown = -1, Any = 0, Default = 10, SnakeBeach = 11, RedBeach = 12, BlueBeach = 13, JellyHell = 14, BlackSand = 15 } public enum TropicsZone { Unknown = -1, Any = 0, Default = 30, Lava = 31, Pillars = 32, Thorny = 33, Bombs = 34, Ivy = 35, SkyJungle = 36 } public enum RootsZone { Unknown = -1, Any = 0, Default = 40 } public enum AlpineZone { Unknown = -1, Any = 0, Default = 50, Lava = 51, Spiky = 52, GeyserHell = 53 } public enum MesaZone { Unknown = -1, Any = 0, Default = 70 } public enum CalderaZone { Unknown = -1, Any = 0, Default = 90 } public enum KilnZone { Unknown = -1, Any = 0, Default = 110 } public enum PeakZone { Unknown = -1, Any = 0, Default = 130 } public enum Zone { Unknown = -1, Any, Shore, Tropics, Roots, Alpine, Mesa, Caldera, Kiln, Peak } } namespace NetGameState.Level.Helpers { public static class SegmentMapper { public static Chapter GetChapterFromSegment(Segment segment) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected I4, but got Unknown return (int)segment switch { 0 => Chapter.One, 1 => Chapter.Two, 2 => Chapter.Three, 3 => Chapter.Four, 4 => Chapter.Five, 5 => Chapter.Six, _ => Chapter.Unknown, }; } public static bool TryGetSegmentFromChapter(Chapter chapter, out Segment? segment) { switch (chapter) { case Chapter.One: segment = (Segment)0; return true; case Chapter.Two: segment = (Segment)1; return true; case Chapter.Three: segment = (Segment)2; return true; case Chapter.Four: segment = (Segment)3; return true; case Chapter.Five: segment = (Segment)4; return true; case Chapter.Six: segment = (Segment)5; return true; default: segment = null; return false; } } public static Zone GetZoneFromChapter(Chapter chapter) { switch (chapter) { case Chapter.One: return Zone.Shore; case Chapter.Two: { Transform? bioTropics = MapObjectRefs.BioTropics; if (bioTropics != null && ((Component)bioTropics).gameObject.activeSelf) { return Zone.Tropics; } Transform? bioRoots = MapObjectRefs.BioRoots; if (bioRoots != null && ((Component)bioRoots).gameObject.activeSelf) { return Zone.Roots; } break; } case Chapter.Three: { Transform? bioAlpine = MapObjectRefs.BioAlpine; if (bioAlpine != null && ((Component)bioAlpine).gameObject.activeSelf) { return Zone.Alpine; } Transform? bioMesa = MapObjectRefs.BioMesa; if (bioMesa != null && ((Component)bioMesa).gameObject.activeSelf) { return Zone.Mesa; } break; } case Chapter.Four: return Zone.Caldera; case Chapter.Five: return Zone.Kiln; case Chapter.Six: return Zone.Peak; } return Zone.Unknown; } public static Chapter GetChapterFromZone(Zone zone) { return zone switch { Zone.Shore => Chapter.One, Zone.Tropics => Chapter.Two, Zone.Roots => Chapter.Two, Zone.Alpine => Chapter.Three, Zone.Mesa => Chapter.Three, Zone.Caldera => Chapter.Four, Zone.Kiln => Chapter.Five, Zone.Peak => Chapter.Six, _ => Chapter.Unknown, }; } public static bool TryGetBiomeTypeFromZone(Zone zone, out BiomeType? biomeType) { switch (zone) { case Zone.Shore: biomeType = (BiomeType)0; return true; case Zone.Tropics: biomeType = (BiomeType)1; return true; case Zone.Roots: biomeType = (BiomeType)7; return true; case Zone.Alpine: biomeType = (BiomeType)2; return true; case Zone.Mesa: biomeType = (BiomeType)6; return true; case Zone.Caldera: biomeType = (BiomeType)3; return true; case Zone.Kiln: biomeType = (BiomeType)3; return true; case Zone.Peak: biomeType = (BiomeType)5; return true; default: biomeType = null; return false; } } private static SubZone GetActiveSubZone<T>(Transform? root, T[] subZones, string zoneName) { if (root == null) { LogProvider.Log?.LogColorW("Could not find '" + zoneName + "' Segment"); return SubZone.Unknown; } for (int i = 0; i < subZones.Length; i++) { T val = subZones[i]; Transform obj = root.Find(val?.ToString()); if (obj != null && ((Component)obj).gameObject.activeSelf) { return (SubZone)Convert.ToInt32(val); } } LogProvider.Log?.LogColorW("Could not find sub-zone for '" + zoneName + "'"); return SubZone.Unknown; } public static SubZone GetSubZoneFromZone(Zone zone) { return zone switch { Zone.Shore => GetActiveSubZone(MapObjectRefs.SegShore, SubZoneHelper.ShoreSubZones, "Shore"), Zone.Tropics => GetActiveSubZone(MapObjectRefs.SegTropics, SubZoneHelper.TropicsSubZones, "Tropics"), Zone.Roots => SubZone.Roots_Default, Zone.Alpine => GetActiveSubZone(MapObjectRefs.SegAlpine, SubZoneHelper.AlpineSubZones, "Alpine"), Zone.Mesa => SubZone.Mesa_Default, Zone.Caldera => SubZone.Caldera_Default, Zone.Kiln => SubZone.Kiln_Default, Zone.Peak => SubZone.Peak_Default, _ => SubZone.Unknown, }; } public static Zone GetZoneFromSubZone(SubZone subZone) { if ((uint)(subZone - -1) <= 1u) { return Zone.Unknown; } switch (subZone) { case SubZone.Shore_Default: case SubZone.Shore_SnakeBeach: case SubZone.Shore_RedBeach: case SubZone.Shore_BlueBeach: case SubZone.Shore_JellyHell: case SubZone.Shore_BlackSand: case (SubZone)16: case (SubZone)17: case (SubZone)18: case (SubZone)19: case (SubZone)20: case (SubZone)21: case (SubZone)22: case (SubZone)23: case (SubZone)24: case (SubZone)25: case (SubZone)26: case (SubZone)27: case (SubZone)28: case (SubZone)29: if (Enum.IsDefined(typeof(SubZone), subZone)) { return Zone.Shore; } break; case SubZone.Tropics_Default: case SubZone.Tropics_Lava: case SubZone.Tropics_Pillars: case SubZone.Tropics_Thorny: case SubZone.Tropics_Bombs: case SubZone.Tropics_Ivy: case SubZone.Tropics_SkyJungle: case (SubZone)37: case (SubZone)38: case (SubZone)39: if (Enum.IsDefined(typeof(SubZone), subZone)) { return Zone.Tropics; } break; case SubZone.Roots_Default: case (SubZone)41: case (SubZone)42: case (SubZone)43: case (SubZone)44: case (SubZone)45: case (SubZone)46: case (SubZone)47: case (SubZone)48: case (SubZone)49: if (Enum.IsDefined(typeof(SubZone), subZone)) { return Zone.Roots; } break; case SubZone.Alpine_Default: case SubZone.Alpine_Lava: case SubZone.Alpine_Spiky: case SubZone.Alpine_GeyserHell: case (SubZone)54: case (SubZone)55: case (SubZone)56: case (SubZone)57: case (SubZone)58: case (SubZone)59: case (SubZone)60: case (SubZone)61: case (SubZone)62: case (SubZone)63: case (SubZone)64: case (SubZone)65: case (SubZone)66: case (SubZone)67: case (SubZone)68: case (SubZone)69: if (Enum.IsDefined(typeof(SubZone), subZone)) { return Zone.Alpine; } break; case SubZone.Mesa_Default: case (SubZone)71: case (SubZone)72: case (SubZone)73: case (SubZone)74: case (SubZone)75: case (SubZone)76: case (SubZone)77: case (SubZone)78: case (SubZone)79: case (SubZone)80: case (SubZone)81: case (SubZone)82: case (SubZone)83: case (SubZone)84: case (SubZone)85: case (SubZone)86: case (SubZone)87: case (SubZone)88: case (SubZone)89: if (Enum.IsDefined(typeof(SubZone), subZone)) { return Zone.Mesa; } break; case SubZone.Caldera_Default: case (SubZone)91: case (SubZone)92: case (SubZone)93: case (SubZone)94: case (SubZone)95: case (SubZone)96: case (SubZone)97: case (SubZone)98: case (SubZone)99: case (SubZone)100: case (SubZone)101: case (SubZone)102: case (SubZone)103: case (SubZone)104: case (SubZone)105: case (SubZone)106: case (SubZone)107: case (SubZone)108: case (SubZone)109: if (Enum.IsDefined(typeof(SubZone), subZone)) { return Zone.Kiln; } break; case SubZone.Kiln_Default: case (SubZone)111: case (SubZone)112: case (SubZone)113: case (SubZone)114: case (SubZone)115: case (SubZone)116: case (SubZone)117: case (SubZone)118: case (SubZone)119: case (SubZone)120: case (SubZone)121: case (SubZone)122: case (SubZone)123: case (SubZone)124: case (SubZone)125: case (SubZone)126: case (SubZone)127: case (SubZone)128: case (SubZone)129: if (Enum.IsDefined(typeof(SubZone), subZone)) { return Zone.Peak; } break; } return Zone.Unknown; } public static string SubZoneToExactString(Zone zone, SubZone subZone) { switch (zone) { case Zone.Shore: { ShoreZone shoreZone = (ShoreZone)subZone; return shoreZone.ToString(); } case Zone.Tropics: { TropicsZone tropicsZone = (TropicsZone)subZone; return tropicsZone.ToString(); } case Zone.Roots: { RootsZone rootsZone = (RootsZone)subZone; return rootsZone.ToString(); } case Zone.Alpine: { AlpineZone alpineZone = (AlpineZone)subZone; return alpineZone.ToString(); } case Zone.Mesa: { MesaZone mesaZone = (MesaZone)subZone; return mesaZone.ToString(); } case Zone.Caldera: { CalderaZone calderaZone = (CalderaZone)subZone; return calderaZone.ToString(); } case Zone.Kiln: { KilnZone kilnZone = (KilnZone)subZone; return kilnZone.ToString(); } case Zone.Peak: { PeakZone peakZone = (PeakZone)subZone; return peakZone.ToString(); } default: return subZone.ToString(); } } } public static class SubZoneHelper { public static readonly ShoreZone[] ShoreSubZones = (from ShoreZone v in Enum.GetValues(typeof(ShoreZone)) where v != ShoreZone.Unknown && v != ShoreZone.Any select v).ToArray(); public static readonly TropicsZone[] TropicsSubZones = (from TropicsZone v in Enum.GetValues(typeof(TropicsZone)) where v != TropicsZone.Unknown && v != TropicsZone.Any select v).ToArray(); public static readonly AlpineZone[] AlpineSubZones = (from AlpineZone v in Enum.GetValues(typeof(AlpineZone)) where v != AlpineZone.Unknown && v != AlpineZone.Any select v).ToArray(); } } namespace NetGameState.LevelStructure { public static class MapObjectPaths { public const string MapRoot = "Map"; private const string Biome1 = "Map/Biome_1"; private const string Biome2 = "Map/Biome_2"; private const string Biome3 = "Map/Biome_3"; private const string Biome4 = "Map/Biome_4"; public const string BioShore = "Map/Biome_1/Beach"; public const string BioTropics = "Map/Biome_2/Tropics"; public const string BioRoots = "Map/Biome_2/Roots"; public const string BioAlpine = "Map/Biome_3/Alpine"; public const string BioMesa = "Map/Biome_3/Mesa"; public const string BioVolcano = "Map/Biome_4/Volcano"; public const string SegShore = "Map/Biome_1/Beach/Beach_Segment"; public const string SegTropics = "Map/Biome_2/Tropics/Jungle_Segment"; public const string SegRoots = "Map/Biome_2/Roots/Roots Segment"; public const string SegAlpine = "Map/Biome_3/Alpine/Snow_Segment"; public const string SegMesa = "Map/Biome_3/Mesa/Desert_Segment"; public const string SegCaldera = "Map/Biome_4/Volcano/Caldera_Segment"; public const string SegKiln = "Map/Biome_4/Volcano/Volcano_Segment"; public const string SegPeak = "Map/Biome_4/Volcano/Peak"; public const string CampAreaShore = "Map/Biome_1/Beach/Beach_Campfire"; public const string CampAreaTropics = "Map/Biome_2/Tropics/Jungle_Campfire"; public const string CampAreaRoots = "Map/Biome_2/Roots/Roots_Campfire"; public const string CampAreaAlpine = "Map/Biome_3/Alpine/Snow_Campfire"; public const string CampAreaMesa = "Map/Biome_3/Mesa/Desert_Campfire/Snow_Campfire"; public const string CampAreaCaldera = "Map/Biome_4/Volcano/Volcano_Campfire"; public const string CampSpawnerShore = "Map/Biome_1/Beach/Beach_Campfire/Campfire"; public const string CampSpawnerTropics = "Map/Biome_2/Tropics/Jungle_Campfire/Campfire"; public const string CampSpawnerRoots = "Map/Biome_2/Roots/Roots_Campfire/Campfire"; public const string CampSpawnerAlpine = "Map/Biome_3/Alpine/Snow_Campfire/Campfire"; public const string CampSpawnerMesa = "Map/Biome_3/Mesa/Desert_Campfire/Snow_Campfire/Campfire"; public const string CampSpawnerCaldera = "Map/Biome_4/Volcano/Volcano_Campfire/Campfire"; public const string CampfireShore = "Map/Biome_1/Beach/Beach_Campfire/Campfire/Campfire"; public const string CampfireTropics = "Map/Biome_2/Tropics/Jungle_Campfire/Campfire/Campfire"; public const string CampfireRoots = "Map/Biome_2/Roots/Roots_Campfire/Campfire/Campfire"; public const string CampfireAlpine = "Map/Biome_3/Alpine/Snow_Campfire/Campfire/Campfire"; public const string CampfireMesa = "Map/Biome_3/Mesa/Desert_Campfire/Snow_Campfire/Campfire/Campfire"; public const string CampfireCaldera = "Map/Biome_4/Volcano/Volcano_Campfire/Campfire/Campfire-Kiln"; public const string SubBioShoreDefault = "Map/Biome_1/Beach/Beach_Segment/Default"; public const string SubBioShoreSnakeBeach = "Map/Biome_1/Beach/Beach_Segment/SnakeBeach"; public const string SubBioShoreRedBeach = "Map/Biome_1/Beach/Beach_Segment/RedBeach"; public const string SubBioShoreBlueBeach = "Map/Biome_1/Beach/Beach_Segment/BlueBeach"; public const string SubBioShoreJellyHell = "Map/Biome_1/Beach/Beach_Segment/JellyHell"; public const string SubBioShoreBlackSand = "Map/Biome_1/Beach/Beach_Segment/BlackSand"; public const string SubBioTropicsDefault = "Map/Biome_2/Tropics/Jungle_Segment/Default"; public const string SubBioTropicsLava = "Map/Biome_2/Tropics/Jungle_Segment/Lava"; public const string SubBioTropicsPillars = "Map/Biome_2/Tropics/Jungle_Segment/Pillars"; public const string SubBioTropicsThorny = "Map/Biome_2/Tropics/Jungle_Segment/Thorny"; public const string SubBioTropicsBombs = "Map/Biome_2/Tropics/Jungle_Segment/Bombs"; public const string SubBioTropicsIvy = "Map/Biome_2/Tropics/Jungle_Segment/Ivy"; public const string SubBioTropicsSkyJungle = "Map/Biome_2/Tropics/Jungle_Segment/SkyJungle"; public const string SubBioAlpineDefault = "Map/Biome_3/Alpine/Snow_Segment/Default"; public const string SubBioAlpineLava = "Map/Biome_3/Alpine/Snow_Segment/Lava"; public const string SubBioAlpineSpiky = "Map/Biome_3/Alpine/Snow_Segment/Spiky"; public const string SubBioAlpineGeyserHell = "Map/Biome_3/Alpine/Snow_Segment/GeyserHell"; public const string PeakFlagPole = "Map/Biome_4/Volcano/Peak/Flag_planted_seagull/Flag Pole"; public static bool TryGetBiomeRoot(Zone biome, out string biomeRoot) { switch (biome) { case Zone.Shore: biomeRoot = "Map/Biome_1/Beach"; return true; case Zone.Tropics: biomeRoot = "Map/Biome_2/Tropics"; return true; case Zone.Roots: biomeRoot = "Map/Biome_2/Roots"; return true; case Zone.Alpine: biomeRoot = "Map/Biome_3/Alpine"; return true; case Zone.Mesa: biomeRoot = "Map/Biome_3/Mesa"; return true; case Zone.Caldera: biomeRoot = "Map/Biome_4/Volcano"; return true; case Zone.Kiln: biomeRoot = "Map/Biome_4/Volcano"; return true; case Zone.Peak: biomeRoot = "Map/Biome_4/Volcano"; return true; default: biomeRoot = ""; return false; } } public static bool TryGetSegmentRoot(Zone biome, out string segmentRoot) { switch (biome) { case Zone.Shore: segmentRoot = "Map/Biome_1/Beach/Beach_Segment"; return true; case Zone.Tropics: segmentRoot = "Map/Biome_2/Tropics/Jungle_Segment"; return true; case Zone.Roots: segmentRoot = "Map/Biome_2/Roots/Roots Segment"; return true; case Zone.Alpine: segmentRoot = "Map/Biome_3/Alpine/Snow_Segment"; return true; case Zone.Mesa: segmentRoot = "Map/Biome_3/Mesa/Desert_Segment"; return true; case Zone.Caldera: segmentRoot = "Map/Biome_4/Volcano/Caldera_Segment"; return true; case Zone.Kiln: segmentRoot = "Map/Biome_4/Volcano/Volcano_Segment"; return true; case Zone.Peak: segmentRoot = "Map/Biome_4/Volcano/Peak"; return true; default: segmentRoot = ""; return false; } } public static bool TryGetCampAreaRoot(Zone zone, out string campAreaRoot) { switch (zone) { case Zone.Shore: campAreaRoot = "Map/Biome_1/Beach/Beach_Campfire"; return true; case Zone.Tropics: campAreaRoot = "Map/Biome_2/Tropics/Jungle_Campfire"; return true; case Zone.Roots: campAreaRoot = "Map/Biome_2/Roots/Roots_Campfire"; return true; case Zone.Alpine: campAreaRoot = "Map/Biome_3/Alpine/Snow_Campfire"; return true; case Zone.Mesa: campAreaRoot = "Map/Biome_3/Mesa/Desert_Campfire/Snow_Campfire"; return true; case Zone.Caldera: campAreaRoot = "Map/Biome_4/Volcano/Volcano_Campfire"; return true; default: campAreaRoot = ""; return false; } } public static bool TryGetCampSpawnerRoot(Zone zone, out string campfireSpawnerRoot) { switch (zone) { case Zone.Shore: campfireSpawnerRoot = "Map/Biome_1/Beach/Beach_Campfire/Campfire"; return true; case Zone.Tropics: campfireSpawnerRoot = "Map/Biome_2/Tropics/Jungle_Campfire/Campfire"; return true; case Zone.Roots: campfireSpawnerRoot = "Map/Biome_2/Roots/Roots_Campfire/Campfire"; return true; case Zone.Alpine: campfireSpawnerRoot = "Map/Biome_3/Alpine/Snow_Campfire/Campfire"; return true; case Zone.Mesa: campfireSpawnerRoot = "Map/Biome_3/Mesa/Desert_Campfire/Snow_Campfire/Campfire"; return true; case Zone.Caldera: campfireSpawnerRoot = "Map/Biome_4/Volcano/Volcano_Campfire/Campfire"; return true; default: campfireSpawnerRoot = ""; return false; } } public static bool TryGetCampfireRoot(Zone zone, out string campfireRoot) { switch (zone) { case Zone.Shore: campfireRoot = "Map/Biome_1/Beach/Beach_Campfire/Campfire/Campfire"; return true; case Zone.Tropics: campfireRoot = "Map/Biome_2/Tropics/Jungle_Campfire/Campfire/Campfire"; return true; case Zone.Roots: campfireRoot = "Map/Biome_2/Roots/Roots_Campfire/Campfire/Campfire"; return true; case Zone.Alpine: campfireRoot = "Map/Biome_3/Alpine/Snow_Campfire/Campfire/Campfire"; return true; case Zone.Mesa: campfireRoot = "Map/Biome_3/Mesa/Desert_Campfire/Snow_Campfire/Campfire/Campfire"; return true; case Zone.Caldera: campfireRoot = "Map/Biome_4/Volcano/Volcano_Campfire/Campfire/Campfire-Kiln"; return true; default: campfireRoot = ""; return false; } } public static bool TryGetSubZoneRoot(SubZone subZone, out string subZoneRoot) { switch (subZone) { case SubZone.Shore_Default: subZoneRoot = "Map/Biome_1/Beach/Beach_Segment/Default"; return true; case SubZone.Shore_SnakeBeach: subZoneRoot = "Map/Biome_1/Beach/Beach_Segment/SnakeBeach"; return true; case SubZone.Shore_RedBeach: subZoneRoot = "Map/Biome_1/Beach/Beach_Segment/RedBeach"; return true; case SubZone.Shore_BlueBeach: subZoneRoot = "Map/Biome_1/Beach/Beach_Segment/BlueBeach"; return true; case SubZone.Shore_JellyHell: subZoneRoot = "Map/Biome_1/Beach/Beach_Segment/JellyHell"; return true; case SubZone.Shore_BlackSand: subZoneRoot = "Map/Biome_1/Beach/Beach_Segment/BlackSand"; return true; case SubZone.Tropics_Default: subZoneRoot = "Map/Biome_2/Tropics/Jungle_Segment/Default"; return true; case SubZone.Tropics_Lava: subZoneRoot = "Map/Biome_2/Tropics/Jungle_Segment/Lava"; return true; case SubZone.Tropics_Pillars: subZoneRoot = "Map/Biome_2/Tropics/Jungle_Segment/Pillars"; return true; case SubZone.Tropics_Thorny: subZoneRoot = "Map/Biome_2/Tropics/Jungle_Segment/Thorny"; return true; case SubZone.Tropics_Bombs: subZoneRoot = "Map/Biome_2/Tropics/Jungle_Segment/Bombs"; return true; case SubZone.Tropics_Ivy: subZoneRoot = "Map/Biome_2/Tropics/Jungle_Segment/Ivy"; return true; case SubZone.Tropics_SkyJungle: subZoneRoot = "Map/Biome_2/Tropics/Jungle_Segment/SkyJungle"; return true; case SubZone.Alpine_Default: subZoneRoot = "Map/Biome_3/Alpine/Snow_Segment/Default"; return true; case SubZone.Alpine_Lava: subZoneRoot = "Map/Biome_3/Alpine/Snow_Segment/Lava"; return true; case SubZone.Alpine_Spiky: subZoneRoot = "Map/Biome_3/Alpine/Snow_Segment/Spiky"; return true; case SubZone.Alpine_GeyserHell: subZoneRoot = "Map/Biome_3/Alpine/Snow_Segment/GeyserHell"; return true; default: subZoneRoot = ""; return false; } } } public static class MapObjectRefs { private static int _initCount; private const int TotalTransformFields = 44; public static Transform? BioShore { get; private set; } public static Transform? BioTropics { get; private set; } public static Transform? BioRoots { get; private set; } public static Transform? BioAlpine { get; private set; } public static Transform? BioMesa { get; private set; } public static Transform? BioVolcano { get; private set; } public static Transform? SegShore { get; private set; } public static Transform? SegTropics { get; private set; } public static Transform? SegRoots { get; private set; } public static Transform? SegAlpine { get; private set; } public static Transform? SegMesa { get; private set; } public static Transform? SegCaldera { get; private set; } public static Transform? SegKiln { get; private set; } public static Transform? SegPeak { get; private set; } public static Transform? CampAreaShore { get; private set; } public static Transform? CampAreaTropics { get; private set; } public static Transform? CampAreaRoots { get; private set; } public static Transform? CampAreaAlpine { get; private set; } public static Transform? CampAreaMesa { get; private set; } public static Transform? CampAreaCaldera { get; private set; } public static Transform? CampSpawnerShore { get; private set; } public static Transform? CampSpawnerTropics { get; private set; } public static Transform? CampSpawnerRoots { get; private set; } public static Transform? CampSpawnerAlpine { get; private set; } public static Transform? CampSpawnerMesa { get; private set; } public static Transform? CampSpawnerCaldera { get; private set; } public static Transform? SubBioShoreDefault { get; private set; } public static Transform? SubBioShoreSnakeBeach { get; private set; } public static Transform? SubBioShoreRedBeach { get; private set; } public static Transform? SubBioShoreBlueBeach { get; private set; } public static Transform? SubBioShoreJellyHell { get; private set; } public static Transform? SubBioShoreBlackSand { get; private set; } public static Transform? SubBioTropicsDefault { get; private set; } public static Transform? SubBioTropicsLava { get; private set; } public static Transform? SubBioTropicsPillars { get; private set; } public static Transform? SubBioTropicsThorny { get; private set; } public static Transform? SubBioTropicsBombs { get; private set; } public static Transform? SubBioTropicsIvy { get; private set; } public static Transform? SubBioTropicsSkyJungle { get; private set; } public static Transform? SubBioAlpineDefault { get; private set; } public static Transform? SubBioAlpineLava { get; private set; } public static Transform? SubBioAlpineSpiky { get; private set; } public static Transform? SubBioAlpineGeyserHell { get; private set; } public static Transform? PeakFlagPole { get; private set; } static MapObjectRefs() { GameStateEvents.OnAirportLoaded += Reset; GameStateEvents.OnSelfLeaveLobby += Reset; } internal static void Init() { BioShore = Find("Map/Biome_1/Beach"); BioTropics = Find("Map/Biome_2/Tropics"); BioRoots = Find("Map/Biome_2/Roots"); BioAlpine = Find("Map/Biome_3/Alpine"); BioMesa = Find("Map/Biome_3/Mesa"); BioVolcano = Find("Map/Biome_4/Volcano"); SegShore = Find("Map/Biome_1/Beach/Beach_Segment"); SegTropics = Find("Map/Biome_2/Tropics/Jungle_Segment"); SegRoots = Find("Map/Biome_2/Roots/Roots Segment"); SegAlpine = Find("Map/Biome_3/Alpine/Snow_Segment"); SegMesa = Find("Map/Biome_3/Mesa/Desert_Segment"); SegCaldera = Find("Map/Biome_4/Volcano/Caldera_Segment"); SegKiln = Find("Map/Biome_4/Volcano/Volcano_Segment"); SegPeak = Find("Map/Biome_4/Volcano/Peak"); CampAreaShore = Find("Map/Biome_1/Beach/Beach_Campfire"); CampAreaTropics = Find("Map/Biome_2/Tropics/Jungle_Campfire"); CampAreaRoots = Find("Map/Biome_2/Roots/Roots_Campfire"); CampAreaAlpine = Find("Map/Biome_3/Alpine/Snow_Campfire"); CampAreaMesa = Find("Map/Biome_3/Mesa/Desert_Campfire/Snow_Campfire"); CampAreaCaldera = Find("Map/Biome_4/Volcano/Volcano_Campfire"); CampSpawnerShore = Find("Map/Biome_1/Beach/Beach_Campfire/Campfire"); CampSpawnerTropics = Find("Map/Biome_2/Tropics/Jungle_Campfire/Campfire"); CampSpawnerRoots = Find("Map/Biome_2/Roots/Roots_Campfire/Campfire"); CampSpawnerAlpine = Find("Map/Biome_3/Alpine/Snow_Campfire/Campfire"); CampSpawnerMesa = Find("Map/Biome_3/Mesa/Desert_Campfire/Snow_Campfire/Campfire"); CampSpawnerCaldera = Find("Map/Biome_4/Volcano/Volcano_Campfire/Campfire"); SubBioShoreDefault = Find("Map/Biome_1/Beach/Beach_Segment/Default"); SubBioShoreSnakeBeach = Find("Map/Biome_1/Beach/Beach_Segment/SnakeBeach"); SubBioShoreRedBeach = Find("Map/Biome_1/Beach/Beach_Segment/RedBeach"); SubBioShoreBlueBeach = Find("Map/Biome_1/Beach/Beach_Segment/BlueBeach"); SubBioShoreJellyHell = Find("Map/Biome_1/Beach/Beach_Segment/JellyHell"); SubBioShoreBlackSand = Find("Map/Biome_1/Beach/Beach_Segment/BlackSand"); SubBioTropicsDefault = Find("Map/Biome_2/Tropics/Jungle_Segment/Default"); SubBioTropicsLava = Find("Map/Biome_2/Tropics/Jungle_Segment/Lava"); SubBioTropicsPillars = Find("Map/Biome_2/Tropics/Jungle_Segment/Pillars"); SubBioTropicsThorny = Find("Map/Biome_2/Tropics/Jungle_Segment/Thorny"); SubBioTropicsBombs = Find("Map/Biome_2/Tropics/Jungle_Segment/Bombs"); SubBioTropicsIvy = Find("Map/Biome_2/Tropics/Jungle_Segment/Ivy"); SubBioTropicsSkyJungle = Find("Map/Biome_2/Tropics/Jungle_Segment/SkyJungle"); SubBioAlpineDefault = Find("Map/Biome_3/Alpine/Snow_Segment/Default"); SubBioAlpineLava = Find("Map/Biome_3/Alpine/Snow_Segment/Lava"); SubBioAlpineSpiky = Find("Map/Biome_3/Alpine/Snow_Segment/Spiky"); SubBioAlpineGeyserHell = Find("Map/Biome_3/Alpine/Snow_Segment/GeyserHell"); PeakFlagPole = Find("Map/Biome_4/Volcano/Peak/Flag_planted_seagull/Flag Pole"); if (_initCount == 44) { LogProvider.Log?.LogColorS($"All map object references initialized: {_initCount}/{44}"); } else { LogProvider.Log?.LogColorW($"Not all map object references initialized: {_initCount}/{44}"); } } internal static void Reset() { _initCount = 0; BioShore = null; BioTropics = null; BioRoots = null; BioAlpine = null; BioMesa = null; BioVolcano = null; SegShore = null; SegTropics = null; SegRoots = null; SegAlpine = null; SegMesa = null; SegCaldera = null; SegKiln = null; SegPeak = null; CampAreaShore = null; CampAreaTropics = null; CampAreaRoots = null; CampAreaAlpine = null; CampAreaMesa = null; CampAreaCaldera = null; CampSpawnerShore = null; CampSpawnerTropics = null; CampSpawnerRoots = null; CampSpawnerAlpine = null; CampSpawnerMesa = null; CampSpawnerCaldera = null; SubBioShoreDefault = null; SubBioShoreSnakeBeach = null; SubBioShoreRedBeach = null; SubBioShoreBlueBeach = null; SubBioShoreJellyHell = null; SubBioShoreBlackSand = null; SubBioTropicsDefault = null; SubBioTropicsLava = null; SubBioTropicsPillars = null; SubBioTropicsThorny = null; SubBioTropicsBombs = null; SubBioTropicsIvy = null; SubBioTropicsSkyJungle = null; SubBioAlpineDefault = null; SubBioAlpineLava = null; SubBioAlpineSpiky = null; SubBioAlpineGeyserHell = null; PeakFlagPole = null; } private static Transform? Find(string path) { GameObject obj = GameObject.Find(path); Transform val = ((obj != null) ? obj.transform : null); if (val == null) { LogProvider.Log?.LogColor("Could not find transform for: " + path); } else { _initCount++; } GameObject obj2 = GameObject.Find(path); if (obj2 == null) { return null; } return obj2.transform; } } } namespace NetGameState.LevelProgression { public static class SegmentManager { public readonly struct SegmentInfo { public readonly Chapter Chapter; public readonly Zone Zone; public readonly SubZone SubZone; public readonly Transform? SegTansform; public SegmentInfo(Chapter chapter, Zone biome, SubZone subZone, Transform? segment = null) { Chapter = chapter; Zone = biome; SubZone = subZone; SegTansform = segment; } } public static readonly SegmentInfo[] CurrentRunSegments; public static readonly Dictionary<Zone, SubZone> CurrentRunSubZones; public static Chapter CurrentChapter { get; private set; } public static Zone CurrentZone { get; private set; } public static SubZone CurrentSubZone { get; private set; } public static SegmentInfo CurrentSegmentInfo { get; private set; } public static SegmentInfo PreviousSegmentInfo { get; set; } public static bool IsAlpine { get; private set; } public static bool IsTropics { get; private set; } public static event Action<SegmentInfo, SegmentInfo>? OnSegmentLoading; public static event Action<SegmentInfo>? OnSegmentLoadComplete; static SegmentManager() { CurrentRunSegments = new SegmentInfo[Enum.GetValues(typeof(Segment)).Length]; CurrentRunSubZones = new Dictionary<Zone, SubZone>(); CurrentChapter = Chapter.Unknown; CurrentZone = Zone.Unknown; CurrentSubZone = SubZone.Unknown; CurrentSegmentInfo = new SegmentInfo(CurrentChapter, CurrentZone, CurrentSubZone); PreviousSegmentInfo = new SegmentInfo(CurrentChapter, CurrentZone, CurrentSubZone); GameStateEvents.OnAirportLoaded += Reset; GameStateEvents.OnSelfLeaveLobby += Reset; } private static void Reset() { CurrentChapter = Chapter.Unknown; CurrentZone = Zone.Unknown; CurrentSubZone = SubZone.Unknown; CurrentSegmentInfo = new SegmentInfo(CurrentChapter, CurrentZone, CurrentSubZone); PreviousSegmentInfo = new SegmentInfo(CurrentChapter, CurrentZone, CurrentSubZone); for (int i = 0; i < CurrentRunSegments.Length; i++) { CurrentRunSegments[i] = new SegmentInfo(Chapter.Unknown, Zone.Unknown, SubZone.Unknown); } IsAlpine = false; IsTropics = false; } internal static void SetCurrentSegment(Segment segment) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) PreviousSegmentInfo = new SegmentInfo(CurrentChapter, CurrentZone, CurrentSubZone); CurrentChapter = SegmentMapper.GetChapterFromSegment(segment); CurrentZone = SegmentMapper.GetZoneFromChapter(CurrentChapter); CurrentSubZone = SegmentMapper.GetSubZoneFromZone(CurrentZone); Transform biomeSegment = GetBiomeSegment(CurrentZone); CurrentSegmentInfo = new SegmentInfo(CurrentChapter, CurrentZone, CurrentSubZone, biomeSegment); SegmentManager.OnSegmentLoading?.Invoke(PreviousSegmentInfo, CurrentSegmentInfo); } internal static void RaiseOnSegmentLoadComplete() { SegmentManager.OnSegmentLoadComplete?.Invoke(CurrentSegmentInfo); } internal static void DetermineRunSegments() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) foreach (var item in Enum.GetValues(typeof(Segment)).Cast<Segment>().Select((Segment segment, int index) => new { segment, index })) { Chapter chapterFromSegment = SegmentMapper.GetChapterFromSegment(item.segment); Zone zoneFromChapter = SegmentMapper.GetZoneFromChapter(chapterFromSegment); SubZone subZoneFromZone = SegmentMapper.GetSubZoneFromZone(zoneFromChapter); Transform biomeSegment = GetBiomeSegment(zoneFromChapter); CurrentRunSegments[item.index] = new SegmentInfo(chapterFromSegment, zoneFromChapter, subZoneFromZone, biomeSegment); CurrentRunSubZones[zoneFromChapter] = subZoneFromZone; if (zoneFromChapter == Zone.Alpine) { IsAlpine = true; } if (zoneFromChapter == Zone.Tropics) { IsTropics = true; } } CurrentChapter = CurrentRunSegments[0].Chapter; CurrentZone = CurrentRunSegments[0].Zone; CurrentSubZone = CurrentRunSegments[0].SubZone; } private static Transform? GetBiomeSegment(Zone zone) { return (Transform?)(zone switch { Zone.Shore => MapObjectRefs.SegShore, Zone.Tropics => MapObjectRefs.SegTropics, Zone.Roots => MapObjectRefs.SegRoots, Zone.Alpine => MapObjectRefs.SegAlpine, Zone.Mesa => MapObjectRefs.SegMesa, Zone.Caldera => MapObjectRefs.SegCaldera, Zone.Kiln => MapObjectRefs.SegKiln, Zone.Peak => MapObjectRefs.SegPeak, _ => null, }); } } } namespace NetGameState.Events { public static class GameStateEvents { private static bool _isLobbyCreated; public static string CurrentLevel { get; private set; } = ""; public static int CurrentAscent { get; private set; } public static bool IsRunActive { get; private set; } public static bool IsInAirport { get; private set; } public static bool IsOfflineMode { get; private set; } public static bool IsAllReady { get; private set; } public static event Action? OnPlayOfflineClicked; public static event Action<Player>? OnPlayerEnteredRoom; public static event Action<Player>? OnPlayerLeftRoom; public static event Action? OnSelfCreateLobby; public static event Action? OnSelfJoinLobby; public static event Action? OnSelfLeaveLobby; public static event Action<Player>? OnPlayerRegistered; public static event Action<Player>? OnPlayerUnregistered; public static event Action? OnAirportLoaded; public static event Action<string, int>? OnRunStartLoading; public static event Action? OnLocalPlayerReady; public static event Action<Player>? OnPlayerReady; public static event Action? OnAllPlayersReady; public static event Action<Player>? OnPlayerLoadTimeout; public static event Action<string, int>? OnRunStartLoadComplete; public static event Action? OnRunStartedAndPlayersReady; internal static void RaiseOnPlayOfflineClicked() { IsOfflineMode = true; GameStateEvents.OnPlayOfflineClicked?.Invoke(); } internal static void RaiseOnPlayerEnteredRoom(Player player) { GameStateEvents.OnPlayerEnteredRoom?.Invoke(player); } internal static void RaiseOnPlayerLeftRoom(Player player) { GameStateEvents.OnPlayerLeftRoom?.Invoke(player); } internal static void RaiseOnSelfCreateLobby() { _isLobbyCreated = true; IsOfflineMode = false; GameStateEvents.OnSelfCreateLobby?.Invoke(); } internal static void RaiseOnSelfJoinLobby() { IsOfflineMode = false; if (!_isLobbyCreated) { GameStateEvents.OnSelfJoinLobby?.Invoke(); } } internal static void RaiseOnSelfLeaveLobby() { _isLobbyCreated = false; IsInAirport = false; IsRunActive = false; GameStateEvents.OnSelfLeaveLobby?.Invoke(); } internal static void RaiseOnPlayerRegistered(Player player) { GameStateEvents.OnPlayerRegistered?.Invoke(player); } internal static void RaiseOnPlayerUnregistered(Player player) { GameStateEvents.OnPlayerUnregistered?.Invoke(player); } internal static void RaiseOnAirportLoaded() { IsInAirport = true; IsRunActive = false; IsAllReady = false; ((Behaviour)PlayerReadyTracker.Instance).enabled = true; GameStateEvents.OnAirportLoaded?.Invoke(); } internal static void RaiseOnStartLoading(string sceneName, int ascent) { CurrentLevel = sceneName; CurrentAscent = ascent; IsInAirport = false; GameStateEvents.OnRunStartLoading?.Invoke(sceneName, ascent); } internal static void RaiseOnLocalPlayerReady() { GameStateEvents.OnLocalPlayerReady?.Invoke(); } internal static void RaiseOnPlayerReady(Player player) { GameStateEvents.OnPlayerReady?.Invoke(player); } internal static void RaiseOnAllPlayersReady() { IsAllReady = true; GameStateEvents.OnAllPlayersReady?.Invoke(); if (IsRunActive) { GameStateEvents.OnRunStartedAndPlayersReady?.Invoke(); } } internal static void RaiseOnPlayerLoadTimeout(Player player) { IsAllReady = true; GameStateEvents.OnPlayerLoadTimeout?.Invoke(player); } internal static void RaiseOnRunLoadComplete() { MapObjectRefs.Init(); SegmentManager.DetermineRunSegments(); IsRunActive = true; IsInAirport = false; GameStateEvents.OnRunStartLoadComplete?.Invoke(CurrentLevel, CurrentAscent); if (IsAllReady) { GameStateEvents.OnRunStartedAndPlayersReady?.Invoke(); } } } } namespace ConsoleTools { public static class ConsoleConfig { internal static readonly Dictionary<string, bool> RegisteredPlugins = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase); public static bool ShowUnityLogs { get; set; } = true; internal static ConsoleColor SourceColor { get; private set; } = ConsoleColor.Gray; internal static ConsoleColor CallerColor { get; private set; } = ConsoleColor.Gray; public static void Register(string pluginName) { RegisteredPlugins[pluginName] = true; } public static void Unregister(string pluginName) { RegisteredPlugins.Remove(pluginName); } public static void SetLogging(string pluginName, bool enable) { if (!string.IsNullOrEmpty(pluginName)) { RegisteredPlugins[pluginName] = enable; } } public static void SetDefaultSourceColor(ConsoleColor color) { SourceColor = color; } public static void SetDefaultCallerColor(ConsoleColor color) { CallerColor = color; } } internal static class ConsoleManagerReflection { private static readonly MethodInfo? SetConsoleColorMethod; private static TextWriter? ConsoleStream { get; } static ConsoleManagerReflection() { Assembly assembly = typeof(BaseUnityPlugin).Assembly; Type type = assembly.GetType("BepInEx.ConsoleManager"); if (!(type == null)) { SetConsoleColorMethod = type.GetMethod("SetConsoleColor", BindingFlags.Static | BindingFlags.Public); ConsoleStream = type.GetProperty("ConsoleStream", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) as TextWriter; } } private static void SetColor(ConsoleColor color) { SetConsoleColorMethod?.Invoke(null, new object[1] { color }); } internal static void Write(string message, ConsoleColor? color = null, bool newline = true) { if (color.HasValue) { SetColor(color.Value); } if (newline) { ConsoleStream?.WriteLine(message); } else { ConsoleStream?.Write(message); } if (color.HasValue) { SetColor(ConsoleColor.Gray); } } } public static class ManualLogSourceExtensions { private static void LogColorX(this ManualLogSource log, string message, LogLevel logLevel = 16) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected I4, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 if ((int)logLevel <= 16) { switch ((int)logLevel) { default: if ((int)logLevel != 16) { break; } log.LogInfo((object)(message ?? "")); return; case 4: log.LogWarning((object)(message ?? "")); return; case 2: log.LogError((object)(message ?? "")); return; case 1: log.LogFatal((object)(message ?? "")); return; case 0: log.LogInfo((object)(message ?? "")); return; case 3: case 5: case 6: case 7: case 8: break; } } else { if ((int)logLevel == 32) { log.LogDebug((object)(message ?? "")); return; } if ((int)logLevel == 63) { } } log.LogInfo((object)(message ?? "")); } private static string ParseColor(string message, ConsoleColor color, bool callerInfo, bool oneColor) { string text = ""; if (callerInfo) { StackTrace stackTrace = new StackTrace(2, fNeedFileInfo: false); StackFrame frame = stackTrace.GetFrame(0); MethodBase method = frame.GetMethod(); string text2 = method.DeclaringType?.Name ?? "<unknown>"; string name = method.Name; text = "[" + text2 + "." + name + "] "; } if (oneColor) { string text3 = $"#CC{(int)color:D2}"; return text3 + text + message; } string text4 = $"#CS{(int)ConsoleConfig.SourceColor:D2}"; string text5 = $"#CS{(int)ConsoleConfig.CallerColor:D2}"; string text6 = $"#CS{(int)color:D2}"; return text4 + text5 + text + text6 + message; } public static void LogColor(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Gray, bool callerInfo = true, bool oneColor = false) { if (!ConsoleConfig.RegisteredPlugins.TryGetValue(log.SourceName, out var value) || !value) { log.LogInfo((object)message); } else { log.LogColorX(ParseColor(message, color, callerInfo, oneColor), (LogLevel)16); } } public static void LogColorW(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.DarkYellow, bool callerInfo = true, bool oneColor = false) { if (!ConsoleConfig.RegisteredPlugins.TryGetValue(log.SourceName, out var value) || !value) { log.LogWarning((object)message); } else { log.LogColorX(ParseColor(message, color, callerInfo, oneColor), (LogLevel)4); } } public static void LogColorE(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.DarkRed, bool callerInfo = true, bool oneColor = false) { if (!ConsoleConfig.RegisteredPlugins.TryGetValue(log.SourceName, out var value) || !value) { log.LogError((object)message); } else { log.LogColorX(ParseColor(message, color, callerInfo, oneColor), (LogLevel)2); } } public static void LogColorF(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.DarkRed, bool callerInfo = true, bool oneColor = false) { if (!ConsoleConfig.RegisteredPlugins.TryGetValue(log.SourceName, out var value) || !value) { log.LogFatal((object)message); } else { log.LogColorX(ParseColor(message, color, callerInfo, oneColor), (LogLevel)1); } } public static void LogColorD(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Gray, bool callerInfo = true, bool oneColor = false) { if (!ConsoleConfig.RegisteredPlugins.TryGetValue(log.SourceName, out var value) || !value) { log.LogDebug((object)message); } else { log.LogColorX(ParseColor(message, color, callerInfo, oneColor), (LogLevel)32); } } public static void LogColorS(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.DarkGreen, bool callerInfo = true, bool oneColor = false) { if (!ConsoleConfig.RegisteredPlugins.TryGetValue(log.SourceName, out var value) || !value) { log.LogInfo((object)message); } else { log.LogColorX(ParseColor(message, color, callerInfo, oneColor), (LogLevel)0); } } } } namespace ConsoleTools.Patches { [HarmonyPatch(typeof(ConsoleLogListener))] public static class ConsoleLogListenerPatches { [HarmonyPatch("LogEvent")] private static bool Prefix(ConsoleLogListener __instance, object sender, LogEventArgs eventArgs) { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) if (eventArgs.Source.SourceName == "Unity Log" && !ConsoleConfig.ShowUnityLogs) { return false; } if (!ConsoleConfig.RegisteredPlugins.TryGetValue(eventArgs.Source.SourceName, out var value) || !value) { return true; } string text = eventArgs.Data.ToString(); ConsoleColor consoleColor = ConsoleColor.Gray; if (text.StartsWith("#CC") && text.Length >= 5) { if (int.TryParse(text.Substring(3, 2), out var result)) { consoleColor = (ConsoleColor)result; text = text.Substring(5); } ConsoleManagerReflection.Write("[Info :" + eventArgs.Source.SourceName + "] " + text, consoleColor); } else if (text.StartsWith("#CS") && text.Length >= 5) { int num = 0; ConsoleColor value2 = consoleColor; if (int.TryParse(text.Substring(3, 2), out var result2)) { value2 = (ConsoleColor)result2; num = 5; } LogLevel level = eventArgs.Level; string text2 = ((object)(LogLevel)(ref level)).ToString().PadRight(7); string message = "[" + text2 + ":" + eventArgs.Source.SourceName + "] "; ConsoleManagerReflection.Write(message, value2, newline: false); while (num < text.Length) { if (text.Length - num >= 5 && text.Substring(num, 3) == "#CS" && int.TryParse(text.Substring(num + 3, 2), out var result3)) { value2 = (ConsoleColor)result3; num += 5; continue; } int num2 = text.IndexOf("#CS", num, StringComparison.Ordinal); int num3 = ((num2 == -1) ? text.Length : num2) - num; string message2 = text.Substring(num, num3); ConsoleManagerReflection.Write(message2, value2, newline: false); num += num3; } ConsoleManagerReflection.Write("", consoleColor); } return false; } } } namespace HazardSpam { public static class ModManager { [CompilerGenerated] private sealed class <LoadRun>d__11 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadRun>d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; Plugin.Log.LogColor("Waiting to load run.. 3 seconds"); <>2__current = (object)new WaitForSeconds(3f); <>1__state = 1; return true; case 1: <>1__state = -1; Plugin.Log.LogColor("Creating spawners.."); HazardManager.CreateSpawnersFromConfigOverNetwork(); Plugin.Log.LogColor("Spawners created"); <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 2; return true; case 2: <>1__state = -1; Plugin.Log.LogColor("Applying hazard tweaks.."); HazardManager.ApplyTweaksFromConfigOverNetwork(); Plugin.Log.LogColor("Hazard tweaks applied"); <>2__current = (object)new WaitForSeconds(3f); <>1__state = 3; return true; case 3: <>1__state = -1; Plugin.Log.LogColor("Loading zone"); <>2__current = HazardManager.LoadZone(Zone.Shore); <>1__state = 4; return true; case 4: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal static void Awake() { InitNetworkObjects(); GameStateEvents.OnRunStartLoading += OnRunStartLoading; GameStateEvents.OnRunStartLoadComplete += OnRunStartLoadComplete; GameStateEvents.OnAllPlayersReady += OnAllPlayersReady; GameStateEvents.OnRunStartedAndPlayersReady += OnRunStartedAndPlayersReady; SegmentManager.OnSegmentLoading += OnSegmentLoading; SegmentManager.OnSegmentLoadComplete += OnSegmentLoadComplete; GameStateEvents.OnAirportLoaded += OnAirportLoaded; GameStateEvents.OnSelfLeaveLobby += OnSelfLeaveLobby; } internal static void OnDestroy() { GameStateEvents.OnRunStartLoading -= OnRunStartLoading; GameStateEvents.OnRunStartLoadComplete -= OnRunStartLoadComplete; GameStateEvents.OnAllPlayersReady -= OnAllPlayersReady; GameStateEvents.OnRunStartedAndPlayersReady -= OnRunStartedAndPlayersReady; SegmentManager.OnSegmentLoading -= OnSegmentLoading; SegmentManager.OnSegmentLoadComplete -= OnSegmentLoadComplete; GameStateEvents.OnAirportLoaded -= OnAirportLoaded; GameStateEvents.OnSelfLeaveLobby -= OnSelfLeaveLobby; CleanupSpawners(); CleanupNetwork(); } private static void InitNetworkObjects() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if (GameObject.Find("HazardSpamNetwork") != null) { Plugin.Log.LogDebug((object)"HazardSpamNetwork already exists."); return; } GameObject val = new GameObject("HazardSpamNetwork"); val.AddComponent<PlayerReadyTracker>(); val.AddComponent<PhotonCallbacks>(); val.AddComponent<PhotonView>(); PhotonView component = val.GetComponent<PhotonView>(); component.ViewID = 9989; val.AddComponent<NetComm>(); } private static void CleanupNetwork() { GameObject val = GameObject.Find("HazardSpamNetwork"); if (val != null) { Plugin.DestroyGameObject(val); } } private static void CleanupSpawners() { HazardTemplateManager.Reset(); HazardManager.Reset(); Plugin.SpawnersInitialized = false; } private static void OnAirportLoaded() { Plugin.Log.LogColor("Loaded airport, cleaning spawners"); CleanupSpawners(); } private static void OnSelfLeaveLobby() { Plugin.Log.LogColor("Left lobby, cleaning spawners"); CleanupSpawners(); } private static void OnRunStartLoading(string sceneName, int ascent) { } private static void OnAllPlayersReady() { _ = PhotonNetwork.IsMasterClient; } private static void OnRunStartLoadComplete(string sceneName, int ascent) { HazardTemplateManager.LoadSceneData(); } private static void OnRunStartedAndPlayersReady() { Plugin.Log.LogColor("Run started and all players are ready"); if (PhotonNetwork.IsMasterClient) { ((MonoBehaviour)NetComm.Instance).StartCoroutine(LoadRun()); } } [IteratorStateMachine(typeof(<LoadRun>d__11))] private static IEnumerator LoadRun() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadRun>d__11(0); } private static void OnSegmentLoading(SegmentManager.SegmentInfo fromSegment, SegmentManager.SegmentInfo toSegment) { if (PhotonNetwork.IsMasterClient) { Plugin.Log.LogColor("FROM: " + fromSegment.Chapter.ToString() + "/" + fromSegment.Zone.ToString() + "/" + fromSegment.SubZone.ToString() + " - TO: " + toSegment.Chapter.ToString() + "/" + toSegment.Zone.ToString() + "/" + toSegment.SubZone); Plugin.Log.LogColor($"Segment loading: {fromSegment.Zone} -> {toSegment.Zone}"); if (fromSegment.Zone != Zone.Unknown) { HazardManager.UnloadZone(fromSegment.Zone); } } } private static void OnSegmentLoadComplete(SegmentManager.SegmentInfo segment) { Plugin.Log.LogColor("LOADED: " + segment.Chapter.ToString() + "/" + segment.Zone.ToString() + "/" + segment.SubZone); if (PhotonNetwork.IsMasterClient && segment.Zone != Zone.Shore) { ((MonoBehaviour)NetComm.Instance).StartCoroutine(HazardManager.LoadZone(segment.Zone)); } } } [BepInPlugin("com.github.tehUsual.HazardSpam", "HazardSpam", "2.0.6")] public class Plugin : BaseUnityPlugin { private MenuHandler _menuHandler; internal const int HazardSpamViewID = 9989; private const string CompatibleVersion = "1.60.d"; internal static bool SpawnersInitialized; public const string Id = "com.github.tehUsual.HazardSpam"; internal static ManualLogSource Log { get; private set; } internal static Plugin Instance { get; private set; } internal static bool Debug { get; private set; } internal static bool DebugFull { get; private set; } internal static bool DebugMenu { get; private set; } public static string Name => "HazardSpam"; public static string Version => "2.0.6"; private void Awake() { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)("Plugin " + Name + " is loading..")); LogProvider.Log = Log; ConfigHandler.Init(((BaseUnityPlugin)this).Config); Debug = ConfigHandler.Debug.Value; DebugFull = ConfigHandler.DebugVerbose.Value; DebugMenu = ConfigHandler.DebugMenu.Value; if (Debug) { ConsoleConfig.Register(Name); ConsoleConfig.SetLogging(Name, enable: true); ConsoleConfig.ShowUnityLogs = false; ConsoleConfig.SetDefaultSourceColor(ConsoleColor.DarkCyan); ConsoleConfig.SetDefaultCallerColor(ConsoleColor.DarkYellow); } Harmony val = new Harmony("com.github.tehUsual.HazardSpam"); val.PatchAll(typeof(AOEPatches)); val.PatchAll(typeof(CollisionModifierPatches)); val.PatchAll(typeof(RemoveAfterSecondsPatches)); val.PatchAll(typeof(SlipperyJellyfishPatches)); val.PatchAll(typeof(StatusTriggerPatches)); val.PatchAll(typeof(TimeEventPatches)); val.PatchAll(typeof(TriggerEventPatches)); val.PatchAll(typeof(AirportCheckInPatches)); val.PatchAll(typeof(LoadScenePatches)); val.PatchAll(typeof(MainMenuPatches)); val.PatchAll(typeof(MapHandlerPatches)); val.PatchAll(typeof(MountainProgressHandlerPatches)); val.PatchAll(typeof(PlayerHandlerPatches)); val.PatchAll(typeof(RunManagerPatches)); val.PatchAll(typeof(SteamLobbyHandlerPatches)); if (Debug) { val.PatchAll(typeof(ConsoleLogListenerPatches)); } if (Application.version.Trim('.') != "1.60.d") { Log.LogColorW("This plugin has only been tested with v1.60.d. The mod may not work correctly. Current game version: v" + Application.version); } if (DebugFull) { CallbackTests.Init(); } ModManager.Awake(); HazardTemplateManager.Initialize(); _menuHandler = new MenuHandler(); _menuHandler.Initialize(); Log.LogInfo((object)("Plugin " + Name + " load complete!")); } private void Update() { if (Input.GetKeyDown((KeyCode)286)) { ConsoleConfig.ShowUnityLogs = !ConsoleConfig.ShowUnityLogs; Log.LogColor("Unity console logs " + (ConsoleConfig.ShowUnityLogs ? "enabled" : "disabled")); } if (!PhotonNetwork.IsMasterClient) { return; } if (Input.GetKeyDown((KeyCode)127) && GameStateEvents.IsInAirport) { _menuHandler.Toggle(); } if (!Debug || !Input.GetKey((KeyCode)308)) { return; } if (GameStateEvents.IsRunActive) { if (Input.GetKeyDown((KeyCode)257)) { TeleportHandler.TeleportToCampfire(Campfire.Shore); } if (Input.GetKeyDown((KeyCode)258)) { TeleportHandler.TeleportToCampfire(Campfire.TropicsRoots); } if (Input.GetKeyDown((KeyCode)259)) { TeleportHandler.TeleportToCampfire(Campfire.AlpineMesa); } if (Input.GetKeyDown((KeyCode)260)) { TeleportHandler.TeleportToCampfire(Campfire.Caldera); } if (Input.GetKeyDown((KeyCode)261)) { TeleportHandler.TeleportToCampfire(Campfire.PeakFlagpole); } } if (GameStateEvents.IsInAirport && Input.GetKeyDown((KeyCode)265)) { GameObject val = GameObject.Find("Map/BL_Airport/Fences/Check In desk/AirportGateKiosk"); AirportCheckInKiosk val2 = ((val != null) ? val.GetComponent<AirportCheckInKiosk>() : null); if (val2 != null) { ((MonoBehaviourPun)val2).photonView.RPC("LoadIslandMaster", (RpcTarget)2, new object[2] { 0, Array.Empty<byte>() }); } } } private void OnDestroy() { ModManager.OnDestroy(); if (DebugFull) { CallbackTests.Reset(); } } internal static void DestroyGameObject(GameObject go) { Object.Destroy((Object)(object)go); } public void UpdateSidebarTabCount(string biomeName, int totalHazards) { _menuHandler.UpdateSidebarTabCount(biomeName, totalHazards); } } } namespace HazardSpam.Types { public readonly struct HazardTweakNet { public readonly HazardType Type; public readonly string Field; public readonly object Value; public HazardTweakNet(HazardType type, string field, object value) { Type = type; Field = field; Value = value; } public void Deconstruct(out HazardType type, out string field, out object value) { type = Type; field = Field; value = Value; } public string GenID() { return Type.ToString() + "/" + Field; } } public enum HazardType { Unknown, Urchin, Jelly, PoisonIvy, ExploSpore, PoisonSpore, Thorn, BigThorn, Beehive, Geyser, FlashPlant, CactusBall, Cactus, CactusBig, Dynamite, Tumbler, Scorpion, LavaRiver } public struct SpawnIdentifier { public Zone Zone; public SubZoneArea Area; public HazardType Type; public SpawnIdentifier(Zone zone, SubZoneArea area, HazardType type) { Zone = zone; Area = area; Type = type; } public void Deconstruct(out Zone zone, out SubZoneArea area, out HazardType type) { zone = Zone; area = Area; type = Type; } public string GenID() { return Zone.ToString() + "/" + Area.ToString() + "/" + Type; } } public readonly struct SpawnIdentifierNet { public readonly Zone Zone; public readonly SubZoneArea Area; public readonly HazardType Type; public readonly int ViewID; public SpawnIdentifierNet(Zone zone, SubZoneArea area, HazardType type, int viewID = -1) { Zone = zone; Area = area; Type = type; ViewID = viewID; } public void Deconstruct(out Zone zone, out SubZoneArea area, out HazardType type, out int viewID) { zone = Zone; area = Area; type = Type; viewID = ViewID; } public string GenID() { return Zone.ToString() + "/" + Area.ToString() + "/" + Type; } } public enum SubZoneArea { Unknown, Plateau, Wall, WallLeft, WallRight } public enum SupportedHazardType { Unknown = 0, Urchin = 1, Jelly = 2, PoisonIvy = 3, ExploSpore = 4, PoisonSpore = 5, Thorn = 6, BigThorn = 7, Geyser = 9, FlashPlant = 10, Cactus = 12, CactusBig = 13 } public static class TweakField { public const string Force = "fc"; public const string Spin = "sp"; public const string StatusAmount = "sa"; public const string TriggerChance = "tc"; public const string FallTime = "ft"; public const string Knockback = "kb"; public const string Range = "r"; public const string StatusType = "st"; public const string RemoveAfterSeconds = "ras"; public const string Cooldown = "cd"; public const string RepeatRate = "rr"; } } namespace HazardSpam.Tests { public static class SpawnTests { [CompilerGenerated] private sealed class <CreateSpawnerTypes>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private List<SpawnIdentifierNet> <spawnerNetIds>5__2; private List<SpawnIdentifier>.Enumerator <>7__wrap2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CreateSpawnerTypes>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <spawnerNetIds>5__2 = null; <>7__wrap2 = default(List<SpawnIdentifier>.Enumerator); <>1__state = -2; } private bool MoveNext() { //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; List<SpawnIdentifier> list = new List<SpawnIdentifier>(14) { new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.Urchin), new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.Jelly), new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.PoisonIvy), new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.PoisonSpore), new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.Thorn), new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.BigThorn), new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.Beehive), new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.Geyser), new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.FlashPlant), new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.CactusBall), new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.Cactus), new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.CactusBig), new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.Dynamite), new SpawnIdentifier(Zone.Shore, SubZoneArea.Wall, HazardType.LavaRiver) }; <spawnerNetIds>5__2 = new List<SpawnIdentifierNet>(); <>7__wrap2 = list.GetEnumerator(); <>1__state = -3; break; } case 1: <>1__state = -3; break; } while (<>7__wrap2.MoveNext()) { SpawnIdentifier current = <>7__wrap2.Current; SpawnIdentifier spawnIdentifier = current; var (zone2, area, hazardType2) = (SpawnIdentifier)(ref spawnIdentifier); if (HazardManager.TryCreateSpawnerData(zone2, area, hazardType2, out var spawnIdentifierNet)) { <spawnerNetIds>5__2.Add(spawnIdentifierNet); <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap2 = default(List<SpawnIdentifier>.Enumerator); if (<spawnerNetIds>5__2.Count > 0) { NetComm.Instance.CreateMultipleSpawnersNetwork(<spawnerNetIds>5__2.ToArray()); } return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap2).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <InitializeRunSegmentTest>d__5 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <InitializeRunSegmentTest>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; HazardTemplateManager.LoadSceneData(); CreateSpawnerSegments(); <>2__current = LoadZone(Zone.Shore); <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <InitializeRunTypeTest>d__4 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <InitializeRunTypeTest>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; HazardTemplateManager.LoadSceneData(); <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = CreateSpawnerTypes(); <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 3; return true; case 3: <>1__state = -1; <>2__current = LoadZone(Zone.Shore); <>1__state = 4; return true; case 4: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadZone>d__8 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Zone zoneToLoad; private Dictionary<(Zone, SubZoneArea, HazardType), GameObject>.Enumerator <>7__wrap1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadZone>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 2u) { try { } finally { <>m__Finally1(); } } <>7__wrap1 = default(Dictionary<(Zone, SubZoneArea, HazardType), GameObject>.Enumerator); <>1__state = -2; } private bool MoveNext() { //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; Plugin.Log.LogColor($"Loading zone {zoneToLoad}"); if (!PhotonNetwork.IsMasterClient) { Plugin.Log.LogColorW("Not master"); return false; } <>7__wrap1 = HazardManager.ActiveSpawners.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; case 2: <>1__state = -3; break; case 3: <>1__state = -3; break; } while (<>7__wrap1.MoveNext()) { <>7__wrap1.Current.Deconstruct(out (Zone, SubZoneArea, HazardType) key, out GameObject value); (Zone, SubZoneArea, HazardType) tuple = key; Zone item = tuple.Item1; SubZoneArea item2 = tuple.Item2; HazardType item3 = tuple.Item3; GameObject val = value; if (item == zoneToLoad && val != null) { PropSpawner component = val.GetComponent<PropSpawner>(); if (component != null) { int num = 20; if (item3 == HazardType.LavaRiver) { num = 10; } var (array, rotations) = SpawnerLogic.GenerateSpawnPoints(component, num); Plugin.Log.LogColor($"Generated {array.Length} positions out of {num}"); if (array.Length == 0) { <>2__current = null; <>1__state = 1; return true; } NetComm.Instance.SpawnHazardsNetwork(item, item2, item3, array, rotations); <>2__current = (object)new WaitForSeconds(0.33f); <>1__state = 2; return true; } Plugin.Log.LogColorW("Could not find prop spawner for " + item.ToString() + "/" + item2.ToString() + "/" + item3); } else if (val == null) { Plugin.Log.LogColorW("Spawner for " + item.ToString() + "/" + item2.ToString() + "/" + item3.ToString() + " is null"); <>2__current = null; <>1__state = 3; return true; } } <>m__Finally1(); <>7__wrap1 = default(Dictionary<(Zone, SubZoneArea, HazardType), GameObject>.Enumerator); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap1).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal static void Update() { if (!PhotonNetwork.IsMasterClient || !Plugin.Debug) { return; } if (Input.GetKey((KeyCode)306)) { if (Input.GetKeyDown((KeyCode)257)) { CreateSpawner(Zone.Shore, SubZoneArea.Plateau, HazardType.ExploSpore); } if (Input.GetKeyDown((KeyCode)258)) { CreateSpawner(Zone.Shore, SubZoneArea.Plateau, HazardType.Thorn); } if (Input.GetKeyDown((KeyCode)259)) { CreateSpawner(Zone.Shore, SubZoneArea.Wall, HazardType.PoisonSpore); } if (Input.GetKeyDown((KeyCode)260)) { CreateSpawners(Zone.Tropics, SubZoneArea.Wall, new HazardType[3] { HazardType.Beehive, HazardType.PoisonSpore, HazardType.CactusBig }); } if (Input.GetKeyDown((KeyCode)261)) { CreateSpawners(Zone.Alpine, SubZoneArea.Wall, new HazardType[3] { HazardType.Geyser, HazardType.Urchin, HazardType.LavaRiver }); } if (Input.GetKeyDown((KeyCode)262)) { CreateSpawners(Zone.Caldera, SubZoneArea.Plateau, new HazardType[4] { HazardType.PoisonSpore, HazardType.Jelly, HazardType.PoisonIvy, HazardType.Dynamite }); } } if (Input.GetKey((KeyCode)306)) { if (Input.GetKeyDown((KeyCode)56)) { SpawnHazards(Zone.Shore, SubZoneArea.Plateau, HazardType.ExploSpore); } if (Input.GetKeyDown((KeyCode)57)) { SpawnHazards(Zone.Shore, SubZoneArea.Plateau, HazardType.Thorn); } if (Input.GetKeyDown((KeyCode)48)) { SpawnHazards(Zone.Shore, SubZoneArea.Wall, HazardType.PoisonSpore); } } } private static void SpawnHazards(Zone zone, SubZoneArea area, HazardType type) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if (!HazardManager.ActiveSpawners.TryGetValue((zone, area, type), out GameObject value)) { Plugin.Log.LogColorW("Could not get spawner from Active Spawners " + zone.ToString() + "/" + area.ToString() + "/" + type); return; } PropSpawner component = value.GetComponent<PropSpawner>(); var (array, array2) = SpawnerLogic.GenerateSpawnPoints(component, 1000); Plugin.Log.LogColor($"Generated {array.Length} positions out of {1000}"); if (array.Length != 0) { string text = Helper.GenSpawnID(zone, area, type); for (int i = 0; i < array.Length; i++) { GameObject val = NetComm.Instance.InstantiateHazard(component.props[0], array[i], array2[i], value.transform); } } } private static void CreateSpawner(Zone zone, SubZoneArea area, HazardType type) { if (HazardManager.TryCreateSpawnerData(zone, area, type, out var spawnIdentifierNet)) { NetComm.Instance.CreateSpawnerNetwork(spawnIdentifierNet); } } private static void CreateSpawners(Zone zone, SubZoneArea area, HazardType[] types) { List<SpawnIdentifierNet> list = new List<SpawnIdentifierNet>(); foreach (HazardType hazardType in types) { if (HazardManager.TryCreateSpawnerData(zone, area, hazardType, out var spawnIdentifierNet)) { list.Add(spawnIdentifierNet); } } if (list.Count > 0) { NetComm.Instance.CreateMultipleSpawnersNetwork(list.ToArray()); } } [IteratorStateMachine(typeof(<InitializeRunTypeTest>d__4))] internal static IEnumerator InitializeRunTypeTest() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <InitializeRunTypeTest>d__4(0); } [IteratorStateMachine(typeof(<InitializeRunSegmentTest>d__5))] internal static IEnumerator InitializeRunSegmentTest() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <InitializeRunSegmentTest>d__5(0); } internal static void CreateSpawnerSegments() { List<SpawnIdentifier> list = new List<SpawnIdentifier>(9) { new SpawnIdentifier(Zone.Shore, SubZoneArea.Plateau, HazardType.Jelly), new SpawnIdentifier(Zone.Shore, SubZoneArea.Wall, HazardType.Jelly), new SpawnIdentifier(Zone.Tropics, SubZoneArea.Plateau, HazardType.Jelly), new SpawnIdentifier(Zone.Tropics, SubZoneArea.Wall, HazardType.Jelly), new SpawnIdentifier(Zone.Alpine, SubZoneArea.Plateau, HazardType.Jelly), new SpawnIdentifier(Zone.Alpine, SubZoneArea.Wall, HazardType.Jelly), new SpawnIdentifier(Zone.Mesa, SubZoneArea.Plateau, HazardType.Jelly), new SpawnIdentifier(Zone.Mesa, SubZoneArea.Wall, HazardType.Jelly), new SpawnIdentifier(Zone.Caldera, SubZoneArea.Plateau, HazardType.Jelly) }; List<SpawnIdentifierNet> list2 = new List<SpawnIdentifierNet>(); foreach (SpawnIdentifier item in list) { SpawnIdentifier spawnIdentifier = item; var (zone2, area, hazardType2) = (SpawnIdentifier)(ref spawnIdentifier); if (HazardManager.TryCreateSpawnerData(zone2, area, hazardType2, out var spawnIdentifierNet)) { list2.Add(spawnIdentifierNet); } } if (list2.Count > 0) { NetComm.Instance.CreateMultipleSpawnersNetwork(list2.ToArray()); } } [IteratorStateMachine(typeof(<CreateSpawnerTypes>d__7))] internal static IEnumerator CreateSpawnerTypes() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CreateSpawnerTypes>d__7(0); } [IteratorStateMachine(typeof(<LoadZone>d__8))] internal static IEnumerator LoadZone(Zone zoneToLoad) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadZone>d__8(0) { zoneToLoad = zoneToLoad }; } } } namespace HazardSpam.Spawning { public class FakeHazard : MonoBehaviour { } public static class SpawnerLogic { internal static (Vector3[] positions, Quaternion[] rotations) GenerateSpawnPoints(PropSpawner propSpawner, int attempts) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) int num = 0; int num2 = 0; int num3 = 0; List<Vector3> list = new List<Vector3>(); List<Quaternion> list2 = new List<Quaternion>(); MethodInfo method = ((object)propSpawner).GetType().GetMethod("GetRandomPoint", BindingFlags.Instance | BindingFlags.NonPublic); if (method == null) { Plugin.Log.LogColorE("Could not find GetRandomPoint method in PropSpawner."); } else { while (num < attempts && num2 < attempts * 2) { num2++; try { object obj = method.Invoke(propSpawner, null); if (obj != null) { Vector3 item = (Vector3)obj.GetType().GetField("pos").GetValue(obj); Vector3 val = (Vector3)obj.GetType().GetField("normal").GetValue(obj); Quaternion randomRotationWithUp = HelperFunctions.GetRandomRotationWithUp(val); list.Add(item); list2.Add(randomRotationWithUp); num++; } } catch (Exception) { num3++; } } } Plugin.Log.LogInfo((object)$"Generated {num} spawn points. Failed attempts: {num3}"); return (list.ToArray(), list2.ToArray()); } internal static (Vector3[] positions, Quaternion[] rotations) GenerateSpawnPoints(PropSpawner_Line propSpawnerLine, int attempts) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be