Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Outfall v0.2.2
NoteBoxz.Outfall.dll
Decompiled 7 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using DunGen; using DunGen.Graph; using DunGen.Tags; using GameNetcodeStuff; using HarmonyLib; using LethalLevelLoader; using Microsoft.CodeAnalysis; using NoteBoxz.Outfall.NetcodePatcher; using NotezyLib.Utils; using OutfallMod; using OutfallMod.Patches; using TMPro; using Unity.AI.Navigation; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("EasyTextEffects")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("LethalLevelLoader")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: AssemblyCompany("NoteBoxz.Outfall")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.2.2.0")] [assembly: AssemblyInformationalVersion("0.2.2")] [assembly: AssemblyProduct("OutfallMod")] [assembly: AssemblyTitle("NoteBoxz.Outfall")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] 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; } } } public class TestController : MonoBehaviour { public RuntimeDungeon Dungeon = null; public DungeonAdapt DungeonAdapt = null; public DungeonTileAdapt TileAdapt = null; private DungeonFlow originalFlow = null; private void Start() { AdaptDungeonDoors(); } [ContextMenu("Adapt Dungeon Doors and Regenerate Dungeon")] public void AdaptDungeonDoors() { if (((Object)Dungeon.Generator.DungeonFlow).name.EndsWith("_Adapted")) { Dungeon.Generator.DungeonFlow = originalFlow; } DungeonAdapt.FlowToUse = Dungeon.Generator.DungeonFlow; TileAdapt.FlowToUse = Dungeon.Generator.DungeonFlow; DungeonAdaptData adaptData = DungeonAdapt.Adapt(); TileAdapt.Adapt(adaptData); originalFlow = Dungeon.Generator.DungeonFlow; Dungeon.Generator.DungeonFlow = adaptData.AdaptedFlow; Dungeon.Generate(); } } namespace OutfallMod { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("NoteBoxz.Outfall", "OutfallMod", "0.2.2")] public class OutfallMod : BaseUnityPlugin { private readonly string targetSceneName = "NotezLevel3Outfall"; private bool isPatchActive = false; public static Vector3 InitEnvPos = new Vector3(0f, -1000f, 0f); public static Quaternion InitEnvRot = Quaternion.Euler(0f, 0f, 0f); public static Vector3 InitSLPpos = new Vector3(0f, -1000f, 0f); public static Quaternion InitSLProt = Quaternion.Euler(0f, 0f, 0f); public static RuntimeAnimatorController PrevShipAnimatorController = null; public static string[] BlacklistedDungeons = new string[2] { "Rubber Rooms", "PlayZone" }; public static OutfallMod Instance { get; private set; } = null; internal static ManualLogSource Logger { get; private set; } = null; internal static Harmony? PermanentHarmony { get; set; } internal static Harmony? DynamicHarmony { get; set; } public static List<ItemGroup> ItemGroups => Resources.FindObjectsOfTypeAll<ItemGroup>().ToList(); private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; Patch(); NetcodePatcher(); SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.sceneUnloaded += OnSceneUnloaded; Logger.LogInfo((object)"NoteBoxz.Outfall v0.2.2 has loaded!"); } internal static void SetShipAnimatorClips(ExtendedLevel extendedLevel) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown if ((Object)(object)PrevShipAnimatorController != (Object)null) { Logger.LogWarning((object)"Ship animator clips are already set!"); return; } AnimatorOverrideController val = new AnimatorOverrideController(StartOfRound.Instance.shipAnimator.runtimeAnimatorController); ((Object)val).name = "OutfallShipAnimatorOverride"; val["HangarShipLandB"] = extendedLevel.ShipFlyToMoonClip; val["ShipLeave"] = extendedLevel.ShipFlyFromMoonClip; PrevShipAnimatorController = StartOfRound.Instance.shipAnimator.runtimeAnimatorController; StartOfRound.Instance.shipAnimator.runtimeAnimatorController = (RuntimeAnimatorController)(object)val; Logger.LogInfo((object)("Set ship animator clips from ExtendedLevel! " + ((Object)extendedLevel).name + " PrevShipAnimatorController: " + ((Object)PrevShipAnimatorController).name + " ShipAnimator: " + ((Object)StartOfRound.Instance.shipAnimator.runtimeAnimatorController).name)); } internal static void ClearShipAnimatorClips() { if ((Object)(object)PrevShipAnimatorController != (Object)null) { StartOfRound.Instance.shipAnimator.runtimeAnimatorController = PrevShipAnimatorController; PrevShipAnimatorController = null; Logger.LogInfo((object)("Setting ship animator clips to defaults! " + ((Object)StartOfRound.Instance.shipAnimator.runtimeAnimatorController).name)); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown if (!(((Scene)(ref scene)).name == targetSceneName) || isPatchActive) { return; } if (DynamicHarmony == null) { DynamicHarmony = new Harmony("NoteBoxz.Outfall.dynamic"); } IEnumerable<Type> enumerable = from t in Assembly.GetExecutingAssembly().GetTypes() where t.Namespace == "OutfallMod.MoonPatches" select t; foreach (Type item in enumerable) { DynamicHarmony.PatchAll(item); } isPatchActive = true; Logger.LogInfo((object)("Dynamic patches applied for " + targetSceneName)); } private void OnSceneUnloaded(Scene scene) { if (((Scene)(ref scene)).name == targetSceneName && isPatchActive) { CleanUpBeforeUnPatch(); Harmony? dynamicHarmony = DynamicHarmony; if (dynamicHarmony != null) { dynamicHarmony.UnpatchSelf(); } isPatchActive = false; Logger.LogInfo((object)("Dynamic patches removed for " + targetSceneName)); } } internal static void Patch() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if (PermanentHarmony == null) { PermanentHarmony = new Harmony("NoteBoxz.Outfall.permanent"); } Logger.LogDebug((object)"Patching permanent patches..."); IEnumerable<Type> enumerable = from t in Assembly.GetExecutingAssembly().GetTypes() where t.Namespace == "OutfallMod.Patches" select t; foreach (Type item in enumerable) { PermanentHarmony.PatchAll(item); Logger.LogDebug((object)("Patched permanent type: " + item.Name)); } Logger.LogDebug((object)"Finished patching!"); } private void CleanUpBeforeUnPatch() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) ClearShipAnimatorClips(); GameObject val = GameObject.Find("Environment"); val.transform.position = InitEnvPos; val.transform.rotation = InitEnvRot; StartOfRound.Instance.shipLandingPosition.position = InitSLPpos; StartOfRound.Instance.shipLandingPosition.rotation = InitSLProt; } internal static void Unpatch() { Logger.LogDebug((object)"Unpatching all patches..."); Harmony? permanentHarmony = PermanentHarmony; if (permanentHarmony != null) { permanentHarmony.UnpatchSelf(); } Harmony? dynamicHarmony = DynamicHarmony; if (dynamicHarmony != null) { dynamicHarmony.UnpatchSelf(); } Logger.LogDebug((object)"Finished unpatching!"); } private void NetcodePatcher() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); Type[] array = types; foreach (Type type in array) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { methodInfo.Invoke(null, null); } } } } } public class DungeonAdapt : MonoBehaviour { [Tooltip("The TileSet to use for the ship landing area")] public TileSet ShipLandTileSet = null; [Tooltip("The DungeonFlow to adapt")] public DungeonFlow FlowToUse = null; private DungeonFlow dupedFlow = null; public DungeonAdaptData Adapt() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Invalid comparison between Unknown and I4 LogInfo("[DungeonAdapt] Starting adaptation of flow: " + ((Object)FlowToUse).name); dupedFlow = Object.Instantiate<DungeonFlow>(FlowToUse); GraphNode val = null; bool flag = false; foreach (GraphNode node in FlowToUse.Nodes) { if ((int)node.NodeType == 2) { LogInfo($"[DungeonAdapt] Found goal node with {node.TileSets.Count} tilesets, checking for cap tiles"); val = node; flag = HasCapTiles(node); if (flag) { LogInfo("[DungeonAdapt] Goal node has cap tiles"); } break; } } if (val == null) { LogError("[DungeonAdapt] No Goal Node found in DungeonFlow!"); return default(DungeonAdaptData); } GraphNode val2 = DupeGraphNode(val); val2.TileSets.Add(ShipLandTileSet); LogInfo("[DungeonAdapt] Created ship landing node with tileset: " + ((Object)ShipLandTileSet).name); GraphNode val3 = null; if (flag) { LogInfo("[DungeonAdapt] Cap tiles detected - placing ship landing node after start node"); int num = -1; for (int i = 0; i < dupedFlow.Nodes.Count; i++) { if ((int)dupedFlow.Nodes[i].NodeType == 1) { num = i; val3 = dupedFlow.Nodes[i]; LogInfo($"[DungeonAdapt] Found start node at index {i}"); break; } } if (num >= 0) { dupedFlow.Nodes.Insert(num + 1, val2); LogInfo($"[DungeonAdapt] Inserted ship landing node at position {num + 1}"); } else { dupedFlow.Nodes.Add(val2); LogWarning("[DungeonAdapt] No start node found, added ship landing node to the end"); } } else { dupedFlow.Nodes.Add(val2); val3 = val; LogInfo("[DungeonAdapt] Added ship landing node to the end of the flow"); } ((Object)dupedFlow).name = ((Object)FlowToUse).name + "_Adapted"; LogInfo($"[DungeonAdapt] Adaptation complete. New flow: {((Object)dupedFlow).name} with {dupedFlow.Nodes.Count} nodes connecting to {val3.NodeType}"); DungeonAdaptData result = default(DungeonAdaptData); result.OriginalFlow = FlowToUse; result.AdaptedFlow = dupedFlow; result.NodeConnectingToShipLand = val3; return result; } public GraphNode DupeGraphNode(GraphNode original) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) if (original == null) { LogError("[DungeonAdapt] Attempted to duplicate a null GraphNode!"); return null; } LogInfo($"[DungeonAdapt] Duplicating node of type {original.NodeType} with {original.TileSets.Count} tilesets"); GraphNode val = new GraphNode(original.Graph); val.TileSets = new List<TileSet>(); val.NodeType = original.NodeType; val.Position = original.Position; val.Label = original.Label + "_Duplicated"; val.LockPlacement = original.LockPlacement; return val; } private bool HasCapTiles(GraphNode node) { if (node.TileSets.Count == 0) { return false; } int num = 0; int num2 = 0; foreach (TileSet tileSet in node.TileSets) { if (tileSet.TileWeights.Weights.Count == 0) { continue; } num = 0; LogInfo("[DungeonAdapt] Checking TileSet: " + ((Object)tileSet).name + " for cap tiles"); foreach (GameObjectChance weight in tileSet.TileWeights.Weights) { bool flag = false; Tile componentInChildren = weight.Value.GetComponentInChildren<Tile>(); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.Entrance != (Object)null && (Object)(object)componentInChildren.Exit == (Object)null) { LogInfo("[DungeonAdapt] Found cap tile: " + ((Object)weight.Value).name); num++; flag = true; } if (!flag && weight.Value.GetComponentsInChildren<Doorway>().Length == 1) { LogInfo("[DungeonAdapt] Found cap tile (1 doorway): " + ((Object)weight.Value).name); num++; } } LogInfo($"[DungeonAdapt] TileSet {((Object)tileSet).name} has {num}/{tileSet.TileWeights.Weights.Count} cap tiles"); if (num == tileSet.TileWeights.Weights.Count) { num2++; } } return num2 == node.TileSets.Count; } private void LogInfo(object message) { if (OutfallMod.Logger != null) { OutfallMod.Logger.LogInfo(message); } else { Debug.Log(message); } } private void LogWarning(object message) { if (OutfallMod.Logger != null) { OutfallMod.Logger.LogWarning(message); } else { Debug.LogWarning(message); } } private void LogError(object message) { if (OutfallMod.Logger != null) { OutfallMod.Logger.LogError(message); } else { Debug.LogError(message); } } } [Serializable] public struct DungeonAdaptData { public DungeonFlow OriginalFlow; public DungeonFlow AdaptedFlow; public GraphNode NodeConnectingToShipLand; } public class DungeonDoorwayModelAdapt : MonoBehaviour { public List<DoorwayModelAdaptInfo> DoorwayAdaptInfos = new List<DoorwayModelAdaptInfo>(); public Doorway[] Doorways = null; public void Start() { AdaptObjects(); } public void AdaptObjects() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) Doorway[] doorways = Doorways; foreach (Doorway val in doorways) { if (((Component)val).transform.childCount > 0) { OutfallMod.Logger.LogInfo((object)("[DungeonDoorwayModelAdapt] Doorway " + ((Object)val).name + " already has child objects, skipping adaptation.")); continue; } foreach (DoorwayModelAdaptInfo doorwayAdaptInfo in DoorwayAdaptInfos) { if (Vector2.Distance(doorwayAdaptInfo.doorSize, val.socket.size) < 0.1f) { GameObject val2 = Object.Instantiate<GameObject>(doorwayAdaptInfo.Object, ((Component)val).transform); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; OutfallMod.Logger.LogInfo((object)$"[DungeonDoorwayModelAdapt] Adapted doorway {((Object)val).name} with object {((Object)val2).name} for socket size {val.socket.size}."); break; } } } } } [Serializable] public struct DoorwayModelAdaptInfo { public Vector2 doorSize; public GameObject Object; } public class DungeonStartingTitleProps : MonoBehaviour { public Transform ShipLandingPosition = null; public Transform ShipGroundLandingPosition = null; public Transform DropshipLandingPosition = null; public bool RoofOpen = false; public Animator Animator = null; public AudioClip RoofOpenSound = null; public AudioClip RoofCloseSound = null; public AudioSource AudioSource = null; public void ToggleRoof(bool open) { if (RoofOpen == open) { return; } RoofOpen = open; if ((Object)(object)Animator != (Object)null) { if (open) { Animator.Play("OpenRoof"); AudioSource.PlayOneShot(RoofOpenSound); } else { Animator.Play("CloseRoof"); AudioSource.PlayOneShot(RoofCloseSound); } } } } public class DungeonTileAdapt : MonoBehaviour { [Tooltip("The landing prefab that needs doorway adaptation")] public GameObject LandPrefab = null; [Tooltip("The dungeon flow to extract socket types from")] public DungeonFlow FlowToUse = null; public DungeonAdaptData AdaptData = default(DungeonAdaptData); public void Adapt(DungeonAdaptData adaptData) { AdaptData = adaptData; LogInfo("[DungeonTileAdapt] Starting doorway adaptation process for " + ((Object)LandPrefab).name); AdaptDoorways(); LogInfo("[DungeonTileAdapt] Starting tag adaptation process for " + ((Object)LandPrefab).name); AdaptTags(); } public void AdaptDoorways() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 TileSet val = null; foreach (GraphNode node in FlowToUse.Nodes) { if ((int)node.NodeType != 2) { continue; } LogInfo($"[DungeonTileAdapt] Found goal node with {node.TileSets?.Count ?? 0} tile sets"); if (node.TileSets == null) { LogWarning($"[DungeonTileAdapt] Node {FlowToUse.Nodes.IndexOf(node)} has null TileSets"); continue; } if (node.TileSets.Count == 0) { LogWarning($"[DungeonTileAdapt] Node {FlowToUse.Nodes.IndexOf(node)} has no TileSets"); continue; } foreach (TileSet tileSet in node.TileSets) { if ((Object)(object)tileSet != (Object)null) { val = tileSet; LogInfo("[DungeonTileAdapt] Found valid ending tileset: " + ((Object)tileSet).name); break; } } } if ((Object)(object)val == (Object)null) { LogError("[DungeonTileAdapt] No Ending TileSet found in DungeonFlow Goal Node!"); return; } if (val.TileWeights.Weights.Count == 0) { LogError("[DungeonTileAdapt] EndingTileSet has no tiles assigned!"); return; } int num = -1; for (int i = 0; i < val.TileWeights.Weights.Count; i++) { if ((Object)(object)val.TileWeights.Weights[i].Value != (Object)null) { num = i; LogInfo($"[DungeonTileAdapt] Found non-null tile at index {i}"); break; } } if (num == -1) { LogError("[DungeonTileAdapt] EndingTileSet has no valid (non-null) tiles assigned!"); return; } List<DoorwaySocket> list = new List<DoorwaySocket>(); Doorway[] componentsInChildren = val.TileWeights.Weights[num].Value.GetComponentsInChildren<Doorway>(); foreach (Doorway val2 in componentsInChildren) { if ((Object)(object)val2.Socket == (Object)null) { LogWarning("[DungeonTileAdapt] Doorway " + ((Object)val2).name + " has no socket assigned"); continue; } list.Add(val2.Socket); LogInfo("[DungeonTileAdapt] Found socket: " + ((Object)val2.Socket).name + " in doorway " + ((Object)val2).name); } if (list.Count == 0) { LogError("[DungeonTileAdapt] No Doorways with valid Sockets found in EndingTileSet tile!"); return; } Doorway[] componentsInChildren2 = LandPrefab.GetComponentsInChildren<Doorway>(); LogInfo($"[DungeonTileAdapt] Found {componentsInChildren2.Length} doorways in land prefab and {list.Count} available sockets"); for (int k = 0; k < componentsInChildren2.Length; k++) { Doorway val3 = componentsInChildren2[k]; FieldInfo field = typeof(Doorway).GetField("socket", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { int index = Mathf.Clamp(k, 0, list.Count - 1); field.SetValue(val3, list[index]); LogInfo("[DungeonTileAdapt] Assigned socket '" + ((Object)list[index]).name + "' to doorway '" + ((Object)val3).name + "'"); } else { LogError("[DungeonTileAdapt] Could not find 'socket' field on Doorway using reflection"); } } LogInfo("[DungeonTileAdapt] Doorway adaptation completed successfully"); } public void AdaptTags() { //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Expected O, but got Unknown //IL_06a1: Unknown result type (might be due to invalid IL or missing references) //IL_06a7: Invalid comparison between Unknown and I4 //IL_0720: Unknown result type (might be due to invalid IL or missing references) //IL_0726: Invalid comparison between Unknown and I4 //IL_0816: Unknown result type (might be due to invalid IL or missing references) //IL_081d: Expected O, but got Unknown //IL_082e: Unknown result type (might be due to invalid IL or missing references) //IL_0835: Expected O, but got Unknown //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Invalid comparison between Unknown and I4 //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_04f1: Invalid comparison between Unknown and I4 Tile component = LandPrefab.GetComponent<Tile>(); if ((Object)(object)component == (Object)null) { LogError("[DungeonTileAdapt] LandPrefab does not have a Tile component!"); return; } if (AdaptData.NodeConnectingToShipLand == null) { LogError("[DungeonTileAdapt] NodeConnectingToShipLand is null!"); return; } if (AdaptData.NodeConnectingToShipLand.TileSets == null || AdaptData.NodeConnectingToShipLand.TileSets.Count == 0) { LogError("[DungeonTileAdapt] NodeConnectingToShipLand has no TileSets!"); return; } bool flag = false; foreach (TileSet tileSet in AdaptData.NodeConnectingToShipLand.TileSets) { if ((Object)(object)tileSet == (Object)null || tileSet.TileWeights == null) { continue; } foreach (GameObjectChance weight in tileSet.TileWeights.Weights) { if ((Object)(object)weight.Value == (Object)null) { continue; } Tile componentInChildren = weight.Value.GetComponentInChildren<Tile>(); if (!((Object)(object)componentInChildren == (Object)null)) { Doorway[] componentsInChildren = ((Component)componentInChildren).GetComponentsInChildren<Doorway>(); if (componentsInChildren.Length > 1 && (!((Object)(object)componentInChildren.Entrance != (Object)null) || !((Object)(object)componentInChildren.Exit == (Object)null)) && componentInChildren.Tags != null && componentInChildren.Tags.Tags.Count > 0) { flag = true; break; } } } if (!flag) { continue; } break; } if (!flag) { LogInfo("[DungeonTileAdapt] Dungeon flow doesn't use tags (no tags found in any tiles). Skipping tag adaptation."); component.Tags.Tags.Clear(); return; } int num = 0; component.Tags.Tags.Clear(); component.Tags.Tags.Add(new Tag(num)); bool flag2 = true; List<int> list = new List<int>(); foreach (TileSet tileSet2 in AdaptData.NodeConnectingToShipLand.TileSets) { if ((Object)(object)tileSet2 == (Object)null || tileSet2.TileWeights == null) { continue; } foreach (GameObjectChance weight2 in tileSet2.TileWeights.Weights) { if ((Object)(object)weight2.Value == (Object)null) { continue; } Tile componentInChildren2 = weight2.Value.GetComponentInChildren<Tile>(); if ((Object)(object)componentInChildren2 == (Object)null) { continue; } Doorway[] componentsInChildren2 = ((Component)componentInChildren2).GetComponentsInChildren<Doorway>(); if (componentsInChildren2.Length <= 1) { LogInfo($"[DungeonTileAdapt] Skipping cap tile {((Object)componentInChildren2).name} with {componentsInChildren2.Length} doorways"); } else if ((Object)(object)componentInChildren2.Entrance != (Object)null && (Object)(object)componentInChildren2.Exit == (Object)null) { LogInfo("[DungeonTileAdapt] Skipping cap tile " + ((Object)componentInChildren2).name + " (has entrance but no exit)"); } else { if (componentInChildren2.Tags == null || componentInChildren2.Tags.Tags.Count == 0) { continue; } foreach (Tag tag in componentInChildren2.Tags) { if (!list.Contains(tag.ID)) { list.Add(tag.ID); } if (tag.ID != num) { LogInfo($"[DungeonTileAdapt] Candidate tile {((Object)componentInChildren2).name} tag {tag.ID} does not match land tile tag {num}"); continue; } bool flag3 = false; if ((int)FlowToUse.TileTagConnectionMode == 1) { foreach (TagPair tileConnectionTag in FlowToUse.TileConnectionTags) { if ((tileConnectionTag.TagA.ID == num && tileConnectionTag.TagB.ID == tag.ID) || (tileConnectionTag.TagA.ID == tag.ID && tileConnectionTag.TagB.ID == num)) { flag3 = true; break; } } } else if ((int)FlowToUse.TileTagConnectionMode == 0) { flag3 = true; foreach (TagPair tileConnectionTag2 in FlowToUse.TileConnectionTags) { if ((tileConnectionTag2.TagA.ID == num && tileConnectionTag2.TagB.ID == tag.ID) || (tileConnectionTag2.TagA.ID == tag.ID && tileConnectionTag2.TagB.ID == num)) { flag3 = false; break; } } } if (flag3) { continue; } flag2 = false; LogInfo($"[DungeonTileAdapt] Current tag {num} is valid for connection with tag {tag.ID}"); break; } if (!flag2) { break; } } } if (flag2) { continue; } break; } if (flag2) { LogInfo($"[DungeonTileAdapt] Current tag {num} is not valid for connections, attempting to adapt"); if (list.Count == 0) { LogError("[DungeonTileAdapt] No valid tags found to adapt to!"); return; } int num2 = -1; foreach (int item in list) { bool flag4 = true; if ((int)FlowToUse.TileTagConnectionMode == 0) { foreach (TagPair tileConnectionTag3 in FlowToUse.TileConnectionTags) { if (tileConnectionTag3.TagA.ID == item && tileConnectionTag3.TagB.ID == item) { flag4 = false; break; } } } if ((int)FlowToUse.TileTagConnectionMode == 0) { flag4 = false; foreach (TagPair tileConnectionTag4 in FlowToUse.TileConnectionTags) { if (tileConnectionTag4.TagA.ID == item && tileConnectionTag4.TagB.ID == item) { flag4 = true; break; } } } if (flag4) { num2 = item; break; } } if (num2 == -1 && list.Count > 0) { num2 = list[0]; LogWarning($"[DungeonTileAdapt] No tag that can connect with itself found, using tag ID {num2}"); } if (num2 != -1) { Tag val = new Tag(num2); if (val == (Tag)null) { val = new Tag(num2); } component.Tags.Tags.Clear(); component.Tags.Tags.Add(val); LogInfo($"[DungeonTileAdapt] Successfully adapted land tile tag from {num} to {num2}"); } else { LogError("[DungeonTileAdapt] Failed to find a valid tag ID to adapt to!"); } } else { LogInfo($"[DungeonTileAdapt] No tag adaptation needed, current tag {num} is valid"); } } private void LogInfo(object message) { if (OutfallMod.Logger != null) { OutfallMod.Logger.LogInfo(message); } else { Debug.Log(message); } } private void LogWarning(object message) { if (OutfallMod.Logger != null) { OutfallMod.Logger.LogWarning(message); } else { Debug.LogWarning(message); } } private void LogError(object message) { if (OutfallMod.Logger != null) { OutfallMod.Logger.LogError(message); } else { Debug.LogError(message); } } } [Serializable] public class GameObjectWithRarity { public GameObject gameObject = null; [Range(0f, 100f)] public int rarity; } public class OutfallMoonController : NetworkBehaviour { [CompilerGenerated] private sealed class <DoIntroRoofOpenClose>d__17 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public OutfallMoonController <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DoIntroRoofOpenClose>d__17(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitUntil((Func<bool>)(() => StartOfRound.Instance.shipDoorsEnabled)); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = (object)new WaitForSeconds(6f); <>1__state = 2; return true; case 2: <>1__state = -1; Object.FindObjectOfType<DungeonStartingTitleProps>()?.ToggleRoof(open: true); <>2__current = (object)new WaitUntil((Func<bool>)(() => StartOfRound.Instance.shipHasLanded)); <>1__state = 3; return true; case 3: <>1__state = -1; Object.FindObjectOfType<DungeonStartingTitleProps>()?.ToggleRoof(open: false); 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 <WaitPreventSoftlock>d__18 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public OutfallMoonController <>4__this; private DungeonStartingTitleProps <dungeonStartingTitleProps>5__1; private Doorway[] <doorways>5__2; private Doorway[] <>s__3; private int <>s__4; private Doorway <doorway>5__5; private DoorLock <doorLock>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitPreventSoftlock>d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <dungeonStartingTitleProps>5__1 = null; <doorways>5__2 = null; <>s__3 = null; <doorway>5__5 = null; <doorLock>5__6 = null; <>1__state = -2; } private bool MoveNext() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0121: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitUntil((Func<bool>)(() => StartOfRound.Instance.shipDoorsEnabled)); <>1__state = 1; return true; case 1: <>1__state = -1; <dungeonStartingTitleProps>5__1 = Object.FindObjectOfType<DungeonStartingTitleProps>(); if ((Object)(object)<dungeonStartingTitleProps>5__1 == (Object)null) { return false; } <doorways>5__2 = ((Component)<dungeonStartingTitleProps>5__1).GetComponentsInChildren<Doorway>(); <>s__3 = <doorways>5__2; for (<>s__4 = 0; <>s__4 < <>s__3.Length; <>s__4++) { <doorway>5__5 = <>s__3[<>s__4]; if (!((Object)(object)<doorway>5__5.DoorComponent == (Object)null) && ((Component)<doorway>5__5).transform.childCount <= 0) { OutfallMod.Logger.LogInfo((object)("[OutfallMoonController] Doorway " + ((Object)<doorway>5__5).name + " has no blocker and is connected to a door, checking for DoorLock")); <doorLock>5__6 = GeneralUtils.FindClosestInstanceOfScript<DoorLock>(((Component)<doorway>5__5.doorComponent).transform.position); if ((Object)(object)<doorLock>5__6 == (Object)null) { OutfallMod.Logger.LogWarning((object)("[OutfallMoonController] Could not find DoorLock for doorway " + ((Object)<doorway>5__5).name)); } else { if (<doorLock>5__6.isLocked) { OutfallMod.Logger.LogInfo((object)("[OutfallMoonController] Unlocking DoorLock " + ((Object)((Component)<doorLock>5__6).gameObject).name + " for doorway " + ((Object)<doorway>5__5).name + " to prevent softlock")); <doorLock>5__6.UnlockDoorClientRpc(); } <doorLock>5__6 = null; <doorway>5__5 = null; } } } <>s__3 = null; 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(); } } [Header("Terrain")] public TerrainGenerator terrainGenerator = null; public NavMeshSurface navMeshSurface = null; public GameObject MainFactory = null; [Header("Dungeon")] public DungeonAdapt dungeonAdapter = null; public DungeonTileAdapt DungeonTileAdapter = null; [HideInInspector] public DungeonFlow originalFlow = null; public GameObject Dropship = null; public GameObject ShipNM = null; public Dictionary<DungeonGenerator, (DungeonFlow, DungeonFlow)> FlowsToRemove = new Dictionary<DungeonGenerator, (DungeonFlow, DungeonFlow)>(); public List<Collider> DungeonColliders = new List<Collider>(); public Dictionary<Collider, LayerMask> OriginalColliderLayers = null; public static OutfallMoonController Instance { get; private set; } private void Awake() { Instance = this; terrainGenerator.seed = StartOfRoundPatch.randomTerrainSeed; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); terrainGenerator.GenerateTerrain(); stopwatch.Stop(); OutfallMod.Logger.LogInfo((object)$"Terrain generated in {stopwatch.ElapsedMilliseconds} ms with seed {terrainGenerator.seed}"); } private void Start() { ExtendedLevel currentExtendedLevel = LevelManager.CurrentExtendedLevel; OutfallMod.SetShipAnimatorClips(currentExtendedLevel); ((MonoBehaviour)this).StartCoroutine(DoIntroRoofOpenClose()); if (((NetworkBehaviour)StartOfRound.Instance).IsServer) { ((MonoBehaviour)this).StartCoroutine(WaitPreventSoftlock()); } } [IteratorStateMachine(typeof(<DoIntroRoofOpenClose>d__17))] private IEnumerator DoIntroRoofOpenClose() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DoIntroRoofOpenClose>d__17(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<WaitPreventSoftlock>d__18))] private IEnumerator WaitPreventSoftlock() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitPreventSoftlock>d__18(0) { <>4__this = this }; } public void Update() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (DungeonColliders.Count == 0) { return; } Bounds bounds = StartOfRound.Instance.shipBounds.bounds; if (((Bounds)(ref bounds)).Contains(((Component)StartOfRound.Instance.localPlayerController).transform.position) && !StartOfRound.Instance.shipHasLanded) { if (OriginalColliderLayers == null) { DisableDungeonColliders(); } } else if (OriginalColliderLayers != null) { RestoreDungeonColliders(); } } public void DisableDungeonColliders() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) OutfallMod.Logger.LogInfo((object)"[OutfallMoonController] Disabling dungeon colliders for local player inside detection"); if (OriginalColliderLayers != null) { OutfallMod.Logger.LogWarning((object)"[OutfallMoonController] OriginalColliderLayers is not null, skipping DisableDungeonColliders to avoid overwriting original layers"); return; } OriginalColliderLayers = new Dictionary<Collider, LayerMask>(); foreach (Collider dungeonCollider in DungeonColliders) { if (!dungeonCollider.isTrigger && !((Object)(object)dungeonCollider == (Object)null)) { OriginalColliderLayers[dungeonCollider] = dungeonCollider.excludeLayers; dungeonCollider.excludeLayers = LayerMask.op_Implicit(-32769); } } } public void RestoreDungeonColliders() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) OutfallMod.Logger.LogInfo((object)"[OutfallMoonController] Restoring dungeon colliders for local player inside detection"); if (OriginalColliderLayers == null) { OutfallMod.Logger.LogWarning((object)"[OutfallMoonController] OriginalColliderLayers is null, cannot restore dungeon colliders!"); return; } foreach (KeyValuePair<Collider, LayerMask> originalColliderLayer in OriginalColliderLayers) { Collider key = originalColliderLayer.Key; if (!key.isTrigger && !((Object)(object)key == (Object)null)) { key.excludeLayers = originalColliderLayer.Value; } } OriginalColliderLayers = null; } public override void OnDestroy() { ((NetworkBehaviour)this).OnDestroy(); PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { PlayerUtils.SetPlayerInside(val, false); } } protected override void __initializeVariables() { ((NetworkBehaviour)this).__initializeVariables(); } protected override void __initializeRpcs() { ((NetworkBehaviour)this).__initializeRpcs(); } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "OutfallMoonController"; } } public class PrefabReverbFixer : MonoBehaviour { public AudioReverbTrigger reverbTrigger = null; public List<string> entries = new List<string>(); public void Start() { PrefabReverbFixerManager.Instance.Fix(this); } } [Serializable] public class PrefabReverbFixerEntry { public string AudioSorceName = ""; } public class PrefabReverbFixerManager : MonoBehaviour { public static PrefabReverbFixerManager Instance; public List<AudioSource> ReverbAudioSources = new List<AudioSource>(); public void Awake() { Instance = this; } public void Fix(PrefabReverbFixer fixer) { for (int i = 0; i < fixer.entries.Count; i++) { string text = fixer.entries[i]; AudioSource val = null; foreach (AudioSource reverbAudioSource in ReverbAudioSources) { if (((Object)((Component)reverbAudioSource).gameObject).name == text) { val = reverbAudioSource; break; } } if ((Object)(object)val == (Object)null) { OutfallMod.Logger.LogWarning((object)("[PrefabReverbFixerManager] Could not find AudioSource named " + text + " for PrefabReverbFixer on " + ((Object)((Component)fixer).gameObject).name)); continue; } OutfallMod.Logger.LogInfo((object)("[PrefabReverbFixerManager] Setting AudioSource " + text + " for PrefabReverbFixer on " + ((Object)((Component)fixer).gameObject).name)); fixer.reverbTrigger.audioChanges[i].audio = val; } } } [Serializable] public struct PlayerSpawnArea { public Vector3 SpawnCenter; public float SpawnRadius; public GameObject SpawnBuilding; public Vector3 SpawnBuildingBounds; public float SpawnTerrainTransitionWidth; } [Serializable] public class TreeSettings { public GameObject placeholderTerrain = null; [Tooltip("Tree prefabs to use for painting")] public GameObject[] treePrefabs = (GameObject[])(object)new GameObject[0]; [Tooltip("Number of trees per square unit (higher = more dense forest)")] [Range(0.0001f, 0.05f)] public float treeDensity = 0.005f; [Tooltip("Minimum tree scale")] [Range(0.5f, 1f)] public float minScale = 0.8f; [Tooltip("Maximum tree scale")] [Range(1f, 3f)] public float maxScale = 1.2f; [Tooltip("How much to vary tree placement (0 = grid, 1 = fully random)")] [Range(0f, 1f)] public float randomness = 0.7f; [Tooltip("Prevent trees from spawning in this radius around the player spawn")] public float clearRadiusAroundSpawn = 20f; } public class TerrainGenerator : MonoBehaviour { [Tooltip("The terrain component to modify")] public Terrain terrain = null; [Tooltip("Reference terrain data to use as a template")] public TerrainData RefData = null; [Tooltip("NavMeshSurface to update after terrain generation")] public NavMeshSurface navMeshSurface = null; [Header("Generation Settings")] [Tooltip("Random seed for terrain generation - same seed produces the same terrain")] public int seed = 0; [Tooltip("Controls the scale of the noise pattern - larger values create bigger features")] public float noiseScale = 50f; [Tooltip("Controls the overall height of the terrain")] public float heightMultiplier = 0.05f; [Tooltip("Number of noise layers to combine - more layers add more detail but increase generation time")] [Range(1f, 8f)] public int octaves = 2; [Tooltip("How much each octave contributes to the overall shape - lower values create smoother terrain")] [Range(0f, 1f)] public float persistence = 0.25f; [Tooltip("How much detail is added at each octave - higher values create more rugged terrain")] public float lacunarity = 1f; [Tooltip("2D offset for the entire terrain pattern")] public Vector2 offset = Vector2.zero; [Header("Play Area Settings")] [Tooltip("Radius of the circular play area (0-1 where 1 is half the terrain width)")] [Range(0.1f, 1f)] public float playAreaRadius = 0.5f; [Tooltip("Height of the boundary outside the play area (0-1)")] [Range(0f, 1f)] public float boundaryHeight = 0.25f; [Tooltip("Width of the transition between play area and boundary (0-1)")] [Range(0f, 0.5f)] public float transitionWidth = 0.1f; [Header("Player Spawn Settings")] [Tooltip("Player spawn area configuration")] public PlayerSpawnArea spawnArea; [Tooltip("Minimum distance from center (0-1 as percentage of play area radius)")] [Range(0f, 1f)] public float minSpawnDistanceFromCenter = 0.1f; [Tooltip("Maximum distance from center (0-1 as percentage of play area radius)")] [Range(0f, 1f)] public float maxSpawnDistanceFromCenter = 0.7f; [Tooltip("Flattened area around spawn building (multiplier of building bounds)")] [Range(1f, 3f)] public float spawnFlatAreaMultiplier = 1.5f; [Tooltip("Height for the flattened spawn area (0-1)")] [Range(0f, 1f)] public float spawnAreaHeight = 0.2f; [Header("Node Placement")] [Tooltip("AI Node prefab to spawn in the world")] public GameObject aiNodePrefab = null; [Tooltip("Item Node prefab to spawn in the world")] public GameObject itemNodePrefab = null; [Tooltip("Grid spacing between nodes (in meters)")] public float nodeSpacing = 25f; [Tooltip("Margin from play area boundary (0-1 as percentage of play area radius)")] [Range(0f, 0.5f)] public float boundaryMargin = 0.1f; [Tooltip("Percentage chance for item nodes to spawn (0-100)")] [Range(0f, 100f)] public float itemNodeSpawnChance = 35f; [Header("Tree Settings")] public TreeSettings treeSettings = new TreeSettings(); private List<GameObject> aiNodes = new List<GameObject>(); private List<GameObject> itemNodes = new List<GameObject>(); private Random prng = null; private Vector3 selectedSpawnPosition; [ContextMenu("Generate Terrain")] public void GenerateTerrain() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)terrain == (Object)null || (Object)(object)RefData == (Object)null) { Debug.LogError((object)"Terrain or reference TerrainData is missing!"); return; } prng = new Random(seed); TerrainData val = Object.Instantiate<TerrainData>(RefData); ((Object)val).name = $"TerrainData_{seed}"; float[,] heightMap = GenerateHeightMap(val.heightmapResolution); selectedSpawnPosition = DetermineSpawnPosition(val); heightMap = FlattenSpawnArea(heightMap, val, selectedSpawnPosition); val.SetHeights(0, 0, heightMap); treeSettings.placeholderTerrain.SetActive(true); ((Behaviour)terrain).enabled = false; ((Collider)((Component)terrain).GetComponent<TerrainCollider>()).enabled = false; treeSettings.placeholderTerrain.GetComponent<Terrain>().terrainData = val; treeSettings.placeholderTerrain.GetComponent<TerrainCollider>().terrainData = val; navMeshSurface.BuildNavMesh(); PaintTrees(val); treeSettings.placeholderTerrain.SetActive(false); ((Behaviour)terrain).enabled = true; ((Collider)((Component)terrain).GetComponent<TerrainCollider>()).enabled = true; terrain.terrainData = val; ((Component)terrain).GetComponent<TerrainCollider>().terrainData = val; PositionSpawnBuilding(); navMeshSurface.BuildNavMesh(); PlaceNodesInGrid(); } private void PaintTrees(TerrainData terrainData) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) if (treeSettings.treePrefabs == null || treeSettings.treePrefabs.Length == 0) { return; } terrainData.treeInstances = (TreeInstance[])(object)new TreeInstance[0]; List<TreePrototype> list = new List<TreePrototype>(); GameObject[] treePrefabs = treeSettings.treePrefabs; foreach (GameObject val in treePrefabs) { if ((Object)(object)val != (Object)null) { TreePrototype item = new TreePrototype { prefab = val }; list.Add(item); } } if (list.Count == 0) { return; } terrainData.treePrototypes = list.ToArray(); Vector3 size = terrainData.size; float num = playAreaRadius * Mathf.Min(size.x, size.z) / 2f; Vector3 position = ((Component)terrain).transform.position; int num2 = Mathf.FloorToInt(size.x * size.z * treeSettings.treeDensity); List<TreeInstance> list2 = new List<TreeInstance>(); int num3 = StartOfRound.Instance.collidersRoomDefaultAndFoliage; if (num3 == 0) { num3 = -1; } Vector2 val2 = default(Vector2); Vector3 val3 = default(Vector3); RaycastHit val4 = default(RaycastHit); NavMeshHit val5 = default(NavMeshHit); for (int j = 0; j < num2; j++) { float num4 = Mathf.Sqrt(1f / treeSettings.treeDensity); int num5 = Mathf.CeilToInt(size.x / num4); int num6 = Mathf.CeilToInt(size.z / num4); int num7 = j % num5; int num8 = j / num5; if (num8 >= num6) { continue; } float num9 = (float)num7 / (float)num5; float num10 = (float)num8 / (float)num6; num9 += (float)(prng.NextDouble() - 0.5) * treeSettings.randomness / (float)num5; num10 += (float)(prng.NextDouble() - 0.5) * treeSettings.randomness / (float)num6; num9 = Mathf.Clamp01(num9); num10 = Mathf.Clamp01(num10); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); float num11 = Vector2.Distance(new Vector2(num9, num10), val2); float num12 = playAreaRadius / 2f; if (num11 > num12) { continue; } float num13 = spawnArea.SpawnCenter.x / size.x; float num14 = spawnArea.SpawnCenter.z / size.z; float num15 = treeSettings.clearRadiusAroundSpawn / size.x; if (!(Vector2.Distance(new Vector2(num9, num10), new Vector2(num13, num14)) < num15)) { float num16 = position.x + num9 * size.x; float num17 = position.z + num10 * size.z; ((Vector3)(ref val3))..ctor(num16, position.y + size.y * 2f, num17); if (Physics.Raycast(val3, Vector3.down, ref val4, size.y * 3f, num3) && NavMesh.SamplePosition(((RaycastHit)(ref val4)).point, ref val5, 5f, -1)) { ((NavMeshHit)(ref val5)).position = ((NavMeshHit)(ref val5)).position - Vector3.up * 0.1f; float num18 = (((NavMeshHit)(ref val5)).position.y - position.y) / size.y; TreeInstance val6 = default(TreeInstance); val6.position = new Vector3(num9, num18, num10); val6.prototypeIndex = prng.Next(0, list.Count); val6.widthScale = treeSettings.minScale + (float)prng.NextDouble() * (treeSettings.maxScale - treeSettings.minScale); val6.heightScale = treeSettings.minScale + (float)prng.NextDouble() * (treeSettings.maxScale - treeSettings.minScale); val6.color = Color32.op_Implicit(Color.white); val6.lightmapColor = Color32.op_Implicit(Color.white); val6.rotation = (float)prng.NextDouble() * MathF.PI * 2f; TreeInstance item2 = val6; list2.Add(item2); } } } terrainData.treeInstances = list2.ToArray(); } private void PlaceNodesInGrid() { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) foreach (GameObject aiNode in aiNodes) { if ((Object)(object)aiNode != (Object)null) { if (Application.isEditor) { Object.DestroyImmediate((Object)(object)aiNode); } else { Object.Destroy((Object)(object)aiNode); } } } foreach (GameObject itemNode in itemNodes) { if ((Object)(object)itemNode != (Object)null) { if (Application.isEditor) { Object.DestroyImmediate((Object)(object)itemNode); } else { Object.Destroy((Object)(object)itemNode); } } } aiNodes.Clear(); itemNodes.Clear(); if ((Object)(object)aiNodePrefab == (Object)null && (Object)(object)itemNodePrefab == (Object)null) { return; } Vector3 size = terrain.terrainData.size; Vector3 position = ((Component)terrain).transform.position; float num = playAreaRadius * Mathf.Min(size.x, size.z) / 2f; Vector3 val = position + new Vector3(size.x / 2f, 0f, size.z / 2f); float num2 = num * (1f - boundaryMargin); Vector3 val2 = val - new Vector3(num2, 0f, num2); Vector3 val3 = val + new Vector3(num2, 0f, num2); int num3 = 0; int num4 = 0; Vector3 val4 = default(Vector3); RaycastHit val5 = default(RaycastHit); NavMeshHit val6 = default(NavMeshHit); for (float num5 = val2.x; num5 <= val3.x; num5 += nodeSpacing) { num4 = 0; num3++; for (float num6 = val2.z; num6 <= val3.z; num6 += nodeSpacing) { num4++; ((Vector3)(ref val4))..ctor(num5, position.y + size.y, num6); float num7 = Vector2.Distance(new Vector2(val4.x, val4.z), new Vector2(val.x, val.z)); if (!(num7 <= num2) || !Physics.Raycast(val4, Vector3.down, ref val5, size.y * 2f) || !NavMesh.SamplePosition(((RaycastHit)(ref val5)).point, ref val6, 2f, -1)) { continue; } if ((Object)(object)aiNodePrefab != (Object)null) { GameObject val7 = Object.Instantiate<GameObject>(aiNodePrefab, ((NavMeshHit)(ref val6)).position, Quaternion.identity, ((Component)this).transform); ((Object)val7).name = $"AINode_R{num3}_C{num4}"; aiNodes.Add(val7); } if ((Object)(object)itemNodePrefab != (Object)null && (float)prng.Next(0, 101) < itemNodeSpawnChance) { GameObject val8 = Object.Instantiate<GameObject>(itemNodePrefab, ((NavMeshHit)(ref val6)).position, Quaternion.identity, ((Component)this).transform); ((Object)val8).name = $"ItemNode_R{num3}_C{num4}"; RandomScrapSpawn component = val8.GetComponent<RandomScrapSpawn>(); if ((Object)(object)component != (Object)null) { List<ItemGroup> itemGroups = OutfallMod.ItemGroups; component.spawnableItems = itemGroups[prng.Next(0, itemGroups.Count)]; } itemNodes.Add(val8); } } } } private Vector3 DetermineSpawnPosition(TerrainData terrainData) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) Vector3 size = terrainData.size; float num = playAreaRadius * Mathf.Min(size.x, size.z) / 2f; float num2 = minSpawnDistanceFromCenter * num; float num3 = maxSpawnDistanceFromCenter * num; float num4 = (float)(prng.NextDouble() * 2.0 * Math.PI); float num5 = num2 + (float)prng.NextDouble() * (num3 - num2); float num6 = size.x / 2f + Mathf.Cos(num4) * num5; float num7 = size.z / 2f + Mathf.Sin(num4) * num5; float num8 = num6 / size.x; float num9 = num7 / size.z; float num10 = terrain.SampleHeight(new Vector3(num6, 0f, num7)) + ((Component)terrain).transform.position.y; return new Vector3(num6, num10, num7); } private float[,] FlattenSpawnArea(float[,] heightMap, TerrainData terrainData, Vector3 spawnPosition) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)spawnArea.SpawnBuilding == (Object)null) { return heightMap; } Vector3 size = terrainData.size; int heightmapResolution = terrainData.heightmapResolution; if (spawnArea.SpawnBuildingBounds == Vector3.zero) { Renderer component = spawnArea.SpawnBuilding.GetComponent<Renderer>(); if ((Object)(object)component != (Object)null) { ref PlayerSpawnArea reference = ref spawnArea; Bounds bounds = component.bounds; reference.SpawnBuildingBounds = ((Bounds)(ref bounds)).size; } else { spawnArea.SpawnBuildingBounds = new Vector3(25f, 5f, 25f); } } Vector3 val = spawnArea.SpawnBuildingBounds * spawnFlatAreaMultiplier; float num = Mathf.Max(val.x, val.z) / 2f; float num2 = (float)(heightmapResolution - 1) / size.x; int num3 = Mathf.RoundToInt(spawnPosition.x / size.x * (float)(heightmapResolution - 1)); int num4 = Mathf.RoundToInt(spawnPosition.z / size.z * (float)(heightmapResolution - 1)); int num5 = Mathf.RoundToInt(num * num2); int num6 = Mathf.RoundToInt((num + spawnArea.SpawnTerrainTransitionWidth) * num2); float num7 = spawnAreaHeight; for (int i = Mathf.Max(0, num4 - num6); i < Mathf.Min(heightmapResolution, num4 + num6); i++) { for (int j = Mathf.Max(0, num3 - num6); j < Mathf.Min(heightmapResolution, num3 + num6); j++) { float num8 = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)num3, (float)num4)); if (num8 < (float)num5) { heightMap[i, j] = num7; } else if (num8 < (float)num6) { float num9 = (num8 - (float)num5) / (float)(num6 - num5); heightMap[i, j] = Mathf.Lerp(num7, heightMap[i, j], num9); } } } return heightMap; } private void PositionSpawnBuilding() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)spawnArea.SpawnBuilding == (Object)null)) { spawnArea.SpawnCenter = selectedSpawnPosition; Vector3 val = ((Component)this).transform.position + spawnArea.SpawnCenter; float num = terrain.SampleHeight(new Vector3(val.x, 0f, val.z)) + ((Component)terrain).transform.position.y; float num2 = num; Renderer component = spawnArea.SpawnBuilding.GetComponent<Renderer>(); if ((Object)(object)component != (Object)null) { Bounds localBounds = component.localBounds; float num3 = ((Bounds)(ref localBounds)).center.y - ((Bounds)(ref localBounds)).extents.y; num2 -= num3; } spawnArea.SpawnBuilding.transform.position = new Vector3(val.x, num2, val.z); if (spawnArea.SpawnBuildingBounds != Vector3.zero) { Vector3 val2 = spawnArea.SpawnBuildingBounds * spawnFlatAreaMultiplier; spawnArea.SpawnRadius = Mathf.Max(val2.x, val2.z) / 2f; } } } private float[,] GenerateHeightMap(int resolution) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) float[,] array = new float[resolution, resolution]; Vector2[] array2 = (Vector2[])(object)new Vector2[octaves]; for (int i = 0; i < octaves; i++) { float num = (float)prng.Next(-100000, 100000) + offset.x; float num2 = (float)prng.Next(-100000, 100000) + offset.y; array2[i] = new Vector2(num, num2); } if (noiseScale <= 0f) { noiseScale = 0.0001f; } Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor((float)resolution / 2f, (float)resolution / 2f); float num3 = Vector2.Distance(val, Vector2.zero); float num4 = playAreaRadius * num3; float num5 = num4 - transitionWidth * num3; float num6 = num4; for (int j = 0; j < resolution; j++) { for (int k = 0; k < resolution; k++) { float num7 = Vector2.Distance(new Vector2((float)k, (float)j), val); float num8 = 1f; float num9 = 1f; float num10 = 0f; for (int l = 0; l < octaves; l++) { float num11 = (float)k / noiseScale * num9 + array2[l].x; float num12 = (float)j / noiseScale * num9 + array2[l].y; float num13 = Mathf.PerlinNoise(num11, num12) * 2f - 1f; num10 += num13 * num8; num8 *= persistence; num9 *= lacunarity; } float num14 = Mathf.Clamp01((num10 + 1f) / 2f * heightMultiplier); if (num7 > num6) { array[j, k] = boundaryHeight; } else if (num7 > num5) { float num15 = (num7 - num5) / (num6 - num5); array[j, k] = Mathf.Lerp(num14, boundaryHeight, num15); } else { array[j, k] = num14; } } } return array; } public void OnDrawGizmos() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)spawnArea.SpawnBuilding != (Object)null) { Gizmos.color = Color.green; Gizmos.DrawWireSphere(spawnArea.SpawnCenter, spawnArea.SpawnRadius); Gizmos.color = Color.yellow; Gizmos.DrawWireCube(spawnArea.SpawnCenter, spawnArea.SpawnBuildingBounds * spawnFlatAreaMultiplier); } if (!((Object)(object)terrain != (Object)null) || !((Object)(object)terrain.terrainData != (Object)null)) { return; } Vector3 size = terrain.terrainData.size; Vector3 position = ((Component)terrain).transform.position; float num = playAreaRadius * Mathf.Min(size.x, size.z) / 2f; Vector3 val = position + new Vector3(size.x / 2f, 0f, size.z / 2f); Gizmos.color = Color.cyan; Gizmos.DrawWireSphere(val, num); if (!(nodeSpacing > 0f)) { return; } float num2 = num * (1f - boundaryMargin); Gizmos.color = Color.blue; Vector3 val2 = val - new Vector3(num2, 0f, num2); Vector3 val3 = val + new Vector3(num2, 0f, num2); Vector3 val4 = default(Vector3); for (float num3 = val2.x; num3 <= val3.x; num3 += nodeSpacing) { for (float num4 = val2.z; num4 <= val3.z; num4 += nodeSpacing) { ((Vector3)(ref val4))..ctor(num3, position.y + 5f, num4); float num5 = Vector2.Distance(new Vector2(val4.x, val4.z), new Vector2(val.x, val.z)); if (num5 <= num2) { Gizmos.DrawWireCube(val4, Vector3.one * 2f); } } } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "NoteBoxz.Outfall"; public const string PLUGIN_NAME = "OutfallMod"; public const string PLUGIN_VERSION = "0.2.2"; } } namespace OutfallMod.Patches { [HarmonyPatch(typeof(GameNetworkManager))] public class GameNetworkManagerPatch { [CompilerGenerated] private sealed class <waitForWriter>d__2 : 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 <waitForWriter>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitUntil((Func<bool>)(() => (Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.CustomMessagingManager != null)); <>1__state = 1; return true; case 1: <>1__state = -1; StartOfRoundPatch.RegisterNetworkHandlers(); OutfallMod.Logger.LogInfo((object)"OutfallMod: Registered custom network handlers."); 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(); } } public static bool HasRegistred; [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPostfix(GameNetworkManager __instance) { if (HasRegistred) { OutfallMod.Logger.LogWarning((object)"OutfallMod: Already registered prefabs to Network."); return; } ((MonoBehaviour)__instance).StartCoroutine(waitForWriter()); HasRegistred = true; } [IteratorStateMachine(typeof(<waitForWriter>d__2))] public static IEnumerator waitForWriter() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <waitForWriter>d__2(0); } } [HarmonyPatch(typeof(StartOfRound))] public class StartOfRoundPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static HandleNamedMessageDelegate <>9__3_0; internal void <RegisterNetworkHandlers>b__3_0(ulong senderId, FastBufferReader reader) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) OutfallMod.Logger.LogMessage((object)"[OutfallMod] Client received terrain seed sync message from server."); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref randomTerrainSeed, default(ForPrimitives)); } } public static int randomTerrainSeed = -1; [HarmonyPatch("Start")] [HarmonyPrefix] public static void Start_Prefix(StartOfRound __instance) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.Find("Environment"); OutfallMod.InitEnvPos = val.transform.position; OutfallMod.InitEnvRot = val.transform.rotation; OutfallMod.InitSLPpos = __instance.shipLandingPosition.position; OutfallMod.InitSLProt = __instance.shipLandingPosition.rotation; } [HarmonyPatch("StartGame")] [HarmonyPrefix] public static void StartGame_Postfix(StartOfRound __instance) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)__instance).IsServer && !(__instance.currentLevel.sceneName != "NotezLevel3Outfall") && __instance.inShipPhase) { randomTerrainSeed = Random.Range(1, 100000000); if ((Object)(object)NetworkManager.Singleton != (Object)null) { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1); ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref randomTerrainSeed, default(ForPrimitives)); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("SyncTerrainSeed", val, (NetworkDelivery)3); } } } public static void RegisterNetworkHandlers() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown if (!((Object)(object)NetworkManager.Singleton != (Object)null)) { return; } CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager; object obj = <>c.<>9__3_0; if (obj == null) { HandleNamedMessageDelegate val = delegate(ulong senderId, FastBufferReader reader) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) OutfallMod.Logger.LogMessage((object)"[OutfallMod] Client received terrain seed sync message from server."); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref randomTerrainSeed, default(ForPrimitives)); }; <>c.<>9__3_0 = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler("SyncTerrainSeed", (HandleNamedMessageDelegate)obj); } [HarmonyPatch("SceneManager_OnLoad")] [HarmonyPostfix] public static void SceneManager_OnLoad_Postfix(StartOfRound __instance) { try { if (__instance.currentLevel.sceneName == "NotezLevel3Outfall") { ((TMP_Text)HUDManager.Instance.loadingText).text = $"LOADING WORLD, Terrain seed: {randomTerrainSeed}"; } } catch (Exception arg) { OutfallMod.Logger.LogError((object)$"Error in StartOfRound.SceneManager_OnLoad_Postfix: {arg}"); } } } } namespace OutfallMod.MoonPatches { [HarmonyPatch(typeof(DungeonLoader))] public class DungeonLoaderPatch { [HarmonyPatch("PrepareDungeon")] [HarmonyPostfix] public static void PrepareDungeonostfix() { try { if (!((Object)(object)OutfallMoonController.Instance == (Object)null)) { OutfallMod.Logger.LogMessage((object)"!!!OVERIDING DUNGEN!!!"); RuntimeDungeon dungeonGenerator = RoundManager.Instance.dungeonGenerator; if (((Object)dungeonGenerator.Generator.DungeonFlow).name.EndsWith("_Adapted")) { dungeonGenerator.Generator.DungeonFlow = OutfallMoonController.Instance.originalFlow; } OutfallMoonController.Instance.dungeonAdapter.FlowToUse = dungeonGenerator.Generator.DungeonFlow; OutfallMoonController.Instance.DungeonTileAdapter.FlowToUse = dungeonGenerator.Generator.DungeonFlow; DungeonAdaptData adaptData = OutfallMoonController.Instance.dungeonAdapter.Adapt(); OutfallMoonController.Instance.DungeonTileAdapter.Adapt(adaptData); OutfallMoonController.Instance.originalFlow = dungeonGenerator.Generator.DungeonFlow; dungeonGenerator.Generator.DungeonFlow = adaptData.AdaptedFlow; OutfallMoonController.Instance.FlowsToRemove[dungeonGenerator.Generator] = (OutfallMoonController.Instance.originalFlow, dungeonGenerator.Generator.DungeonFlow); } } catch (Exception arg) { OutfallMod.Logger.LogError((object)$"Error in DungeonLoader.Generate Postfix: {arg}"); } } } [HarmonyPatch(typeof(DungeonManager))] public class DungeonManagerPatch { [HarmonyPatch("GetValidExtendedDungeonFlows")] [HarmonyPostfix] private static void FilterDungeonFlows(ref List<ExtendedDungeonFlowWithRarity> __result, ExtendedLevel extendedLevel) { if (__result != null && (!((Object)(object)extendedLevel.SelectableLevel != (Object)null) || !(extendedLevel.SelectableLevel.sceneName != "NotezLevel3Outfall"))) { int count = __result.Count; __result = __result.Where((ExtendedDungeonFlowWithRarity flow) => !OutfallMod.BlacklistedDungeons.Contains(flow.extendedDungeonFlow.DungeonName)).ToList(); int count2 = __result.Count; OutfallMod.Logger.LogDebug((object)("[OutfallMod] Filtered DungeonManager.GetValidExtendedDungeonFlows for Outfall. " + $"Removed {count - count2} flows. Remaining flows: ({count2}/{count})")); } } } [HarmonyPatch(typeof(ItemDropship))] public class ItemDropshipPatch { [CompilerGenerated] private sealed class <WaitToToggleRoof>d__2 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private DungeonStartingTitleProps <DSTP>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitToToggleRoof>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <DSTP>5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(3f); <>1__state = 1; return true; case 1: <>1__state = -1; <DSTP>5__1 = Object.FindObjectOfType<DungeonStartingTitleProps>(); if ((Object)(object)<DSTP>5__1 == (Object)null) { OutfallMod.Logger.LogError((object)"DSTP is null, cannot toggle roof after dropship leaves!"); return false; } <DSTP>5__1.ToggleRoof(open: false); 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("LandShipClientRpc")] [HarmonyPrefix] public static void LandShipClientPreFix(ItemDropship __instance) { if (GeneralUtils.IsClientRpcPrefixValid((NetworkBehaviour)(object)__instance)) { Object.FindObjectOfType<DungeonStartingTitleProps>()?.ToggleRoof(open: true); } } [HarmonyPatch("ShipLeave")] [HarmonyPrefix] public static void ShipLeavePrefix(ItemDropship __instance) { ((MonoBehaviour)__instance).StartCoroutine(WaitToToggleRoof()); } [IteratorStateMachine(typeof(<WaitToToggleRoof>d__2))] public static IEnumerator WaitToToggleRoof() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitToToggleRoof>d__2(0); } } [HarmonyPatch(typeof(RoundManager))] public class RoundManagerPatch { [HarmonyPatch("FinishGeneratingLevel")] [HarmonyPriority(800)] [HarmonyPrefix] public static void FinishGeneratingLevel_Prefix(RoundManager __instance) { if ((Object)(object)OutfallMoonController.Instance == (Object)null) { return; } int num = 0; RandomScrapSpawn[] array = Object.FindObjectsByType<RandomScrapSpawn>((FindObjectsSortMode)0); foreach (RandomScrapSpawn val in array) { if ((Object)(object)((Component)val).gameObject.GetComponentInParent<TerrainGenerator>() == (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); num++; } } foreach (KeyValuePair<DungeonGenerator, (DungeonFlow, DungeonFlow)> item in OutfallMoonController.Instance.FlowsToRemove) { item.Key.DungeonFlow = item.Value.Item1; Object.Destroy((Object)(object)item.Value.Item2); } OutfallMod.Logger.LogInfo((object)$"Disabled {num} RandomScrapSpawn objects to prevent conflicts with Outfall terrain."); } [HarmonyPatch("FinishGeneratingNewLevelClientRpc")] [HarmonyPrefix] private static void FinishGeneratingNewLevelClientRpcPrefix(RoundManager __instance) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) try { if (!GeneralUtils.IsClientRpcPrefixValid((NetworkBehaviour)(object)__instance)) { return; } OutfallMod.Logger.LogMessage((object)"Positioning environment and dropship for Outfall Moon"); GameObject val = null; Scene val2 = SceneManager.GetSceneByName("SampleSceneRelay"); if (!((Scene)(ref val2)).IsValid()) { val2 = SceneManager.GetActiveScene(); OutfallMod.Logger.LogWarning((object)"SampleSceneRelay scene not found, using active scene instead"); } GameObject[] rootGameObjects = ((Scene)(ref val2)).GetRootGameObjects(); OutfallMod.Logger.LogMessage((object)$"Searching through {rootGameObjects.Length} root GameObjects for environment with HangarShip"); GameObject[] array = rootGameObjects; foreach (GameObject val3 in array) { Transform val4 = val3.transform.Find("HangarShip"); if ((Object)(object)val4 != (Object)null) { val = val3; OutfallMod.Logger.LogMessage((object)("Found environment with HangarShip child: " + ((Object)val3).name)); break; } } if ((Object)(object)val == (Object)null) { OutfallMod.Logger.LogError((object)"Could not find Environment object by any method!"); return; } DungeonStartingTitleProps dungeonStartingTitleProps = Object.FindObjectOfType<DungeonStartingTitleProps>(); if ((Object)(object)dungeonStartingTitleProps == (Object)null) { OutfallMod.Logger.LogError((object)"DSTP is null, cannot position environment and dropship!"); return; } val.transform.position = ((Component)dungeonStartingTitleProps.ShipLandingPosition).transform.position; val.transform.rotation = ((Component)dungeonStartingTitleProps.ShipLandingPosition).transform.rotation; OutfallMoonController.Instance.Dropship.transform.position = ((Component)dungeonStartingTitleProps.DropshipLandingPosition).transform.position; OutfallMoonController.Instance.Dropship.transform.rotation = ((Component)dungeonStartingTitleProps.DropshipLandingPosition).transform.rotation; StartOfRound.Instance.shipLandingPosition.position = ((Component)dungeonStartingTitleProps.ShipGroundLandingPosition).transform.position; StartOfRound.Instance.shipLandingPosition.rotation = ((Component)dungeonStartingTitleProps.ShipGroundLandingPosition).transform.rotation; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val5 in allPlayerScripts) { PlayerUtils.SetPlayerInside(val5, true); } OutfallMoonController.Instance.DungeonColliders.AddRange(__instance.dungeonGenerator.Root.GetComponentsInChildren<Collider>()); } catch (Exception arg) { OutfallMod.Logger.LogError((object)$"Error in FinishGeneratingNewLevelClientRpcPostfix: {arg}"); } } [HarmonyPatch("SyncScrapValuesClientRpc")] [HarmonyPrefix] public static void SyncScrapValuesClientRpcPrefix(RoundManager __instance, NetworkObjectReference[] spawnedScrap) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!GeneralUtils.IsClientRpcPrefixValid((NetworkBehaviour)(object)__instance)) { return; } OutfallMod.Logger.LogMessage((object)$"Seetting Scrap as not in factory for {spawnedScrap.Length} spawned scrap objects"); NetworkObject val2 = default(NetworkObject); GrabbableObject val3 = default(GrabbableObject); for (int i = 0; i < spawnedScrap.Length; i++) { NetworkObjectReference val = spawnedScrap[i]; try { if (((NetworkObjectReference)(ref val)).TryGet(ref val2, (NetworkManager)null) && ((Component)val2).TryGetComponent<GrabbableObject>(ref val3)) { val3.isInFactory = false; } } catch (Exception arg) { OutfallMod.Logger.LogError((object)$"Error processing spawned scrap object: {arg}"); } } } } [HarmonyPatch(typeof(StartOfRound))] public class StartOfRoundPatch { [HarmonyPatch("ShipLeave")] [HarmonyPrefix] public static void ShipLeave_Prefix(StartOfRound __instance) { if (!((Object)(object)OutfallMoonController.Instance == (Object)null)) { Object.FindObjectOfType<DungeonStartingTitleProps>()?.ToggleRoof(open: true); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace __GEN { internal class NetworkVariableSerializationHelper { [RuntimeInitializeOnLoadMethod] internal static void InitializeSerialization() { } } } namespace NoteBoxz.Outfall.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }