Decompiled source of BiomePicker v0.2.1
plugins/Tobeyyy.BiomePicker.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BiomePicker.Dev; using BiomePicker.Game; using BiomePicker.UI; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Peak; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Profiling; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.UI.ProceduralImage; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Tobeyyy.BiomePicker")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.1.0")] [assembly: AssemblyInformationalVersion("0.2.1+a3b4504a56432d23da4826c484c7e842476a04af")] [assembly: AssemblyProduct("Tobeyyy.BiomePicker")] [assembly: AssemblyTitle("BiomePicker")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace Microsoft.CodeAnalysis { [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace BiomePicker { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Tobeyyy.BiomePicker", "BiomePicker", "0.2.1")] public class Plugin : BaseUnityPlugin { internal static bool DevMode; internal static ConfigEntry<bool> AutoTest; internal static ConfigEntry<int> AutoTestLevel; internal static ConfigEntry<string> AutoTestLab; internal static ConfigEntry<bool> AutoTestQuit; internal static ConfigEntry<int> DonorLevel; internal static ConfigEntry<string> DevPlan; internal static ConfigEntry<bool> DevHotkeys; internal static ConfigEntry<bool> DevPlayKit; internal static ConfigEntry<bool> DevNadirKit; internal static ConfigEntry<bool> DevParity; internal static ConfigEntry<bool> DevShots; internal static ConfigEntry<bool> DevFast; internal static ConfigEntry<string> Plan; internal static string ConflictingPlugin; private static readonly string[] Conflicts = new string[6] { "PLL", "AllBiomes", "TrueFinalAscent", "TerrainRandomiser", "TerrainCustomiser", "PeakWorkshop" }; public const string Id = "Tobeyyy.BiomePicker"; internal static ManualLogSource Log { get; private set; } = null; internal static Plugin Instance { get; private set; } internal static Harmony Harmony { get; private set; } internal static string OutputFolder => Path.Combine(Paths.BepInExRootPath, "BiomePicker"); public static string Name => "BiomePicker"; public static string Version => "0.2.1"; private void Awake() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Instance = this; Plan = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Plan", "", "The biomes of a run and their order, as picked at the boarding pass (empty = every installed biome in a row). In multiplayer the host's plan counts."); string text = Path.Combine(Paths.ConfigPath, "Tobeyyy.BiomePicker.Dev.cfg"); DevMode = File.Exists(text); ConfigFile val = new ConfigFile(text, false, ((BaseUnityPlugin)this).Info.Metadata) { SaveOnConfigSet = DevMode }; AutoTest = val.Bind<bool>("Dev", "AutoTest", false, "Drive the game from the main menu into a solo run on Level_<AutoTestLevel> and run the lab named in AutoTestLab."); AutoTestLevel = val.Bind<int>("Dev", "AutoTestLevel", 17, "Today's island for the auto-test (Level_N, 0..207 in PEAK 3.0)."); AutoTestLab = val.Bind<string>("Dev", "AutoTestLab", "donor", "'donor' = load a second island inert, copy its slot-2 variant into today's island and play it (dumps, shots)."); AutoTestQuit = val.Bind<bool>("Dev", "AutoTestQuit", true, "Quit the game when the auto-test is done."); DonorLevel = val.Bind<int>("Dev", "DonorLevel", -1, "Island to copy biomes from in the donor lab (-1 = the one most different from today's)."); DevPlan = val.Bind<string>("Dev", "Plan", "", "Overrides General.Plan for the auto-tests (empty = General.Plan)."); DevHotkeys = val.Bind<bool>("Dev", "Hotkeys", false, "F6: warp the local scout to the next campfire (the current round's end; on a last Kiln/Citadel its summit)."); DevPlayKit = val.Bind<bool>("Dev", "PlayKit", false, "On every island: Lost City's playtest kit (jetpack, lantern, food, chain launcher; needs Lost City with its developer config)."); DevParity = val.Bind<bool>("Dev", "Parity", true, "Auto-tests: measure every biome against vanilla (Parity.Sample: sky, sounds, hazards, pictures; ~9 s a round)."); DevShots = val.Bind<bool>("Dev", "Shots", true, "Auto-tests: save the pictures (Shots.Shot); off, only what a check measures is rendered."); DevFast = val.Bind<bool>("Dev", "Fast", false, "Auto-tests: the campfire switch at 3x game speed, the fog switched fully on at once, shorter settling waits."); DevNadirKit = val.Bind<bool>("Dev", "NadirKit", false, "On every island: a backpack holding the same amulet four times on the back (instead of PlayKit's jetpack), for the way to the Nadir."); foreach (PluginInfo value2 in Chainloader.PluginInfos.Values) { string text2 = value2.Metadata.GUID + " " + value2.Metadata.Name; string[] conflicts = Conflicts; foreach (string value in conflicts) { if (text2.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0 && value2.Metadata.GUID != "Tobeyyy.BiomePicker") { ConflictingPlugin = value2.Metadata.Name; } } } Harmony = new Harmony("Tobeyyy.BiomePicker"); Harmony.PatchAll(typeof(Plugin).Assembly); CustomBiomes.Register(new LostCityBiome(Harmony)); CustomBiomes.Register(new SakuraBiome(Harmony)); ((Component)this).gameObject.AddComponent<RunDirector>(); if (DevMode && (DevHotkeys.Value || DevPlayKit.Value || DevNadirKit.Value)) { ((Component)this).gameObject.AddComponent<DevKeys>(); } if (DevMode && AutoTest.Value) { ((Component)this).gameObject.AddComponent<AutoTestDriver>(); if (AutoTestLab.Value != "airport") { DestroyTrap.Install(Harmony); } } Log.LogInfo((object)("Plugin " + Name + " " + Version + " loaded" + ((ConflictingPlugin != null) ? (" (inactive: " + ConflictingPlugin + " present)") : "") + (DevMode ? " (developer config found)" : "") + ".")); } } } namespace BiomePicker.UI { internal sealed class Fade : MonoBehaviour { private static Fade _instance; private CanvasGroup _group; private static Fade Get() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_instance != (Object)null) { return _instance; } GameObject val = new GameObject("BiomePicker Fade"); Object.DontDestroyOnLoad((Object)(object)val); Canvas val2 = val.AddComponent<Canvas>(); val2.renderMode = (RenderMode)0; val2.sortingOrder = 30000; _instance = val.AddComponent<Fade>(); _instance._group = val.AddComponent<CanvasGroup>(); _instance._group.alpha = 0f; _instance._group.blocksRaycasts = false; Image val3 = new GameObject("Black").AddComponent<Image>(); ((Component)val3).transform.SetParent(val.transform, false); ((Graphic)val3).color = Color.black; ((Graphic)val3).raycastTarget = false; RectTransform rectTransform = ((Graphic)val3).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; return _instance; } public static IEnumerator To(float alpha, float seconds) { Fade f = Get(); float from = f._group.alpha; for (float t = 0f; t < seconds; t += Time.unscaledDeltaTime) { f._group.alpha = Mathf.Lerp(from, alpha, t / seconds); yield return null; } f._group.alpha = alpha; } public static void Clear() { if ((Object)(object)_instance != (Object)null) { _instance._group.alpha = 0f; } } } internal sealed class LoadBar : MonoBehaviour { private static LoadBar _instance; private CanvasGroup _group; private RectTransform _fill; private TextMeshProUGUI _label; private float _shown; public static void Show() { if ((Object)(object)_instance == (Object)null) { Build(); } _instance._shown = 0f; _instance._group.alpha = 1f; ((Behaviour)_instance).enabled = true; } private static void Build() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00d5: 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_00ef: 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_011b: 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_0144: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown //IL_0171: 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_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Expected O, but got Unknown //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Expected O, but got Unknown //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0294: 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_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Expected O, but got Unknown //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Expected O, but got Unknown //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_032a: 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_034c: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("BiomePicker LoadBar"); Object.DontDestroyOnLoad((Object)(object)val); Canvas val2 = val.AddComponent<Canvas>(); val2.renderMode = (RenderMode)0; val2.sortingOrder = 29000; CanvasScaler val3 = val.AddComponent<CanvasScaler>(); val3.uiScaleMode = (ScaleMode)1; val3.referenceResolution = new Vector2(1920f, 1080f); val3.matchWidthOrHeight = 0.5f; _instance = val.AddComponent<LoadBar>(); _instance._group = val.AddComponent<CanvasGroup>(); _instance._group.blocksRaycasts = false; GameObject val4 = new GameObject("Frame", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent(val.transform, false); RectTransform val5 = (RectTransform)val4.transform; Vector2 val6 = default(Vector2); ((Vector2)(ref val6))..ctor(0.5f, 0f); val5.anchorMax = val6; val5.anchorMin = val6; val5.pivot = new Vector2(0.5f, 0f); val5.anchoredPosition = new Vector2(0f, 70f); val5.sizeDelta = new Vector2(720f, 64f); GameObject val7 = new GameObject("Track", new Type[1] { typeof(RectTransform) }); val7.transform.SetParent(val4.transform, false); RectTransform val8 = (RectTransform)val7.transform; val8.anchorMin = new Vector2(0f, 0f); val8.anchorMax = new Vector2(1f, 0f); val8.pivot = new Vector2(0.5f, 0f); val8.sizeDelta = new Vector2(0f, 12f); Rounded(val7, new Color(0f, 0f, 0f, 0.45f), 6f); GameObject val9 = new GameObject("Fill", new Type[1] { typeof(RectTransform) }); val9.transform.SetParent(val7.transform, false); _instance._fill = (RectTransform)val9.transform; _instance._fill.anchorMin = Vector2.zero; _instance._fill.anchorMax = new Vector2(0f, 1f); _instance._fill.pivot = new Vector2(0f, 0.5f); val6 = (_instance._fill.offsetMin = (_instance._fill.offsetMax = Vector2.zero)); Rounded(val9, new Color(0.98f, 0.92f, 0.78f, 0.95f), 6f); GameObject val11 = new GameObject("Label", new Type[1] { typeof(RectTransform) }); val11.transform.SetParent(val4.transform, false); RectTransform val12 = (RectTransform)val11.transform; val12.anchorMin = new Vector2(0f, 0f); val12.anchorMax = new Vector2(1f, 1f); val12.offsetMin = new Vector2(0f, 20f); val12.offsetMax = Vector2.zero; _instance._label = val11.AddComponent<TextMeshProUGUI>(); TMP_FontAsset val13 = GameFont(); if ((Object)(object)val13 != (Object)null) { ((TMP_Text)_instance._label).font = val13; } ((TMP_Text)_instance._label).fontSize = 26f; ((Graphic)_instance._label).color = new Color(0.98f, 0.95f, 0.88f, 1f); ((TMP_Text)_instance._label).alignment = (TextAlignmentOptions)1026; ((TMP_Text)_instance._label).textWrappingMode = (TextWrappingModes)0; ((Graphic)_instance._label).raycastTarget = false; } private static TMP_FontAsset GameFont() { TMP_Text[] array = Resources.FindObjectsOfTypeAll<TMP_Text>(); foreach (TMP_Text val in array) { if ((Object)(object)val != (Object)null && (Object)(object)val.font != (Object)null && ((Object)val.font).name.IndexOf("LiberationSans", StringComparison.OrdinalIgnoreCase) < 0) { return val.font; } } return null; } private static void Rounded(GameObject go, Color color, float radius) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) ProceduralImage val = go.AddComponent<ProceduralImage>(); val.ModifierType = typeof(UniformModifier); UniformModifier component = go.GetComponent<UniformModifier>(); if ((Object)(object)component != (Object)null) { component.Radius = radius; } ((Graphic)val).color = color; ((Graphic)val).raycastTarget = false; } private void Update() { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) if (!LoadProgress.Shown) { _shown = Mathf.MoveTowards(_shown, 1f, Time.unscaledDeltaTime * 2f); _group.alpha = Mathf.MoveTowards(_group.alpha, 0f, Time.unscaledDeltaTime * 1.5f); if (_group.alpha <= 0f) { ((Behaviour)this).enabled = false; } } else { float value = LoadProgress.Value; if (value > _shown) { _shown = Mathf.Min(value, _shown + Mathf.Max(0.02f, (value - _shown) * 4f) * Time.unscaledDeltaTime); } ((TMP_Text)_label).text = $"{LoadProgress.Label} {Mathf.FloorToInt(_shown * 100f)}%"; } _fill.anchorMax = new Vector2(Mathf.Clamp01(_shown), 1f); } } [HarmonyPatch] internal sealed class PickerPanel : MonoBehaviour { private static readonly Color Paper = new Color(0.12f, 0.11f, 0.1f, 0.93f); private static readonly Color RowOn = new Color(0.22f, 0.2f, 0.17f, 0.95f); private static readonly Color RowOff = new Color(0.16f, 0.15f, 0.13f, 0.85f); private static readonly Color Ink = new Color(0.97f, 0.93f, 0.84f, 1f); private static readonly Color Faint = new Color(0.97f, 0.93f, 0.84f, 0.45f); private static readonly Color Accent = new Color(0.98f, 0.7f, 0.27f, 1f); private BoardingPass _pass; private TMP_FontAsset _font; private Material _fontMat; private Sprite _arrow; private RectTransform _rows; private TextMeshProUGUI _sub; private GameObject _footer; private RunPlan _plan; private string _shown; private float _nextPoll; private const float Width = 400f; private const float Margin = 14f; private const float Padding = 22f; private const float RowWidth = 356f; private const float ColumnGap = 12f; private GridLayoutGroup _grid; private int _columns = 1; private int _units; private static bool Host { get { if (PhotonNetwork.InRoom) { return PhotonNetwork.IsMasterClient; } return true; } } [HarmonyPostfix] [HarmonyPatch(typeof(BoardingPass), "Initialize")] private static void AfterInitialize(BoardingPass __instance) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown if ((Object)(object)((Component)__instance).GetComponentInChildren<PickerPanel>(true) != (Object)null) { return; } GameObject val = new GameObject("BiomePicker Panel", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(((Component)__instance).transform, false); try { val.AddComponent<PickerPanel>().Build(__instance); } catch (Exception ex) { Plugin.Log.LogError((object)("BiomePicker panel failed: " + ex)); Object.Destroy((Object)(object)val); } } [HarmonyPostfix] [HarmonyPatch(typeof(BoardingPass), "OnOpen")] private static void AfterOpen(BoardingPass __instance) { PickerPanel componentInChildren = ((Component)__instance).GetComponentInChildren<PickerPanel>(true); try { if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.Refresh(force: true); } } catch (Exception ex) { Plugin.Log.LogError((object)("BiomePicker panel refresh failed: " + ex)); } } private void Build(BoardingPass pass) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_018f: 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_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Expected O, but got Unknown //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Expected O, but got Unknown //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Expected O, but got Unknown _pass = pass; _font = pass.ascentTitle.font; _fontMat = pass.ascentTitle.fontSharedMaterial; Image val = ((Component)pass.incrementAscentButton).GetComponentInChildren<Image>(true); Image[] componentsInChildren = ((Component)pass.incrementAscentButton).GetComponentsInChildren<Image>(true); foreach (Image val2 in componentsInChildren) { if ((Object)(object)val2.sprite != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)(object)((Component)pass.incrementAscentButton).gameObject) { val = val2; } } _arrow = (((Object)(object)val != (Object)null) ? val.sprite : null); RectTransform val3 = (RectTransform)((Component)this).transform; Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(1f, 0.5f); val3.anchorMax = val4; val3.anchorMin = val4; val3.pivot = new Vector2(1f, 0.5f); val3.anchoredPosition = new Vector2(-14f, 0f); val3.sizeDelta = new Vector2(400f, 0f); Rounded(((Component)this).gameObject, Paper, 22f); VerticalLayoutGroup val5 = ((Component)this).gameObject.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)val5).padding = new RectOffset(22, 22, 20, 20); ((HorizontalOrVerticalLayoutGroup)val5).spacing = 6f; bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)val5).childControlHeight = true); ((HorizontalOrVerticalLayoutGroup)val5).childControlWidth = childControlWidth; ((HorizontalOrVerticalLayoutGroup)val5).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val5).childForceExpandHeight = false; ((Component)this).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; Text(((Component)this).transform, "BIOMES", 38f, Ink, (TextAlignmentOptions)513, 46f); _sub = Text(((Component)this).transform, "", 18f, Faint, (TextAlignmentOptions)513, 46f); ((TMP_Text)_sub).textWrappingMode = (TextWrappingModes)1; GameObject val6 = new GameObject("Rows", new Type[1] { typeof(RectTransform) }); val6.transform.SetParent(((Component)this).transform, false); _rows = (RectTransform)val6.transform; _grid = val6.AddComponent<GridLayoutGroup>(); _grid.cellSize = new Vector2(356f, 42f); _grid.spacing = new Vector2(12f, 4f); _grid.startAxis = (Axis)1; _grid.constraint = (Constraint)2; _footer = new GameObject("Footer", new Type[1] { typeof(RectTransform) }); _footer.transform.SetParent(((Component)this).transform, false); HorizontalLayoutGroup val7 = _footer.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val7).spacing = 8f; childControlWidth = (((HorizontalOrVerticalLayoutGroup)val7).childControlHeight = true); ((HorizontalOrVerticalLayoutGroup)val7).childControlWidth = childControlWidth; ((HorizontalOrVerticalLayoutGroup)val7).childForceExpandWidth = false; _footer.AddComponent<LayoutElement>().preferredHeight = 40f; Pill(_footer.transform, "ALL IN A ROW", delegate { Change(RunPlan.Default()); }); Refresh(force: true); } private void LateUpdate() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0262: 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_0289: 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_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: 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_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0218: 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_02b2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_pass == (Object)null || (Object)(object)_pass.startGameButton == (Object)null || (Object)(object)_rows == (Object)null) { return; } RectTransform val = (RectTransform)((Component)this).transform; RectTransform val2 = (RectTransform)((Transform)val).parent; Rect rect = val2.rect; Rect val3 = PassRect(_pass, val2); int units = _units; if (units != 0) { float num = LayoutUtility.GetPreferredHeight(val) - LayoutUtility.GetPreferredHeight(_rows); float num2 = num + HeightFor(units, 1); float num3 = Mathf.Min(new float[3] { (((Rect)(ref rect)).xMax - ((Rect)(ref val3)).xMax - 28f) / 400f, (((Rect)(ref rect)).height - 28f) / num2, 1f }); int num4 = ((units > 8) ? 3 : 2); float num5 = (float)num4 * 356f + (float)(num4 - 1) * 12f + 44f; float num6 = num + HeightFor(units, num4); float num7 = Mathf.Min(new float[3] { (((Rect)(ref rect)).yMax - ((Rect)(ref val3)).yMax - 28f) / num6, (((Rect)(ref rect)).width - 28f) / num5, 1f }); bool flag = ((_columns > 1) ? (num7 > num3 - 0.05f) : (num7 > num3 + 0.05f)); int num8 = ((!flag) ? 1 : num4); if (num8 != _columns) { _columns = num8; ApplyColumns(); } float num9 = Mathf.Max(flag ? num7 : num3, 0.3f); Vector2 val4 = default(Vector2); if (flag) { ((Vector2)(ref val4))..ctor(0.5f, 1f); val.anchorMax = val4; val.anchorMin = val4; val.pivot = new Vector2(0.5f, 1f); val.sizeDelta = new Vector2(num5, 0f); float num10 = ((Rect)(ref rect)).yMax - ((Rect)(ref val3)).yMax; val.anchoredPosition = new Vector2(((Rect)(ref val3)).center.x - ((Rect)(ref rect)).center.x, 0f - Mathf.Max(14f, (num10 - num6 * num9) / 2f)); } else { ((Vector2)(ref val4))..ctor(1f, 0.5f); val.anchorMax = val4; val.anchorMin = val4; val.pivot = new Vector2(1f, 0.5f); val.sizeDelta = new Vector2(400f, 0f); val.anchoredPosition = new Vector2(-14f, 0f); } ((Transform)val).localScale = new Vector3(num9, num9, 1f); } } private float HeightFor(int units, int columns) { //IL_0013: 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) int num = Mathf.CeilToInt((float)units / (float)columns); return (float)num * _grid.cellSize.y + (float)(num - 1) * _grid.spacing.y; } private void ApplyColumns() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown _grid.constraintCount = Mathf.Max(1, Mathf.CeilToInt((float)_units / (float)_columns)); LayoutRebuilder.MarkLayoutForRebuild((RectTransform)((Component)this).transform); } internal static Rect PassRect(BoardingPass pass, RectTransform space) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0011: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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) Rect result = Bounds((RectTransform)((Component)pass.startGameButton).transform, space); Rect rect = space.rect; float num = ((Rect)(ref rect)).height * 0.9f; Transform parent = ((Component)pass.startGameButton).transform.parent; while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)((Component)pass).transform) { RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (val != null && !((Object)(object)((Component)parent).GetComponent<PickerPanel>() != (Object)null)) { Rect val2 = Bounds(val, space); if (((Rect)(ref val2)).height < num) { float width = ((Rect)(ref val2)).width; rect = space.rect; if (width < ((Rect)(ref rect)).width && ((Rect)(ref val2)).width * ((Rect)(ref val2)).height > ((Rect)(ref result)).width * ((Rect)(ref result)).height) { result = val2; } } } parent = parent.parent; } return result; } private static Rect Bounds(RectTransform rt, RectTransform space) { //IL_0011: 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_001f: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0041: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) Vector3[] array = (Vector3[])(object)new Vector3[4]; rt.GetWorldCorners(array); Vector3 val = ((Transform)space).InverseTransformPoint(array[0]); Vector3 val2 = ((Transform)space).InverseTransformPoint(array[2]); return Rect.MinMaxRect(Mathf.Min(val.x, val2.x), Mathf.Min(val.y, val2.y), Mathf.Max(val.x, val2.x), Mathf.Max(val.y, val2.y)); } private void Update() { if (Time.unscaledTime < _nextPoll) { return; } _nextPoll = Time.unscaledTime + 0.5f; try { Refresh(force: false); } catch (Exception ex) { Plugin.Log.LogError((object)("BiomePicker panel refresh failed: " + ex)); ((Behaviour)this).enabled = false; } } private void Refresh(bool force) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown RunPlan runPlan = (Host ? PlanSync.Local : (PlanSync.Room ?? null)); string text = (Host ? "h:" : "c:") + ((runPlan != null) ? runPlan.Serialize() : "-"); if (!force && text == _shown) { return; } _shown = text; _plan = runPlan; foreach (Transform item in (Transform)_rows) { Transform val = item; ((Component)val).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)val).gameObject); } _units = 0; _footer.SetActive(Host); if (runPlan == null) { ((TMP_Text)_sub).text = "The host doesn't have BiomePicker: a normal run."; return; } int num = 0; BiomeEntry biomeEntry = null; foreach (BiomeEntry item2 in runPlan.Played) { if (item2.Id != "peak") { num++; biomeEntry = item2; } } string arg = ((biomeEntry != null && biomeEntry.Slot == 4) ? "then the Peak" : "then the island's own Caldera + Kiln or Gloom + Citadel up to the Peak"); ((TMP_Text)_sub).text = (Host ? $"{num} biomes, {arg}. Tick to keep, arrows to move." : $"The host's plan: {num} biomes, {arg}."); List<string[]> list = runPlan.Units(); int num2 = 0; for (int i = 0; i < list.Count; i++) { BiomeEntry[] array = Array.ConvertAll(list[i], RunPlan.Find); if (Array.IndexOf(array, null) < 0) { bool flag = !runPlan.Off.Contains(array[0].Id); if (flag) { num2++; } Row(i, array, flag, flag ? num2 : 0); _units++; } } ApplyColumns(); } private void Change(RunPlan p) { if (Host) { PlanSync.Save(p); Refresh(force: true); } } private void Row(int index, BiomeEntry[] es, bool on, int number) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_0085: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0193: 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_01f6: Unknown result type (might be due to invalid IL or missing references) BiomeEntry e = es[0]; GameObject val = new GameObject(e.Id, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)_rows, false); Rounded(val, on ? RowOn : RowOff, 10f); HorizontalLayoutGroup val2 = val.AddComponent<HorizontalLayoutGroup>(); ((LayoutGroup)val2).padding = new RectOffset(10, 8, 4, 4); ((HorizontalOrVerticalLayoutGroup)val2).spacing = 8f; ((LayoutGroup)val2).childAlignment = (TextAnchor)3; bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true); ((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = childControlWidth; ((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false; val.AddComponent<LayoutElement>().preferredHeight = 42f; TextMeshProUGUI val3 = Text(val.transform, (number > 0) ? number.ToString() : "", 20f, Accent, (TextAlignmentOptions)516, 34f); ((Component)val3).GetComponent<LayoutElement>().preferredWidth = 26f; if (!e.Fixed && Host) { Box(val.transform, on, delegate { RunPlan runPlan = _plan.Clone(); runPlan.Toggle(e.Id); Change(runPlan); }); } else { Spacer(val.transform, 26f); } string s = string.Join(" + ", Array.ConvertAll(es, (BiomeEntry x) => (x.Short ?? x.Title).ToUpperInvariant())); TextMeshProUGUI val4 = Text(val.transform, s, 21f, on ? Ink : Faint, (TextAlignmentOptions)513, 34f); ((Component)val4).GetComponent<LayoutElement>().flexibleWidth = 1f; if (e.Fixed) { ((Component)Text(val.transform, (e.Id == "shore") ? "START" : "FINISH", 14f, Faint, (TextAlignmentOptions)516, 34f)).GetComponent<LayoutElement>().preferredWidth = 74f; } else if (Host) { Arrow(val.transform, 45f, _plan.CanMove(index, -1), delegate { RunPlan runPlan = _plan.Clone(); runPlan.Move(index, -1); Change(runPlan); }); Arrow(val.transform, -135f, _plan.CanMove(index, 1), delegate { RunPlan runPlan = _plan.Clone(); runPlan.Move(index, 1); Change(runPlan); }); } } private TextMeshProUGUI Text(Transform parent, string s, float size, Color color, TextAlignmentOptions align, float height) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Text", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val2).font = _font; if ((Object)(object)_fontMat != (Object)null) { ((TMP_Text)val2).fontSharedMaterial = _fontMat; } ((TMP_Text)val2).fontSize = size; ((Graphic)val2).color = color; ((TMP_Text)val2).alignment = align; ((TMP_Text)val2).textWrappingMode = (TextWrappingModes)0; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).text = s; val.AddComponent<LayoutElement>().preferredHeight = height; return val2; } private static void Spacer(Transform parent, float w) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown GameObject val = new GameObject("Spacer", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); LayoutElement val2 = val.AddComponent<LayoutElement>(); val2.preferredWidth = w; val2.preferredHeight = 26f; } private static Graphic Rounded(GameObject go, Color color, float radius) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) ProceduralImage val = go.AddComponent<ProceduralImage>(); val.ModifierType = typeof(UniformModifier); UniformModifier component = go.GetComponent<UniformModifier>(); if ((Object)(object)component != (Object)null) { component.Radius = radius; } ((Graphic)val).color = color; return (Graphic)(object)val; } private void Box(Transform parent, bool on, Action click) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_006a: 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_00a2: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Keep", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); LayoutElement val2 = val.AddComponent<LayoutElement>(); float preferredWidth = (val2.preferredHeight = 26f); val2.preferredWidth = preferredWidth; Graphic targetGraphic = Rounded(val, new Color(1f, 1f, 1f, 0.16f), 6f); Button val3 = val.AddComponent<Button>(); ((Selectable)val3).targetGraphic = targetGraphic; ((UnityEvent)val3.onClick).AddListener((UnityAction)delegate { click(); }); GameObject val4 = new GameObject("Tick", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent(val.transform, false); RectTransform val5 = (RectTransform)val4.transform; val5.anchorMin = Vector2.zero; val5.anchorMax = Vector2.one; val5.offsetMin = new Vector2(5f, 5f); val5.offsetMax = new Vector2(-5f, -5f); Graphic val6 = Rounded(val4, Accent, 3f); val6.raycastTarget = false; val4.SetActive(on); } private void Arrow(Transform parent, float angle, bool enabled, Action click) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: 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_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject((angle > 0f) ? "Up" : "Down", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); LayoutElement val2 = val.AddComponent<LayoutElement>(); float preferredWidth = (val2.preferredHeight = 30f); val2.preferredWidth = preferredWidth; Graphic targetGraphic = Rounded(val, new Color(0f, 0f, 0f, enabled ? 0.35f : 0.12f), 8f); Button val3 = val.AddComponent<Button>(); ((Selectable)val3).targetGraphic = targetGraphic; ((Selectable)val3).interactable = enabled; ((UnityEvent)val3.onClick).AddListener((UnityAction)delegate { click(); }); GameObject val4 = new GameObject("Icon", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent(val.transform, false); RectTransform val5 = (RectTransform)val4.transform; Vector2 val6 = default(Vector2); ((Vector2)(ref val6))..ctor(0.5f, 0.5f); val5.anchorMax = val6; val5.anchorMin = val6; val5.sizeDelta = new Vector2(16f, 16f); ((Transform)val5).localRotation = Quaternion.Euler(0f, 0f, angle); if ((Object)(object)_arrow != (Object)null) { Image val7 = val4.AddComponent<Image>(); val7.sprite = _arrow; val7.preserveAspect = true; ((Graphic)val7).color = (enabled ? Ink : Faint); ((Graphic)val7).raycastTarget = false; } else { ((Transform)val5).localRotation = Quaternion.identity; Text(val4.transform, (angle > 0f) ? "UP" : "DN", 12f, enabled ? Ink : Faint, (TextAlignmentOptions)514, 16f); } } private void Pill(Transform parent, string label, Action click) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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) GameObject val = new GameObject(label, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); LayoutElement val2 = val.AddComponent<LayoutElement>(); val2.preferredWidth = 170f; val2.preferredHeight = 36f; Graphic targetGraphic = Rounded(val, new Color(0f, 0f, 0f, 0.35f), 18f); Button val3 = val.AddComponent<Button>(); ((Selectable)val3).targetGraphic = targetGraphic; ((UnityEvent)val3.onClick).AddListener((UnityAction)delegate { click(); }); TextMeshProUGUI val4 = Text(val.transform, label, 16f, Ink, (TextAlignmentOptions)514, 36f); RectTransform rectTransform = ((TMP_Text)val4).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; Vector2 offsetMin = (rectTransform.offsetMax = Vector2.zero); rectTransform.offsetMin = offsetMin; } } } namespace BiomePicker.Game { internal static class CopyFixups { private static int _nextFakeIndex = -1; private static readonly FieldRef<GenericOptimizer, bool> ScriptsEnabled = AccessTools.FieldRefAccess<GenericOptimizer, bool>("scriptsEnabled"); public static int FakeItemsAdded { get; private set; } public static void Reset() { _nextFakeIndex = -1; FakeItemsAdded = 0; } public static void Apply(GameObject copy, MapHandler mh) { Biome[] componentsInChildren = copy.GetComponentsInChildren<Biome>(true); foreach (Biome val in componentsInChildren) { val.mapHandler = mh; } SpawnedItemTracker[] componentsInChildren2 = copy.GetComponentsInChildren<SpawnedItemTracker>(true); foreach (SpawnedItemTracker val2 in componentsInChildren2) { Object.DestroyImmediate((Object)(object)val2); } FakeItemManager instance = FakeItemManager.Instance; if (_nextFakeIndex < 0) { _nextFakeIndex = (from f in instance.allFakeItems where (Object)(object)f != (Object)null select f.index).DefaultIfEmpty(-1).Max() + 1; } FakeItem[] componentsInChildren3 = copy.GetComponentsInChildren<FakeItem>(true); foreach (FakeItem val3 in componentsInChildren3) { val3.index = _nextFakeIndex++; val3.pickedUp = false; instance.allFakeItems.Add(val3); FakeItemsAdded++; } } public static (int restored, int optimizers) AsBeforeWaking(GameObject original, GameObject copy) { GenericOptimizer[] componentsInChildren = original.GetComponentsInChildren<GenericOptimizer>(true); GenericOptimizer[] componentsInChildren2 = copy.GetComponentsInChildren<GenericOptimizer>(true); if (componentsInChildren.Length != componentsInChildren2.Length) { return (restored: 0, optimizers: componentsInChildren2.Length); } IList list = (IList)AccessTools.Field(typeof(ItemOptimizationManager), "GENERIC_LIST").GetValue(null); int num = 0; for (int i = 0; i < componentsInChildren.Length; i++) { if (!list.Contains(componentsInChildren[i]) || ScriptsEnabled.Invoke(componentsInChildren[i])) { continue; } foreach (MonoBehaviour item in componentsInChildren2[i].scriptsToDisable ?? new List<MonoBehaviour>()) { if ((Object)(object)item != (Object)null && ((Component)item).transform.IsChildOf(copy.transform)) { ((Behaviour)item).enabled = true; } } foreach (Animator item2 in componentsInChildren2[i].animatorsToDisable ?? new List<Animator>()) { if ((Object)(object)item2 != (Object)null && ((Component)item2).transform.IsChildOf(copy.transform)) { ((Behaviour)item2).enabled = true; } } num++; } return (restored: num, optimizers: componentsInChildren2.Length); } public static int RegisterViews(GameObject root) { int num = 0; PhotonView[] componentsInChildren = root.GetComponentsInChildren<PhotonView>(true); foreach (PhotonView val in componentsInChildren) { if (val.sceneViewId != 0 && val.ViewID == 0 && !val.isRuntimeInstantiated) { if ((Object)(object)PhotonNetwork.GetPhotonView(val.sceneViewId) != (Object)null) { Plugin.Log.LogWarning((object)$"view ID {val.sceneViewId} of {((Object)val).name} is taken; it stays unregistered until it wakes"); continue; } val.ViewID = val.sceneViewId; val.FindObservables(false); num++; } } return num; } public static IEnumerable<string> Singletons(GameObject root) { return (from m in root.GetComponentsInChildren<MonoBehaviour>(true) where (Object)(object)m != (Object)null && IsSingleton(((object)m).GetType()) select ((object)m).GetType().Name).Distinct(); } private static bool IsSingleton(Type t) { Type baseType = t.BaseType; while (baseType != null) { if (baseType.IsGenericType && baseType.GetGenericTypeDefinition() == typeof(Singleton<>)) { return true; } baseType = baseType.BaseType; } return false; } public static void UsePeakOf(GameObject content) { if (!((Object)(object)content == (Object)null)) { PeakHandler componentInChildren = content.GetComponentInChildren<PeakHandler>(true); if (!((Object)(object)componentInChildren == (Object)null)) { AccessTools.Field(typeof(Singleton<PeakHandler>), "_instance").SetValue(null, componentInChildren); } } } } internal sealed class CustomStage { private sealed class Lift : IDisposable { private readonly GameObject _go; private readonly Vector3 _by; private readonly List<GameObject> _woken = new List<GameObject>(); public Lift(GameObject go, Vector3 by, bool wake) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown _go = go; _by = by; if ((Object)(object)_go == (Object)null) { return; } if (wake) { Transform val = _go.transform; while ((Object)(object)val != (Object)null) { if (!((Component)val).gameObject.activeSelf) { _woken.Add(((Component)val).gameObject); ((Component)val).gameObject.SetActive(true); } val = val.parent; } foreach (Transform item in _go.transform) { Transform val2 = item; if (!((Component)val2).gameObject.activeSelf && ((Object)val2).name.EndsWith("_Segment")) { _woken.Add(((Component)val2).gameObject); ((Component)val2).gameObject.SetActive(true); } } } if (_by != Vector3.zero) { Transform transform = _go.transform; transform.position += _by; } Physics.SyncTransforms(); } public void Dispose() { //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_002d: 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_0038: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_go == (Object)null)) { if (_by != Vector3.zero) { Transform transform = _go.transform; transform.position -= _by; } for (int num = _woken.Count - 1; num >= 0; num--) { _woken[num].SetActive(false); } Physics.SyncTransforms(); } } } public int Slot; public MapHandler Map; public Scene Scene; public Campfire Start; public Vector3 Offset; public GameObject Shore; public VariantPart Today; public Transform Home; public ulong Seed; public Func<GameObject, GameObject> CopyToday; public GameObject Unit; public GameObject Content; public GameObject EndCamp; public DayNightProfile Sky; public IDisposable ShoreAtStart() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return new Lift(Shore, Offset, wake: true); } public IDisposable SlotHere() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) return new Lift(Today.Unit, Offset - Stack.LiftOf(Today.Unit.transform), wake: false); } } internal interface ICustomBiome { string Id { get; } string Name { get; } string Title { get; } bool Available { get; } IEnumerator Build(CustomStage stage); void Enter(Round r); void Leave(Round r); } internal static class CustomBiomes { private static readonly List<ICustomBiome> All = new List<ICustomBiome>(); public static void Register(ICustomBiome b) { All.Add(b); Plugin.Log.LogInfo((object)("Custom biome " + b.Name + ": " + (b.Available ? "available" : "not installed"))); } public static ICustomBiome Find(string id) { return All.Find((ICustomBiome b) => b.Id == id); } } internal static class DonorGuard { private static readonly HashSet<string> Donors = new HashSet<string>(); private static bool _patched; private static readonly List<MethodBase> Patched = new List<MethodBase>(); internal static Action<Scene> Loaded; private static readonly Type[] ContentSingletons = new Type[1] { typeof(PeakHandler) }; private static readonly Dictionary<Type, object> Saved = new Dictionary<Type, object>(); internal static readonly Dictionary<string, int> Skipped = new Dictionary<string, int>(); private static readonly string[] Lifecycle = new string[5] { "Awake", "OnEnable", "OnDisable", "Start", "OnDestroy" }; internal static int PatchedMethods { get; private set; } internal static bool IsPatched => _patched; internal static int FailedMethods { get; private set; } internal static long PatchMs { get; private set; } internal static void FreeSingletons() { Saved.Clear(); Type[] contentSingletons = ContentSingletons; foreach (Type type in contentSingletons) { FieldInfo fieldInfo = AccessTools.Field(typeof(Singleton<>).MakeGenericType(type), "_instance"); Saved[type] = fieldInfo.GetValue(null); fieldInfo.SetValue(null, null); } } internal static void RestoreSingletons() { foreach (KeyValuePair<Type, object> item in Saved) { AccessTools.Field(typeof(Singleton<>).MakeGenericType(item.Key), "_instance").SetValue(null, item.Value); } Saved.Clear(); } internal static void Add(string scene) { Donors.Add(scene); } internal static void Remove(string scene) { Donors.Remove(scene); } internal static bool IsDonorScene(string scene) { return Donors.Contains(scene); } private static bool IsDonor(object o) { //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) if (Donors.Count == 0) { return false; } Component val = (Component)((o is Component) ? o : null); if (val == null || (Object)(object)val == (Object)null) { return false; } Scene scene = val.gameObject.scene; if (((Scene)(ref scene)).IsValid()) { return Donors.Contains(((Scene)(ref scene)).name); } return false; } private static void Count(MethodBase m) { string name = m.Name; Skipped.TryGetValue(name, out var value); Skipped[name] = value + 1; } private static bool SkipVoid(object __instance, MethodBase __originalMethod) { if (!IsDonor(__instance)) { return true; } Count(__originalMethod); return false; } private static bool SkipEnumerator(object __instance, MethodBase __originalMethod, ref IEnumerator __result) { if (!IsDonor(__instance)) { return true; } Count(__originalMethod); __result = Empty(); return false; } private static IEnumerator Empty() { yield break; } private static bool SceneLoadedPrefix(Scene scene) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!IsDonorScene(((Scene)(ref scene)).name)) { return true; } RestoreSingletons(); try { Loaded?.Invoke(scene); } catch (Exception ex) { Plugin.Log.LogError((object)("Donor scene setup failed: " + ex)); } return false; } private static bool SceneUnloadedPrefix(Scene scene) { return !IsDonorScene(((Scene)(ref scene)).name); } internal static void EnsurePatched(Harmony harmony) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown if (_patched) { return; } _patched = true; Stopwatch stopwatch = Stopwatch.StartNew(); harmony.Patch((MethodBase)AccessTools.Method(typeof(SceneManager), "Internal_SceneLoaded", (Type[])null, (Type[])null), new HarmonyMethod(typeof(DonorGuard), "SceneLoadedPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(SceneManager), "Internal_SceneUnloaded", (Type[])null, (Type[])null), new HarmonyMethod(typeof(DonorGuard), "SceneUnloadedPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyMethod val = new HarmonyMethod(typeof(DonorGuard), "SkipVoid", (Type[])null); HarmonyMethod val2 = new HarmonyMethod(typeof(DonorGuard), "SkipEnumerator", (Type[])null); HashSet<MethodBase> hashSet = new HashSet<MethodBase>(); foreach (MethodInfo item in LifecycleMethods()) { if (!hashSet.Add(item)) { continue; } try { if (item.ReturnType == typeof(void)) { harmony.Patch((MethodBase)item, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); goto IL_012c; } if (typeof(IEnumerator).IsAssignableFrom(item.ReturnType)) { harmony.Patch((MethodBase)item, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); goto IL_012c; } goto end_IL_00da; IL_012c: Patched.Add(item); PatchedMethods++; end_IL_00da:; } catch (Exception ex) { FailedMethods++; if (FailedMethods <= 5) { Plugin.Log.LogWarning((object)$"Donor guard: could not patch {item.DeclaringType}.{item.Name}: {ex.Message}"); } } } PatchMs = stopwatch.ElapsedMilliseconds; Plugin.Log.LogInfo((object)$"Donor guard: {PatchedMethods} lifecycle methods patched in {PatchMs} ms ({FailedMethods} failed)."); } internal static void Unpatch(Harmony harmony) { if (!_patched || Donors.Count > 0) { return; } Stopwatch stopwatch = Stopwatch.StartNew(); foreach (MethodBase item in Patched) { try { harmony.Unpatch(item, (HarmonyPatchType)1, harmony.Id); } catch (Exception ex) { Plugin.Log.LogWarning((object)$"Donor guard: could not unpatch {item.DeclaringType}.{item.Name}: {ex.Message}"); } } harmony.Unpatch((MethodBase)AccessTools.Method(typeof(SceneManager), "Internal_SceneLoaded", (Type[])null, (Type[])null), (HarmonyPatchType)1, harmony.Id); harmony.Unpatch((MethodBase)AccessTools.Method(typeof(SceneManager), "Internal_SceneUnloaded", (Type[])null, (Type[])null), (HarmonyPatchType)1, harmony.Id); Plugin.Log.LogInfo((object)$"Donor guard: {Patched.Count} lifecycle methods unpatched in {stopwatch.ElapsedMilliseconds} ms."); Patched.Clear(); PatchedMethods = 0; _patched = false; } private static IEnumerable<MethodInfo> LifecycleMethods() { string managed = Path.GetFullPath(Path.Combine(Application.dataPath, "Managed")); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly.IsDynamic || !IsGameAssembly(assembly, managed)) { continue; } Type[] array; try { array = assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { array = ex.Types.Where((Type t) => t != null).ToArray(); } Type[] array2 = array; foreach (Type type in array2) { if (type.ContainsGenericParameters || !typeof(MonoBehaviour).IsAssignableFrom(type)) { continue; } Type b = type; while (b != null && b != typeof(MonoBehaviour)) { if (!b.IsGenericType) { string[] lifecycle = Lifecycle; foreach (string name in lifecycle) { MethodInfo method = b.GetMethod(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (!(method == null) && !method.IsAbstract && !method.IsGenericMethod) { MethodBody methodBody; try { methodBody = method.GetMethodBody(); } catch { methodBody = null; } if (methodBody != null) { yield return method; } } } } b = b.BaseType; } } } } private static bool IsGameAssembly(Assembly asm, string managed) { string location; try { location = asm.Location; } catch { return false; } if (string.IsNullOrEmpty(location)) { return false; } if (!string.Equals(Path.GetFullPath(Path.GetDirectoryName(location)), managed, StringComparison.OrdinalIgnoreCase)) { return false; } string name = asm.GetName().Name; if (!(name == "mscorlib") && !(name == "netstandard") && !name.StartsWith("System") && !name.StartsWith("Mono.")) { if (name.StartsWith("UnityEngine.")) { return !name.EndsWith("Module"); } return true; } return false; } } internal sealed class DonorIsland { public int Level; public string SceneName; public Scene Scene; public MapHandler Map; public LightVolume Light; public double BundleSeconds; public double LoadSeconds; public long WorkingSetBefore; public long WorkingSetAfter; public int RootCount; public string Error; public bool Ok { get { if (Error == null) { return (Object)(object)Map != (Object)null; } return false; } } public static IEnumerator Load(Harmony harmony, int level, Action<DonorIsland> done) { DonorIsland d = new DonorIsland { Level = level, SceneName = SingletonAsset<MapBaker>.Instance.GetLevel(level) }; DonorGuard.EnsurePatched(harmony); DonorGuard.Skipped.Clear(); d.WorkingSetBefore = Process.GetCurrentProcess().WorkingSet64; Stopwatch sw = Stopwatch.StartNew(); MapBundleService service = GameHandler.GetService<MapBundleService>(); MapBundleData bundle = ((service != null) ? service.LoadBundlesNearestIndex(level, false) : null); while (bundle != null && bundle.Loading) { yield return null; } d.BundleSeconds = sw.Elapsed.TotalSeconds; sw.Restart(); DonorGuard.Add(d.SceneName); DonorGuard.Loaded = delegate(Scene scene) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) d.OnLoaded(scene); }; DonorGuard.FreeSingletons(); AsyncOperation op; try { op = SceneManager.LoadSceneAsync(d.SceneName, (LoadSceneMode)1); } catch (Exception ex) { op = null; d.Error = ex.Message; } if (op == null) { DonorIsland donorIsland = d; if (donorIsland.Error == null) { donorIsland.Error = "LoadSceneAsync returned null"; } DonorGuard.RestoreSingletons(); DonorGuard.Remove(d.SceneName); done(d); yield break; } while (!op.isDone) { LoadProgress.Report(op.progress / 0.9f); yield return null; } DonorGuard.Loaded = null; d.LoadSeconds = sw.Elapsed.TotalSeconds; d.WorkingSetAfter = Process.GetCurrentProcess().WorkingSet64; if ((Object)(object)d.Map == (Object)null && d.Error == null) { d.Error = "no MapHandler in " + d.SceneName; } done(d); } private void OnLoaded(Scene scene) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) Scene = scene; GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); RootCount = rootGameObjects.Length; GameObject[] array = rootGameObjects; foreach (GameObject val in array) { if ((Object)(object)Map == (Object)null) { Map = val.GetComponentInChildren<MapHandler>(true); } if ((Object)(object)Light == (Object)null) { Light = val.GetComponentInChildren<LightVolume>(true); } val.SetActive(false); } } public GameObject Copy(GameObject source, ViewIds ids) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) Transform transform = source.transform; Vector3 position = transform.position; Quaternion rotation = transform.rotation; Vector3 lossyScale = transform.lossyScale; source.SetActive(false); GameObject val = Object.Instantiate<GameObject>(source); ((Object)val).name = ((Object)source).name; val.transform.SetPositionAndRotation(position, rotation); val.transform.localScale = lossyScale; PhotonView[] componentsInChildren = val.GetComponentsInChildren<PhotonView>(true); foreach (PhotonView val2 in componentsInChildren) { if (val2.sceneViewId != 0 && !val2.isRuntimeInstantiated) { val2.ViewID = (val2.sceneViewId = ids.Next()); val2.FindObservables(false); } } return val; } public IEnumerator Unload() { if (((Scene)(ref Scene)).IsValid()) { AsyncOperation op = SceneManager.UnloadSceneAsync(Scene); while (op != null && !op.isDone) { yield return null; } DonorGuard.Remove(SceneName); } } } internal sealed class ViewIds { public const int Top = 8999; private readonly HashSet<int> _used = new HashSet<int>(); private int _next = 8999; public int Lowest => _next + 1; public ViewIds() { //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) PhotonView[] array = Object.FindObjectsByType<PhotonView>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (PhotonView val in array) { Scene scene = ((Component)val).gameObject.scene; if (!DonorGuard.IsDonorScene(((Scene)(ref scene)).name)) { if (val.sceneViewId != 0) { _used.Add(val.sceneViewId); } if (val.ViewID != 0) { _used.Add(val.ViewID); } } } } public int Next() { while (_used.Contains(_next) || (Object)(object)PhotonNetwork.GetPhotonView(_next) != (Object)null) { _next--; } if (_next <= 0) { throw new InvalidOperationException("no free scene view IDs left"); } _used.Add(_next); return _next--; } } [HarmonyPatch] internal static class GlobalSpawners { public static Dictionary<string, List<GameObject>> ByBiome(MapHandler map, List<VariantPart> parts) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00f2: Unknown result type (might be due to invalid IL or missing references) Dictionary<string, List<GameObject>> dictionary = new Dictionary<string, List<GameObject>>(); if ((Object)(object)map == (Object)null || (Object)(object)map.globalParent == (Object)null) { return dictionary; } List<(string, Collider[])> list = (from p in parts where (Object)(object)p.Parent != (Object)null select (Id: p.Id, Colliders: p.Parent.GetComponentsInChildren<Collider>(true))).ToList(); MonoBehaviour[] componentsInChildren = ((Component)map.globalParent).GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if (!(val is ISpawner)) { continue; } Vector3 position = ((Component)val).transform.position; string text = null; float num2 = float.MaxValue; foreach (var (text2, colliders) in list) { using Stack.GroundProbe groundProbe = new Stack.GroundProbe(colliders, position, 8f); if (groundProbe.Count != 0) { float? num3 = groundProbe.Nearest(position, 8f); if (num3.HasValue && num3.Value < num2) { num2 = num3.Value; text = text2; } } } if (text != null) { if (!dictionary.TryGetValue(text, out var value)) { value = (dictionary[text] = new List<GameObject>()); } if (!value.Contains(((Component)val).gameObject)) { value.Add(((Component)val).gameObject); } } } return dictionary; } public static int CopyInto(Dictionary<string, List<GameObject>> spawners, string id, GameObject content, Vector3 by, Func<GameObject, GameObject> copy) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)content == (Object)null || !spawners.TryGetValue(id, out var value) || value.Count == 0) { return 0; } GameObject val = new GameObject("BiomePicker island spawners"); val.transform.SetParent(content.transform, false); foreach (GameObject item in value) { GameObject val2 = copy(item); val2.transform.SetParent(val.transform, true); val2.transform.position = item.transform.position + by; val2.SetActive(true); } return value.Count; } [HarmonyPrefix] [HarmonyPatch(typeof(MapHandler), "Update")] private static bool HoldFirstSpawn(MapHandler __instance) { if (!__instance.hasSpawnedInitialSpawners) { return !RunDirector.SettingUp; } return true; } } internal static class IslandCatalog { public const int BundleSize = 32; public static MapBaker Baker => SingletonAsset<MapBaker>.Instance; public static int Count { get { if (!((Object)(object)Baker != (Object)null) || Baker.ScenePaths == null) { return 0; } return Baker.ScenePaths.Length; } } public static string Code(int level) { if (!((Object)(object)Baker != (Object)null)) { return ""; } return Baker.GetBiomeID(level); } public static int LevelOf(string sceneName) { int num = sceneName.IndexOf("Level_"); if (num < 0) { return -1; } if (!int.TryParse(sceneName.Substring(num + 6), out var result)) { return -1; } return result; } public static int BundleOf(int level) { return level / 32; } public static int MostDifferent(int level) { string text = Code(level); int result = -1; int num = int.MinValue; for (int i = 0; i < Count; i++) { if (i == level) { continue; } string text2 = Code(i); int num2 = 0; for (int j = 0; j < Mathf.Max(text2.Length, text.Length); j++) { if (j >= text2.Length || j >= text.Length || text2[j] != text[j]) { num2++; } } int num3 = num2 * 1000 + ((BundleOf(i) == BundleOf(level)) ? 500 : 0) - Mathf.Abs(i - level); if (num3 > num) { num = num3; result = i; } } return result; } public static IEnumerable<string> Describe() { for (int i = 0; i < Count; i++) { yield return $"{i,3} {Baker.GetLevel(i),-10} {Code(i)}"; } } } internal static class LightGrids { private static readonly MethodInfo Load = AccessTools.Method(typeof(LightVolume), "LoadLightMapData", (Type[])null, (Type[])null); private static readonly MethodInfo Vars = AccessTools.Method(typeof(LightVolume), "SetShaderVars", (Type[])null, (Type[])null); private static readonly FieldInfo Instance = AccessTools.Field(typeof(LightVolume), "instance"); private static readonly Dictionary<LightVolume, Vector3> Home = new Dictionary<LightVolume, Vector3>(); private static LightVolume _today; private static LightVolume _current; public static void Reset() { Home.Clear(); _today = LightVolume.Instance(); _current = _today; } public static void Use(LightVolume grid, Vector3 lift) { //IL_0060: 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_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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) LightVolume val = (((Object)(object)grid != (Object)null) ? grid : _today); if (!((Object)(object)val == (Object)null)) { Stopwatch stopwatch = Stopwatch.StartNew(); bool flag = (Object)(object)val != (Object)(object)_current; if (flag) { Load.Invoke(val, null); } if (!Home.TryGetValue(val, out var value)) { value = (Home[val] = val.gridOffset); } Vector3 val2 = value + lift; if (flag || !(val.gridOffset == val2)) { val.gridOffset = val2; Vars.Invoke(val, null); Instance.SetValue(null, val); _current = val; Plugin.Log.LogInfo((object)string.Format("Light grid: {0}{1} in {2} ms", ((Object)(object)val == (Object)(object)_today) ? "today's" : ((Object)val).name, (lift != Vector3.zero) ? $" lifted by {lift:F1}" : "", stopwatch.ElapsedMilliseconds)); } } } } internal static class LoadProgress { private sealed class Step { public string Key; public string Label; public float Expected; public bool Done; public float Fraction = -1f; public Stopwatch Clock; } [Serializable] private sealed class TimingsFile { public List<string> keys = new List<string>(); public List<float> seconds = new List<float>(); } private static readonly Dictionary<string, float> Defaults = new Dictionary<string, float> { ["island"] = 10f, ["guard"] = 1.5f, ["donor"] = 4.8f, ["copy"] = 0.3f, ["camps"] = 0.4f, ["lostcity"] = 5.5f, ["sakura"] = 18f, ["finish"] = 1.3f, ["setup"] = 25f }; private static Dictionary<string, float> _timings; private static readonly List<Step> Steps = new List<Step>(); private static Step _current; private static Stopwatch _setup; public static bool Shown { get; private set; } private static string FilePath => Path.Combine(Paths.CachePath, "BiomePicker.timings.json"); public static float Value { get { float num = Steps.Sum((Step s) => s.Expected); float num2 = 0f; if (num <= 0f) { return 0f; } foreach (Step step in Steps) { if (step.Done) { num2 += step.Expected; } else if (step.Clock != null) { float num3 = ((step.Fraction >= 0f) ? step.Fraction : Mathf.Min(0.95f, (float)step.Clock.Elapsed.TotalSeconds / step.Expected)); num2 += num3 * step.Expected; } } return Mathf.Clamp01(num2 / num); } } public static string Label => (_current ?? Steps.FirstOrDefault((Step s) => !s.Done))?.Label ?? "Almost there"; private static float Expect(string key) { if (_timings == null) { LoadTimings(); } if (_timings.TryGetValue(key, out var value) && value > 0f) { return value; } if (!Defaults.TryGetValue(key, out var value2)) { return 1f; } return value2; } public static void Begin() { Steps.Clear(); _current = null; _setup = null; Shown = true; Add("island", "Flying to the island"); Start("island"); Add("setup", "Setting up the run"); } public static void BeginSetup() { if (Shown) { Steps.RemoveAll((Step s) => s.Key == "setup" && !s.Done); _setup = Stopwatch.StartNew(); } } public static void Add(string key, string label) { if (Shown) { Steps.Add(new Step { Key = key, Label = label, Expected = Expect(key) }); } } public static void Start(string key) { if (!Shown) { return; } Step s = Steps.FirstOrDefault((Step x) => !x.Done && x.Key == key && x.Clock == null); if (s == null) { return; } foreach (Step item in Steps.TakeWhile((Step x) => x != s)) { Finish(item); } s.Clock = Stopwatch.StartNew(); _current = s; } public static void Report(float fraction) { if (_current != null) { _current.Fraction = Mathf.Clamp01(fraction); } } public static void End(string key) { Step step = Steps.FirstOrDefault((Step x) => x.Key == key && x.Clock != null && !x.Done); if (step != null) { Finish(step); Remember(step.Key, (float)step.Clock.Elapsed.TotalSeconds); } } private static void Finish(Step s) { s.Done = true; if (_current == s) { _current = null; } } public static void Complete() { if (_setup != null) { Remember("setup", (float)_setup.Elapsed.TotalSeconds); } _setup = null; foreach (Step step in Steps) { step.Done = true; } _current = null; Shown = false; SaveTimings(); } private static void Remember(string key, float seconds) { if (_timings == null) { LoadTimings(); } if (!(seconds <= 0.01f)) { if (key == "copy" || key == "camps") { _timings[key] = (_timings.TryGetValue(key, out var value) ? Mathf.Lerp(value, seconds, 0.3f) : seconds); } else { _timings[key] = (_timings.TryGetValue(key, out var value2) ? Mathf.Lerp(value2, seconds, 0.6f) : seconds); } } } private static void LoadTimings() { _timings = new Dictionary<string, float>(); try { if (File.Exists(FilePath)) { TimingsFile timingsFile = JsonUtility.FromJson<TimingsFile>(File.ReadAllText(FilePath)); for (int i = 0; i < Mathf.Min(timingsFile.keys.Count, timingsFile.seconds.Count); i++) { _timings[timingsFile.keys[i]] = timingsFile.seconds[i]; } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("loading-bar timings unreadable: " + ex.Message)); } } private static void SaveTimings() { if (_timings == null) { return; } try { TimingsFile timingsFile = new TimingsFile(); foreach (KeyValuePair<string, float> timing in _timings) { timingsFile.keys.Add(timing.Key); timingsFile.seconds.Add(timing.Value); } Directory.CreateDirectory(Path.GetDirectoryName(FilePath)); File.WriteAllText(FilePath, JsonUtility.ToJson((object)timingsFile)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("loading-bar timings not saved: " + ex.Message)); } } } internal sealed class LostCityBiome : ICustomBiome { private const string StandIn = "BiomePicker"; private static Type _runtime; private static MethodInfo _takeOver; private static MethodInfo _forNewCity; private static MethodInfo _seedFor; private static MethodInfo _afterInit; private static MethodInfo _setCurrent; private static FieldInfo _conflict; private static FieldInfo _fogHandler; private static FieldInfo _fogBase; private static string _saved; private static bool _swapped; public string Id => "lostcity"; public string Name => "Lost City"; public string Title => "LOST CITY"; public bool Available { get { if (_takeOver != null && _forNewCity != null && _seedFor != null && _afterInit != null) { return _setCurrent != null; } return false; } } public LostCityBiome(Harmony harmony) { //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_01ac: Expected O, but got Unknown //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Expected O, but got Unknown //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Expected O, but got Unknown if (Chainloader.PluginInfos.TryGetValue("Tobeyyy.LostCity", out var value) && !((Object)(object)value.Instance == (Object)null)) { Assembly assembly = ((object)value.Instance).GetType().Assembly; _runtime = assembly.GetType("LostCity.Game.CityRuntime"); Type type = assembly.GetType("LostCity.Game.SessionRules"); _takeOver = AccessTools.Method(_runtime, "TakeOver", (Type[])null, (Type[])null); _forNewCity = AccessTools.Method(type, "ForNewCity", (Type[])null, (Type[])null); _seedFor = AccessTools.Method(assembly.GetType("LostCity.Game.Seeds"), "ForScene", (Type[])null, (Type[])null); _afterInit = AccessTools.Method(_runtime, "AfterInitializeMap", (Type[])null, (Type[])null); _setCurrent = AccessTools.PropertySetter(_runtime, "Current"); _conflict = AccessTools.Field(assembly.GetType("LostCity.Plugin"), "ConflictingPlugin"); Type type2 = assembly.GetType("LostCity.Game.FogPace"); _fogHandler = AccessTools.Field(type2, "_handler"); _fogBase = AccessTools.Field(type2, "_baseSpeed"); MethodInfo methodInfo = AccessTools.Method(assembly.GetType("LostCity.Game.Handshake"), "Notice", (Type[])null, (Type[])null); if (_conflict != null && methodInfo != null) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(LostCityBiome), "NoNoticeAboutUs", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (_conflict != null) { harmony.Patch((MethodBase)AccessTools.Method(_runtime, "OnSceneLoaded", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LostCityBiome), "BeforeSceneLoaded", (Type[])null), new HarmonyMethod(typeof(LostCityBiome), "AfterSceneLoaded", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo2 = AccessTools.Method(assembly.GetType("LostCity.Game.HostWarp"), "Update", (Type[])null, (Type[])null); if (methodInfo2 != null) { harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(LostCityBiome), "NoWarpInRuns", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (_fogHandler != null && _fogBase != null) { harmony.Patch((MethodBase)AccessTools.Method(type2, "Update", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LostCityBiome), "FogOnlyInTheCity", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private static bool NoWarpInRuns() { return !RunDirector.Active; } private static void BeforeSceneLoaded(Scene scene) { if (PlanSync.WillRun(((Scene)(ref scene)).name)) { _saved = (string)_conflict.GetValue(null); _conflict.SetValue(null, "BiomePicker"); _swapped = true; } } private static bool NoNoticeAboutUs(string text) { if (!_swapped || text == null || !text.Contains("BiomePicker")) { return true; } Plugin.Log.LogInfo((object)"Lost City's \"is off\" notice kept off the screen: Lost City is a round of this run."); return false; } private static void AfterSceneLoaded() { if (_swapped) { _conflict.SetValue(null, _saved); _swapped = false; } } private static bool FogOnlyInTheCity(object __instance) { if (!RunDirector.Active) { return true; } if (RunDirector.CurrentRound?.Id == "lostcity") { return true; } object? value = _fogHandler.GetValue(__instance); OrbFogHandler val = (OrbFogHandler)((value is OrbFogHandler) ? value : null); if (val != null && (Object)(object)val != (Object)null) { float num = (float)_fogBase.GetValue(__instance); if (num > 0f && !Mathf.Approximately(val.speed, num)) { val.speed = num; } } return false; } public IEnumerator Build(CustomStage st) { VariantPart today = st.Today; MapHandler map = st.Map; GameObject val = st.CopyToday(today.Unit); Transform transform = val.transform; transform.position += st.Offset; GameObject val2 = Variants.Find(val, Variants.Relative(today.Unit.transform, today.Parent.transform)); GameObject val3 = Variants.Find(val, Variants.Relative(today.Unit.transform, today.Campfire.transform)); if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { throw new InvalidOperationException("Lost City: the copy of today's slot misses its parts"); } MapSegment val4 = map.segments[st.Slot]; GameObject segmentParent = val4._segmentParent; GameObject segmentCampfire = val4._segmentCampfire; DayNightProfile dayNightProfile = val4._dayNightProfile; BiomeType biome = val4._biome; bool hasVariant = val4.hasVariant; val2.SetActive(true); val3.SetActive(true); val.SetActive(true); Physics.SyncTransforms(); IDisposable disposable = st.ShoreAtStart(); object obj2; try { val4._segmentParent = val2; val4._segmentCampfire = val3; val4._dayNightProfile = today.Sky; val4._biome = today.Biome; val4.hasVariant = false; object[] array = new object[1]; object obj = _forNewCity.Invoke(null, array); if (array[0] is string text) { Plugin.Log.LogWarning((object)("Lost City: " + text)); } if (obj == null) { throw new InvalidOperationException("Lost City has no rules in this lobby (the host has no Lost City)"); } ulong num = (ulong)_seedFor.Invoke(null, new object[2] { ((Scene)(ref st.Scene)).name, obj }); obj2 = _takeOver.Invoke(null, new object[4] { st.Scene, map, num, obj }); _setCurrent.Invoke(null, new object[1] { obj2 }); _afterInit.Invoke(null, null); } finally { disposable.Dispose(); val4._segmentParent = segmentParent; val4._segmentCampfire = segmentCampfire; val4._dayNightProfile = dayNightProfile; val4._biome = biome; val4.hasVariant = hasVariant; } GameObject val5 = (GameObject)AccessTools.Field(obj2.GetType(), "Root").GetValue(obj2); val5.transform.SetParent(val.transform, true); val5.SetActive(false); val3.SetActive(false); val.SetActive(false); ((Object)val).name = "BiomePicker Lost City"; st.Unit = val; st.Content = val5; st.EndCamp = val3; yield break; } public void Enter(Round r) { } public void Leave(Round r) { } } [HarmonyPatch] internal static class PlanSync { public const string RoomKey = "BiomePicker.plan"; public static RunPlan Local { get { string text = Plugin.DevPlan?.Value; return RunPlan.Parse((!string.IsNullOrWhiteSpace(text)) ? text : Plugin.Plan.Value); } } public static RunPlan Room { get { if (!PhotonNetwork.InRoom) { return null; } if (!((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"BiomePicker.plan", out object value) || !(value is string text)) { return null; } return RunPlan.Parse(text); } } public static void Save(RunPlan plan) { Plugin.Plan.Value = plan.Serialize(); Publish(plan); } public static void Publish(RunPlan plan) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient) { PhotonNetwork.CurrentRoom.SetCustomProperties(new Hashtable { [(object)"BiomePicker.plan"] = plan.Serialize() }, (Hashtable)null, (WebFlags)null); } } public static bool WillRun(string scene) { if ((scene.StartsWith("Level_") || scene.Contains("Island")) && !RunSettings.isMiniRun && Plugin.ConflictingPlugin == null && Plugin.DevPlan?.Value != "off") { if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient) { return Room != null; } return true; } return false; } public static RunPlan ForIsland() { if (RunSettings.isMiniRun || Plugin.ConflictingPlugin != null || Plugin.DevPlan?.Value == "off") { return null; } if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient) { RunPlan local = Local; Publish(local); return local; } return Room; } [HarmonyPrefix] [HarmonyPatch(typeof(AirportCheckInKiosk), "LoadIslandMaster")] private static void BeforeIslandLoad() { Publish(Local); } } [HarmonyPatch] internal static class Resume { [Serializable] private sealed class Save { public string runId; public string scene; public string plan; public int round; } private static string FilePath => Path.Combine(Application.persistentDataPath, "biomepicker.quicksave.json"); public static int PendingRound { get; private set; } public static RunPlan ForContinue(string scene) { PendingRound = 0; if (!Quicksave.ShouldUseSaveData || !File.Exists(FilePath)) { return null; } try { Save save = JsonUtility.FromJson<Save>(File.ReadAllText(FilePath)); if (save == null || save.scene != scene || save.runId != Quicksave.SavedRunId) { return null; } PendingRound = save.round; Plugin.Log.LogInfo((object)$"BiomePicker: continuing run {save.runId} at round {save.round} ({save.plan})"); return RunPlan.Parse(save.plan); } catch (Exception ex) { Plugin.Log.LogWarning((object)("BiomePicker save unreadable: " + ex.Message)); return null; } } [HarmonyPostfix] [HarmonyPatch(typeof(Quicksave), "SaveNow")] private static void AfterSave() { //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) if (!RunDirector.Active || (Object)(object)RunManager.Instance == (Object)null) { return; } try { Save obj = new Save { runId = RunManager.Instance.RunId.ToString() }; Scene scene = ((Component)Singleton<MapHandler>.Instance).gameObject.scene; obj.scene = ((Scene)(ref scene)).name; obj.plan = RunDirector.Plan?.Serialize(); obj.round = RunDirector.Current; Save save = obj; File.WriteAllText(FilePath, JsonUtility.ToJson((object)save)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("BiomePicker save failed: " + ex.Message)); } } [HarmonyPrefix] [HarmonyPatch(typeof(MapHandler), "JumpToSegment")] private static bool BeforeJump(Segment segment) { if (PendingRound <= 0 || !RunDirector.Active || !PhotonNetwork.IsMasterClient) { return true; } int index = Mathf.Min(PendingRound, RoundTable.Rounds.Count - 1); PendingRound = 0; RunDirector.ContinueAt(index); return false; } } internal sealed class Round { public int Index; public BiomeEntry Entry; public Vector3 Offset; public Vector3 FogShift; public bool ToThePeak; public GameObject Unit; public GameObject Content; public GameObject EndCamp; public GameObject PartnerParent; public GameObject PartnerCamp; public Transform Statue; public DayNightProfile Sky; public BiomeType Biome; public LightVolume Light; public GameObject StartStatue; public bool SummitCamp; public List<Vector3> Platform; public float Sink; public bool BringsFloor; public List<Vector3> CampCells; public bool SummitGrounded; public bool Last; public readonly List<GameObject> Hide = new List<GameObject>(); public string Source = "today"; public ICustomBiome Custom; public int Island = -1; public bool FakeMountainOff; public string Id => Entry.Id; public int Slot => Entry.Slot; public string Title => Entry.Title; public override string ToString() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) string[] array = new string[7]; object[] obj = new object[8] { Index, Id, Slot, ToThePeak ? " (up to the Peak)" : "", Source, Offset, null, null }; GameObject unit = Unit; obj[6] = ((unit != null) ? ((Object)unit).name : null); GameObject content = Content; obj[7] = ((content != null) ? ((Object)content).name : null); array[0] = string.Format("#{0} {1} slot {2}{3} from {4}: lift {5:F1}, unit {6}, content {7}, ", obj); array[1] = "end "; GameObject endCamp = EndCamp; array[2] = ((endCamp != null) ? ((Object)endCamp).name : null) ?? "-"; array[3] = ", sky "; DayNightProfile sky = Sky; array[4] = ((sky != null) ? ((Object)sky).name : null) ?? "-"; array[5] = ", light "; array[6] = (((Object)(object)Light != (Object)null) ? "own" : "today's"); return string.Concat(array); } } internal static class RoundTable { private sealed class PartPaths { public string Parent; public string Campfire; public DayNightProfile Sky; public static PartPaths Of(VariantPart p) { return new PartPaths { Parent = Variants.Relative(p.Unit.transform, p.Parent.transform), Campfire = (((Object)(object)p.Campfire != (Object)null) ? Variants.Relative(p.Unit.transform, p.Campfire.transform) : null), Sky = p.Sky }; } } public static readonly List<Round> Rounds = new List<Round>(); private static readonly List<GameObject> SlotUnits = new List<GameObject>(); private static GameObject _noCamp; public static bool Ready { get; private set; } public static bool Busy { get; private set; } public static string Error { get; private set; } public static string Report { get; private set; } = ""; public static void Clear() { Rounds.Clear(); SlotUnits.Clear(); Stack.Reset(); StackPatches.Reset(); Ready = false; Busy = false; Error = null; Report = ""; } public static IEnumerator Build(RunPlan plan) { Clear(); CopyFixups.Reset(); Busy = true; StringBuilder log = new StringBuilder(); Stopwatch sw = Stopwatch.StartNew(); IEnumerator body = BuildBody(plan, Note); while (true) { bool flag; try { flag = body.MoveNext(); } catch (Exception ex) { Error = ex.ToString(); Plugin.Log.LogError((object)("BiomePicker could not set up the run, it plays as a normal run: " + ex)); Rounds.Clear(); break; } if (!flag) { break; } yield return body.Current; } Note(string.Format("set up in {0} ms: {1}", sw.ElapsedMilliseconds, (Error == null) ? (Rounds.Count + " rounds") : "FAILED")); Report = log.ToString(); Ready = Error == null && Rounds.Count > 1; Busy = false; void Note(string s) { log.AppendLine(s); Plugin.Log.LogInfo((object)("[Rounds] " + s)); } } private static IEnumerator BuildBody(RunPlan plan, Action<string> note) { MapHandler mh = Singleton<MapHandler>.Instance; Scene scene = ((Compo