The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of TerrainRandomiser v0.2.4
TerrainRandomiser.dll
Decompiled 2 months agousing System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using PhotonCustomPropsUtils; using TMPro; using TerrainRandomiser.TerrainGeneration; using Unity.Collections; using Unity.Jobs; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; using Zorro.Core; [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: AssemblyCompany("TerrainRandomiser")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.2.4")] [assembly: AssemblyInformationalVersion("0.2.4+c14f55a8c3cff1dc22be68e0dd20b4e26de4d338")] [assembly: AssemblyProduct("TerrainRandomiser")] [assembly: AssemblyTitle("TerrainRandomiser")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.4.0")] [module: UnverifiableCode] 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; } } } namespace TerrainRandomiser { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.snosz.terrainrandomiser", "TerrainRandomiser", "0.2.4")] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(GameOverHandler), "BeginIslandLoadRPC")] private static class BeginIslandLoadRPCPatch { private static void Postfix(GameOverHandler __instance) { if (viewIDsToSend != null) { viewIDsToSend.Clear(); } if (viewsRequiringIDs != null) { viewsRequiringIDs.Clear(); } if (receivedViewIDs != null) { receivedViewIDs.Clear(); } } } [HarmonyPatch(typeof(AirportCheckInKiosk), "BeginIslandLoadRPC")] private static class AirportCheckInKisokBeginIslandLoadRPCPatch { private static void Prefix(AirportCheckInKiosk __instance) { if (shouldRandomise && !Instance.hasPatched && !Instance.hasPatched) { _harmony.PatchAll(typeof(GenerationPatches.PropGrouperPatch)); _harmony.PatchAll(typeof(GenerationPatches.LevelGenStepSpawnPatch)); _harmony.PatchAll(typeof(GenerationPatches.PropSpawnerAddPatch)); _harmony.PatchAll(typeof(MapHandlerStartPatch)); Instance.hasPatched = true; } } } [HarmonyPatch(typeof(BoardingPass), "StartGame")] private static class StartGamePatch { private static void Prefix(BoardingPass __instance) { if (PhotonNetwork.IsMasterClient && Instance.configAutoRandomise.Value) { Instance.SetMasterSeed(Random.Range(1, 1000001)); } } } [HarmonyPatch(typeof(MapHandler), "Start")] private static class MapHandlerStartPatch { private static bool Prefix(MapHandler __instance) { if (!shouldRandomise) { return true; } viewIDsToSend = new List<int>(); viewsRequiringIDs = new List<PhotonView>(); Debug.Log((object)$"[TerrainRandomiser] Starting generation with seed: {masterSeed}"); Random.InitState(masterSeed); GameObject segmentCampfire = Singleton<MapHandler>.Instance.segments.First((MapSegment s) => ((Object)s.segmentCampfire).name == "Volcano_Campfire").segmentCampfire; if ((Object)(object)segmentCampfire != (Object)null) { segmentCampfire.SetActive(false); } List<MapSegment> list = Singleton<MapHandler>.Instance.segments.ToList(); list.AddRange(Singleton<MapHandler>.Instance.variantSegments); foreach (MapSegment item in list) { if ((Object)(object)item.segmentParent.GetComponent<PropGrouper>() == (Object)null) { item.segmentParent.gameObject.AddComponent<PropGrouper>(); } } MapHandlerHelpers.RunAllSegments(__instance.segments, __instance.variantSegments); MapHandlerHelpers.RunGobal(__instance.globalParent); if ((Object)(object)segmentCampfire != (Object)null) { segmentCampfire.SetActive(true); } if (PhotonNetwork.IsMasterClient) { List<int> andAssignAllUnassignedViews = MapHandlerHelpers.GetAndAssignAllUnassignedViews(); viewIDsToSend.AddRange(andAssignAllUnassignedViews); Instance.SendViewIDsToClients(viewIDsToSend); } return true; } private static void Postfix(MapHandler __instance) { if (shouldRandomise && !PhotonNetwork.IsMasterClient) { Debug.Log((object)string.Format("[TerrainRandomiser] Required viewIDs: {0} | Received viewIDs: {1}", viewsRequiringIDs?.Count ?? (-1), (receivedViewIDs == null) ? "null" : receivedViewIDs.Count.ToString())); } } } public static Plugin Instance; private static Harmony _harmony; public static int masterSeed = 1000; public static List<int> viewIDsToSend; public static List<PhotonView>? viewsRequiringIDs; public static List<int> receivedViewIDs; public ConfigEntry<int> configSeed; public ConfigEntry<bool> configShouldRandomise; public ConfigEntry<bool> configAutoRandomise; public AssetBundle seedPickerUIBundle; public SeedPickerUI seedPickerUI; public static bool shouldRandomise = false; public static bool autoRandomise = false; private PhotonScopedManager manager; public bool hasPatched = false; private string currentScene = "Title"; private void Awake() { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown Instance = this; byte[] seedpicker = Resource1.seedpicker; seedPickerUIBundle = AssetBundle.LoadFromMemory(seedpicker); configSeed = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Seed", 1000, "Seed to apply."); configShouldRandomise = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShouldRandomise", true, "Enable or disable random generation"); configAutoRandomise = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoRandomise", true, "Enable or disable auto seed picker on clicking play."); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; masterSeed = configSeed.Value; shouldRandomise = configShouldRandomise.Value; autoRandomise = configAutoRandomise.Value; _harmony = new Harmony("com.snosz.terrainrandomiser"); SceneManager.activeSceneChanged += Instance.OnSceneChanged; AddPhotonManager(); } private void OnSceneChanged(Scene oldScene, Scene newScene) { currentScene = ((Scene)(ref newScene)).name; if (((Scene)(ref newScene)).name == "Airport") { if (Instance.hasPatched) { _harmony.UnpatchSelf(); Instance.hasPatched = false; } if (configAutoRandomise.Value && PhotonNetwork.IsMasterClient) { SetMasterSeed(Random.Range(1, 1000001)); } LoadSeedPickerUI(); _harmony.PatchAll(typeof(AirportCheckInKisokBeginIslandLoadRPCPatch)); } } private void LoadSeedPickerUI() { if ((Object)(object)GUIManager.instance != (Object)null) { SeedPickerUI seedPickerUI = ((Component)GUIManager.instance.boardingPass).gameObject.AddComponent<SeedPickerUI>(); Instance.seedPickerUI = seedPickerUI; } } private void AddPhotonManager() { manager = PhotonCustomPropsUtilsPlugin.GetManager("com.snosz.terrainrandomiser"); manager.RegisterOnJoinedRoom((Action<Player>)delegate { if (PhotonNetwork.IsMasterClient) { if (configAutoRandomise.Value) { configSeed.Value = Random.Range(1, 1000001); } manager.SetRoomProperty("masterSeed", (object)configSeed.Value); manager.SetRoomProperty("shouldRandomise", (object)configShouldRandomise.Value); } }); manager.RegisterRoomProperty<int>("masterSeed", (RoomEventType)2, (Action<int>)delegate(int value) { masterSeed = value; }); manager.RegisterRoomProperty<bool>("shouldRandomise", (RoomEventType)2, (Action<bool>)delegate(bool value) { shouldRandomise = value; }); manager.RegisterRoomProperty<int[]>("propViews", (RoomEventType)2, (Action<int[]>)delegate(int[] val) { if (!PhotonNetwork.IsMasterClient) { if (receivedViewIDs == null) { receivedViewIDs = new List<int>(); } else { receivedViewIDs.Clear(); } receivedViewIDs = val.ToList(); Instance.UpdateRequiredViewIDs(); Debug.Log((object)$"[TerrainCustomiser] Updated receivedViewIDs with {receivedViewIDs.Count} IDs"); } }); } public void SetMasterSeed(int newSeed) { if (PhotonNetwork.IsMasterClient) { masterSeed = newSeed; configSeed.Value = masterSeed; manager.SetRoomProperty("masterSeed", (object)newSeed); } } public void SetShouldRandomise(bool shouldRandomise) { if (PhotonNetwork.IsMasterClient) { Plugin.shouldRandomise = shouldRandomise; configShouldRandomise.Value = shouldRandomise; manager.SetRoomProperty("shouldRandomise", (object)shouldRandomise); } } public void SetAutoRandomise(bool value) { if (PhotonNetwork.IsMasterClient) { autoRandomise = value; configAutoRandomise.Value = value; if (value) { SetMasterSeed(Random.Range(1, 1000001)); } } } public void SendViewIDsToClients(List<int> viewIDs) { manager.SetRoomProperty("propViews", (object)viewIDs.ToArray()); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } seedPickerUIBundle.Unload(false); } public void UpdateRequiredViewIDs() { if (!shouldRandomise || PhotonNetwork.IsMasterClient) { return; } if (viewsRequiringIDs == null || receivedViewIDs == null) { Debug.LogError((object)"[TerrainRandomiser] Required lists did not initialize or have already been resolved."); return; } if (viewsRequiringIDs.Count > receivedViewIDs.Count) { Debug.LogError((object)"[TerrainRandomiser] ID Count mismatch! Map will be out of sync!"); return; } for (int i = 0; i < viewsRequiringIDs.Count; i++) { if ((Object)(object)viewsRequiringIDs[i] != (Object)null && (Object)(object)((Component)viewsRequiringIDs[i]).gameObject != (Object)null) { viewsRequiringIDs[i].ViewID = receivedViewIDs[i]; } else { Debug.LogError((object)$"Null or destroyed PhotonView at index {i}"); } } List<PhotonView> allUnassignedViews = MapHandlerHelpers.GetAllUnassignedViews(); for (int j = 0; j < allUnassignedViews.Count; j++) { allUnassignedViews[j].ViewID = receivedViewIDs[viewsRequiringIDs.Count + j]; } viewsRequiringIDs.Clear(); viewsRequiringIDs = null; } } [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class Resource1 { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { ResourceManager resourceManager = new ResourceManager("TerrainRandomiser.Resource1", typeof(Resource1).Assembly); resourceMan = resourceManager; } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal static byte[] seedpicker { get { object @object = ResourceManager.GetObject("seedpicker", resourceCulture); return (byte[])@object; } } internal Resource1() { } } public class SeedPickerUI : MonoBehaviour { private GameObject seedPickerInstance; private GameObject seedPickerUIPrefab; private Button setButton; private Button randomSeedButton; private TMP_InputField seedInputField; private Toggle enableRandomiserToggle; private Toggle autoRandomiseToggle; private Toggle forceBiomeToggle; private TMP_Dropdown biomeDropdown; private int inputSeed; private TMP_FontAsset textFontAsset; private void Awake() { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Expected O, but got Unknown //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Expected O, but got Unknown if ((Object)(object)seedPickerUIPrefab == (Object)null) { seedPickerUIPrefab = Plugin.Instance.seedPickerUIBundle.LoadAsset<GameObject>("SeedPicker4"); } TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>(); TMP_FontAsset[] array2 = array; foreach (TMP_FontAsset val in array2) { if (((Object)val).name.Contains("DarumaDropOne")) { textFontAsset = val; break; } } seedPickerInstance = Object.Instantiate<GameObject>(seedPickerUIPrefab, ((Component)this).transform.Find("BoardingPass")); seedPickerInstance.transform.localPosition = new Vector3(2.34f, 175.4367f, 0f); Transform obj = seedPickerInstance.transform.Find("RandomSeedButton"); randomSeedButton = ((obj != null) ? ((Component)obj).GetComponent<Button>() : null); Transform obj2 = seedPickerInstance.transform.Find("SeedInputField"); seedInputField = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_InputField>() : null); if ((Object)(object)seedInputField != (Object)null) { inputSeed = Plugin.Instance.configSeed.Value; seedInputField.text = Plugin.Instance.configSeed.Value.ToString(); seedInputField.characterLimit = 7; seedInputField.characterValidation = (CharacterValidation)2; TextMeshProUGUI[] componentsInChildren = ((Component)seedInputField).GetComponentsInChildren<TextMeshProUGUI>(); for (int j = 0; j < componentsInChildren.Length; j++) { ((TMP_Text)componentsInChildren[j]).font = textFontAsset; ((TMP_Text)componentsInChildren[j]).fontSharedMaterial = ((TMP_Asset)textFontAsset).material; } } Transform obj3 = seedPickerInstance.transform.Find("SetSeedButton"); setButton = ((obj3 != null) ? ((Component)obj3).GetComponent<Button>() : null); Transform obj4 = seedPickerInstance.transform.Find("Toggle"); enableRandomiserToggle = ((obj4 != null) ? ((Component)obj4).GetComponent<Toggle>() : null); if ((Object)(object)enableRandomiserToggle != (Object)null) { ((TMP_Text)((Component)enableRandomiserToggle).GetComponentInChildren<TextMeshProUGUI>()).font = textFontAsset; ((TMP_Text)((Component)enableRandomiserToggle).GetComponentInChildren<TextMeshProUGUI>()).fontSharedMaterial = ((TMP_Asset)textFontAsset).material; enableRandomiserToggle.isOn = Plugin.shouldRandomise; } Transform obj5 = seedPickerInstance.transform.Find("AutoRandomToggle"); autoRandomiseToggle = ((obj5 != null) ? ((Component)obj5).GetComponent<Toggle>() : null); if ((Object)(object)autoRandomiseToggle != (Object)null) { ((TMP_Text)((Component)autoRandomiseToggle).GetComponentInChildren<TextMeshProUGUI>()).font = textFontAsset; ((TMP_Text)((Component)autoRandomiseToggle).GetComponentInChildren<TextMeshProUGUI>()).fontSharedMaterial = ((TMP_Asset)textFontAsset).material; autoRandomiseToggle.isOn = Plugin.autoRandomise; } Transform obj6 = seedPickerInstance.transform.Find("ForceBiomeToggle"); forceBiomeToggle = ((obj6 != null) ? ((Component)obj6).GetComponent<Toggle>() : null); ((Component)forceBiomeToggle).gameObject.SetActive(false); biomeDropdown = ((Component)seedPickerInstance.transform.Find("BiomeDropdown")).GetComponent<TMP_Dropdown>(); ((Component)biomeDropdown).gameObject.SetActive(false); if ((Object)(object)randomSeedButton != (Object)null) { ((UnityEvent)randomSeedButton.onClick).AddListener(new UnityAction(OnRandomSeedClicked)); } if ((Object)(object)setButton != (Object)null) { ((TMP_Text)((Component)setButton).GetComponentInChildren<TextMeshProUGUI>()).font = textFontAsset; ((TMP_Text)((Component)setButton).GetComponentInChildren<TextMeshProUGUI>()).fontSharedMaterial = ((TMP_Asset)textFontAsset).material; ((UnityEvent)setButton.onClick).AddListener(new UnityAction(OnSetSeedClicked)); } if ((Object)(object)enableRandomiserToggle != (Object)null) { ((UnityEvent<bool>)(object)enableRandomiserToggle.onValueChanged).AddListener((UnityAction<bool>)OnToggleChanged); ((Component)setButton).gameObject.SetActive(enableRandomiserToggle.isOn); ((Component)randomSeedButton).gameObject.SetActive(enableRandomiserToggle.isOn); ((Component)autoRandomiseToggle).gameObject.SetActive(enableRandomiserToggle.isOn); ((Component)seedInputField).gameObject.SetActive(enableRandomiserToggle.isOn); } if ((Object)(object)autoRandomiseToggle != (Object)null) { ((UnityEvent<bool>)(object)autoRandomiseToggle.onValueChanged).AddListener((UnityAction<bool>)OnAutoRandomiseToggleChanged); ((Selectable)seedInputField).interactable = !autoRandomiseToggle.isOn; ((Selectable)randomSeedButton).interactable = !autoRandomiseToggle.isOn; ((Selectable)setButton).interactable = !autoRandomiseToggle.isOn; } } private void OnRandomSeedClicked() { if (PhotonNetwork.IsMasterClient) { Plugin.Instance.SetMasterSeed(Random.Range(1, 1000001)); seedInputField.text = Plugin.masterSeed.ToString(); inputSeed = Plugin.masterSeed; } } private void OnSetSeedClicked() { if (int.TryParse(seedInputField.text, out var result)) { if (PhotonNetwork.IsMasterClient) { Plugin.Instance.SetMasterSeed(result); } } else { Debug.LogWarning((object)"[TerrainRandomiser] Invalid seed input"); } } private void OnToggleChanged(bool value) { if (PhotonNetwork.IsMasterClient) { Plugin.Instance.SetShouldRandomise(value); ((Component)setButton).gameObject.SetActive(enableRandomiserToggle.isOn); ((Component)randomSeedButton).gameObject.SetActive(enableRandomiserToggle.isOn); ((Component)autoRandomiseToggle).gameObject.SetActive(enableRandomiserToggle.isOn); ((Component)seedInputField).gameObject.SetActive(enableRandomiserToggle.isOn); } } private void OnAutoRandomiseToggleChanged(bool value) { if (PhotonNetwork.IsMasterClient) { Plugin.Instance.SetAutoRandomise(value); if (value) { ((Selectable)seedInputField).interactable = false; ((Selectable)randomSeedButton).interactable = false; ((Selectable)setButton).interactable = false; } else { ((Selectable)seedInputField).interactable = true; ((Selectable)randomSeedButton).interactable = true; ((Selectable)setButton).interactable = true; } } } } } namespace TerrainRandomiser.TerrainGeneration { public static class GenerationPatches { [HarmonyPatch(typeof(PropSpawner), "Add")] public static class PropSpawnerAddPatch { private static Ray[] rays = (Ray[])(object)new Ray[0]; private static bool Prefix(PropSpawner __instance) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.shouldRandomise) { return true; } if (__instance.chanceToUseSpawner < 0.999f && Random.value > __instance.chanceToUseSpawner) { return false; } if (!CanBatch(__instance)) { return true; } int num = 50000; int num2 = 0; int nrOfSpawns = __instance.nrOfSpawns; LayerMask mask = HelperFunctions.GetMask(__instance.layerType); int num3 = 512; if (rays.Length < num3) { rays = (Ray[])(object)new Ray[num3]; } Vector3 val = ((Component)__instance).transform.forward + __instance.rayDirectionOffset; Vector3 normalized = ((Vector3)(ref val)).normalized; QueryParameters @default = QueryParameters.Default; @default.layerMask = ((LayerMask)(ref mask)).value; @default.hitTriggers = (QueryTriggerInteraction)1; NativeArray<RaycastHit> results = default(NativeArray<RaycastHit>); NativeArray<RaycastCommand> commands = default(NativeArray<RaycastCommand>); while (num2 < nrOfSpawns && num > 0) { rays = PropSpawnerHelpers.BuildRays(__instance, rays, num3, normalized); results..ctor(num3, (Allocator)3, (NativeArrayOptions)1); commands..ctor(num3, (Allocator)3, (NativeArrayOptions)1); ExecuteJob(commands, results, rays, @default, num3, __instance.rayLength); num -= num3; int num4 = ProcessResults(results, rays, __instance, num2, nrOfSpawns); num2 += num4; commands.Dispose(); results.Dispose(); } Physics.SyncTransforms(); __instance.currentSpawns = ((Component)__instance).transform.childCount; __instance.SpawnDecor(); return false; } } [HarmonyPatch(typeof(PropGrouper), "RunAll")] public static class PropGrouperPatch { private static readonly List<LevelGenStep> lateLevelGenSteps = new List<LevelGenStep>(); private static void Postfix(PropGrouper __instance) { PropGrouperHelpers.CollectLateLevelGenSteps(__instance, lateLevelGenSteps); PropGrouperHelpers.RunLateLevelGenSteps(lateLevelGenSteps); } } [HarmonyPatch] public static class LevelGenStepSpawnPatch { [CompilerGenerated] private sealed class <>c__DisplayClass0_0 { public Type baseType; public Func<Type, bool> <>9__0; internal bool <TargetMethods>b__0(Type t) { return baseType.IsAssignableFrom(t) && !t.IsAbstract; } } [CompilerGenerated] private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable { private int <>1__state; private MethodBase <>2__current; private int <>l__initialThreadId; private <>c__DisplayClass0_0 <>8__1; private IEnumerator<Type> <>s__2; private Type <type>5__3; private MethodInfo <method>5__4; MethodBase IEnumerator<MethodBase>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <TargetMethods>d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>8__1 = null; <>s__2 = null; <type>5__3 = null; <method>5__4 = null; <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -3; goto IL_00ff; } <>1__state = -1; <>8__1 = new <>c__DisplayClass0_0(); <>8__1.baseType = typeof(LevelGenStep); <>s__2 = (from t in <>8__1.baseType.Assembly.GetTypes() where <>8__1.baseType.IsAssignableFrom(t) && !t.IsAbstract select t).GetEnumerator(); <>1__state = -3; goto IL_010e; IL_010e: if (<>s__2.MoveNext()) { <type>5__3 = <>s__2.Current; <method>5__4 = <type>5__3.GetMethod("Spawn", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (<method>5__4 != null) { <>2__current = <method>5__4; <>1__state = 1; return true; } goto IL_00ff; } <>m__Finally1(); <>s__2 = null; return false; IL_00ff: <method>5__4 = null; <type>5__3 = null; goto IL_010e; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>s__2 != null) { <>s__2.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new <TargetMethods>d__0(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<MethodBase>)this).GetEnumerator(); } } [IteratorStateMachine(typeof(<TargetMethods>d__0))] private static IEnumerable<MethodBase> TargetMethods() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <TargetMethods>d__0(-2); } private static bool Prefix(LevelGenStep __instance, MethodBase __originalMethod, SpawnData spawnData, ref GameObject __result) { if (!Plugin.shouldRandomise) { return true; } Type type = ((object)__instance).GetType(); GameObject[] array = type.GetField("props", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(__instance) as GameObject[]; IList list = type.GetField("modifiers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(__instance) as IList; IList list2 = type.GetField("postConstraints", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(__instance) as IList; if (array == null) { return true; } List<PropSpawnerMod> modifiers = ((list != null) ? new List<PropSpawnerMod>(list.Cast<PropSpawnerMod>()) : new List<PropSpawnerMod>()); List<PropSpawnerConstraintPost> postConstraints = ((list2 != null) ? new List<PropSpawnerConstraintPost>(list2.Cast<PropSpawnerConstraintPost>()) : new List<PropSpawnerConstraintPost>()); return PropSpawnerHelpers.TrySpawn(spawnData, ref __result, array, modifiers, postConstraints, ((Component)__instance).transform, ((Component)__instance).gameObject, Plugin.viewIDsToSend, Plugin.viewsRequiringIDs); } } public static bool CanBatch(PropSpawner spawner) { if (!spawner.raycastPosition) { return false; } if (!spawner.syncTransforms || PropSpawnerHelpers.SafeToBatchPropNames.Contains(((Object)((Component)spawner).gameObject).name)) { return true; } return true; } public static bool PassedConstraints(PropSpawner spawner, SpawnData sd) { for (int i = 0; i < spawner.constraints.Count; i++) { if (!spawner.constraints[i].CheckConstraint(sd)) { return false; } } return true; } public static void ExecuteJob(NativeArray<RaycastCommand> commands, NativeArray<RaycastHit> results, Ray[] rays, QueryParameters queryParams, int batchCount, float rayLength) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < batchCount; i++) { commands[i] = new RaycastCommand(((Ray)(ref rays[i])).origin, ((Ray)(ref rays[i])).direction, queryParams, rayLength); } JobHandle val = RaycastCommand.ScheduleBatch(commands, results, 128, default(JobHandle)); ((JobHandle)(ref val)).Complete(); } public static int ProcessResults(NativeArray<RaycastHit> results, Ray[] rays, PropSpawner spawner, int successes, int nrOfSpawns) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) int num = 0; int num2 = 0; for (int i = 0; i < results.Length; i++) { if (successes >= nrOfSpawns) { break; } RaycastHit hit = results[i]; if ((Object)(object)((RaycastHit)(ref hit)).collider == (Object)null) { continue; } num++; Ray val = rays[i]; SpawnData val2 = PropSpawnerHelpers.BuildSpawnData(spawner, rays[i], hit, hasHit: true, successes + num2); if (PassedConstraints(spawner, val2)) { object[] array = new object[1] { val2 }; if (Object.op_Implicit((Object)(object)spawner.Spawn(val2))) { successes++; num2++; } } } return num2; } } public class MapHandlerHelpers { public static void RunAllSegments(MapSegment[] segments, MapSegment[] variantSegments, bool forceBiome = false, string biomeName = "MESA") { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 foreach (MapSegment val in segments) { GameObject segmentParent = val.segmentParent; PropGrouper val2 = ((segmentParent != null) ? segmentParent.GetComponent<PropGrouper>() : null); if (val2 != null) { val2.RunAll(true); } } if (!forceBiome) { return; } foreach (MapSegment val3 in variantSegments) { if ((int)val3._biome == 6 && biomeName == "MESA") { GameObject segmentParent2 = val3.segmentParent; PropGrouper val4 = ((segmentParent2 != null) ? segmentParent2.GetComponent<PropGrouper>() : null); if (val4 != null) { val4.RunAll(true); } } } } public static void RunGobal(Transform global) { ((Component)global).gameObject.GetComponent<PropGrouper>().RunAll(true); } public static List<PhotonView> GetAllUnassignedViews() { PhotonView[] componentsInChildren = ((Component)Singleton<MapHandler>.Instance).gameObject.GetComponentsInChildren<PhotonView>(); List<PhotonView> list = new List<PhotonView>(); for (int i = 0; i < componentsInChildren.Length; i++) { if (componentsInChildren[i].ViewID == 0) { list.Add(componentsInChildren[i]); } } return list; } public static List<int> GetAndAssignAllUnassignedViews() { List<PhotonView> allUnassignedViews = GetAllUnassignedViews(); List<int> list = new List<int>(); for (int i = 0; i < allUnassignedViews.Count; i++) { int item = PropSpawnerHelpers.AssignMasterClientViewID(((Component)allUnassignedViews[i]).gameObject); list.Add(item); } return list; } } public static class PropGrouperHelpers { public static void CollectLateLevelGenSteps(PropGrouper grouper, List<LevelGenStep> results) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 results.Clear(); LevelGenStep[] componentsInChildren = ((Component)grouper).GetComponentsInChildren<LevelGenStep>(true); LevelGenStep[] array = componentsInChildren; foreach (LevelGenStep val in array) { PropGrouper componentInParent = ((Component)val).GetComponentInParent<PropGrouper>(); if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.timing == 1) { results.Add(val); } } } public static void RunLateLevelGenSteps(List<LevelGenStep> steps) { foreach (LevelGenStep step in steps) { step.Go(); } } } public static class PropSpawnerHelpers { public static readonly HashSet<string> SafeToBatchPropNames = new HashSet<string> { "LuggageSpawner", "Ivy", "Geysers", "Weed", "ExploShrooms", "PoisonShrooms", "Vines", "BeachGrass", "Driftwood", "Behive", "ShittyPiton", "Monsteras", "FlashPlant", "Shrub", "Pine", "Bushes", "Trees", "DeadTree", "Palms" }; public static bool TrySpawn(SpawnData spawnData, ref GameObject __result, GameObject[] props, List<PropSpawnerMod> modifiers, List<PropSpawnerConstraintPost> postConstraints, Transform parent, GameObject fallback, List<int> viewIDsToSend, List<PhotonView> viewsRequiringIDs) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) GameObject val = props[Random.Range(0, props.Length)]; PhotonView val2 = default(PhotonView); if ((Object)(object)val != (Object)null && val.TryGetComponent<PhotonView>(ref val2)) { Quaternion randomRotationWithUp = GetRandomRotationWithUp(Vector3.up); GameObject val3 = Object.Instantiate<GameObject>(val, spawnData.pos, randomRotationWithUp, parent); RemoveSpineIfLuggage(val3); PropGrouper componentInParent = fallback.GetComponentInParent<PropGrouper>(); ApplyModifiers(val3, spawnData, modifiers); if (!CheckAndHandlePostConstraints(val3, spawnData, postConstraints)) { __result = null; return false; } HandleIfBridge(val3); if (PhotonNetwork.IsMasterClient) { viewIDsToSend.Add(AssignMasterClientViewID(val3)); } else { CollectViewRequiringID(val3, viewsRequiringIDs); } __result = val3; return false; } return true; } public static Quaternion GetRandomRotationWithUp(Vector3 normal) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_002b: Unknown result type (might be due to invalid IL or missing references) Vector3 onUnitSphere = Random.onUnitSphere; onUnitSphere.y = 0f; onUnitSphere = Vector3.Cross(normal, Vector3.Cross(normal, onUnitSphere)); return Quaternion.LookRotation(onUnitSphere, normal); } public static bool CheckAndHandlePostConstraints(GameObject go, SpawnData spawnData, List<PropSpawnerConstraintPost> postConstraints) { foreach (PropSpawnerConstraintPost postConstraint in postConstraints) { if (postConstraint.mute || postConstraint.CheckConstraint(go, spawnData)) { continue; } Object.DestroyImmediate((Object)(object)go); return false; } return true; } public static void ApplyModifiers(GameObject go, SpawnData spawnData, List<PropSpawnerMod> modifiers) { foreach (PropSpawnerMod modifier in modifiers) { if (!modifier.mute) { modifier.ModifyObject(go, spawnData); } } } public static void RemoveSpineIfLuggage(GameObject go) { Luggage val = default(Luggage); if (go.TryGetComponent<Luggage>(ref val)) { SpineCheck component = go.GetComponent<SpineCheck>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } } } public static void HandleIfBridge(GameObject go) { BreakableBridge @object = default(BreakableBridge); if (go.TryGetComponent<BreakableBridge>(ref @object)) { CollisionModifier[] componentsInChildren = go.GetComponentsInChildren<CollisionModifier>(); CollisionModifier[] array = componentsInChildren; foreach (CollisionModifier val in array) { val.applyEffects = false; val.onCollide = (Action<Character, CollisionModifier, Collision, Bodypart>)Delegate.Combine(val.onCollide, new Action<Character, CollisionModifier, Collision, Bodypart>(@object.OnBridgeCollision)); } } } public static bool CheckIfBridge(GameObject go) { BreakableBridge val = default(BreakableBridge); if (go.TryGetComponent<BreakableBridge>(ref val)) { return true; } return false; } public static int AssignMasterClientViewID(GameObject go) { int num = PhotonNetwork.AllocateViewID(false); PhotonView component = go.GetComponent<PhotonView>(); component.ViewID = num; return num; } public static void CollectViewRequiringID(GameObject go, List<PhotonView> viewsRequiringIDs) { PhotonView component = go.GetComponent<PhotonView>(); viewsRequiringIDs.Add(component); } public static Ray[] BuildRays(PropSpawner spawner, Ray[] outRays, int count, Vector3 rayDir) { //IL_0009: 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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < count; i++) { outRays[i] = GetSpawnRay(spawner.area, ((Component)spawner).transform, rayDir); } return outRays; } public static Ray GetSpawnRay(Vector2 area, Transform t, Vector3 rayDir) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(Random.value, Random.value); Vector3 val2 = t.position + t.right * Mathf.Lerp((0f - area.x) * 0.5f, area.x * 0.5f, val.x) + t.up * Mathf.Lerp((0f - area.y) * 0.5f, area.y * 0.5f, val.y); return new Ray(val2, rayDir); } public static SpawnData BuildSpawnData(PropSpawner spawner, Ray ray, RaycastHit hit, bool hasHit, int count) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown Vector3 val = ((Ray)(ref ray)).origin - ((Component)spawner).transform.position; Vector2 placement = default(Vector2); ((Vector2)(ref placement))..ctor(Vector3.Dot(val, ((Component)spawner).transform.right) / spawner.area.x + 0.5f, Vector3.Dot(val, ((Component)spawner).transform.up) / spawner.area.y + 0.5f); return new SpawnData { pos = ((RaycastHit)(ref hit)).point, normal = ((RaycastHit)(ref hit)).normal, rayDir = ((Component)spawner).transform.forward, hit = hit, spawnerTransform = ((Component)spawner).transform, placement = placement, spawnCount = count }; } } }