Decompiled source of TrueFinalAscent v1.0.4
BepInEx/plugins/CptPICHU-TrueFinalAscent/TrueFinalAscent.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Peak; using Peak.Afflictions; using Peak.LevelGeneration; using Photon.Pun; using Photon.Realtime; using TMPro; using Unity.Collections; using Unity.Jobs; using Unity.Jobs.LowLevel.Unsafe; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Profiling; using UnityEngine.Rendering; using UnityEngine.Rendering.UnifiedRayTracing; using UnityEngine.Rendering.Universal; using UnityEngine.SceneManagement; using UnityEngine.TextCore; using UnityEngine.UI; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("TrueFinalAscent")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("TrueFinalAscent")] [assembly: AssemblyTitle("TrueFinalAscent")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 TrueFinalAscent { [HarmonyPatch(typeof(UIPlayerNames), "UpdateName")] internal static class AscentNameColorPatch { private static void Postfix(UIPlayerNames __instance, int index, bool visible) { if (!visible || __instance.playerNameText == null || index < 0 || index >= __instance.playerNameText.Length) { return; } PlayerName val = __instance.playerNameText[index]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val.text == (Object)null) && !((Object)(object)val.characterInteractable == (Object)null)) { Character character = val.characterInteractable.character; if (!((Object)(object)character == (Object)null)) { AscentNameColor.Apply((TMP_Text)(object)val.text, character); } } } } [HarmonyPatch(typeof(AudioLevelSlider), "Update")] internal static class AscentAudioSliderColorPatch { private static void Postfix(AudioLevelSlider __instance) { if (__instance.player != null && !((Object)(object)__instance.playerName == (Object)null)) { Character playerCharacter = PlayerHandler.GetPlayerCharacter(__instance.player); if (!((Object)(object)playerCharacter == (Object)null)) { AscentNameColor.Apply((TMP_Text)(object)__instance.playerName, playerCharacter); } } } } [HarmonyPatch(typeof(EndScreenScoutWindow), "Init", new Type[] { typeof(Character) })] internal static class AscentEndScreenNamePatch { private static void Postfix(EndScreenScoutWindow __instance, Character character) { if (!((Object)(object)character == (Object)null) && !((Object)(object)__instance.scoutName == (Object)null)) { AscentNameColor.Apply(__instance.scoutName, character); } } } internal static class AscentNameColor { internal const int TotalAscents = 8; private const float FontSizeMultiplier = 1.15f; private static readonly Dictionary<TMP_Text, float> ConfiguredTexts = new Dictionary<TMP_Text, float>(); internal static int GetClearedCount(Character character) { if ((Object)(object)character == (Object)null) { return 0; } AscentSync component = ((Component)character).GetComponent<AscentSync>(); return Mathf.Clamp(((Object)(object)component != (Object)null) ? component.Cleared : 0, 0, 8); } internal static void Apply(TMP_Text text, Character character) { EnsureBaseSetup(text); AscentSync ascentSync = (((Object)(object)character != (Object)null) ? ((Component)character).GetComponent<AscentSync>() : null); int clearedCount = GetClearedCount(character); NameStyle wanted = (((Object)(object)ascentSync != (Object)null) ? ascentSync.Style : NameStyle.Auto); bool final = (Object)(object)ascentSync != (Object)null && ascentSync.FinalDone; AscentTitle.Paint(text, AscentTitle.Resolve(wanted, clearedCount, final)); } private static void EnsureBaseSetup(TMP_Text text) { if (!ConfiguredTexts.ContainsKey(text)) { float fontSize = text.fontSize; ConfiguredTexts[text] = fontSize; text.fontSize = fontSize * 1.15f; } } } [HarmonyPatch(typeof(PauseMenuHandler), "OnEnable")] internal static class AscentOverviewPatch { private static void Postfix(PauseMenuHandler __instance) { AscentOverviewPanel.EnsureCreated(((Component)__instance).transform); } } internal static class AscentOverviewPanel { private const string GreenHex = "#4CD964"; private const string GrayHex = "#585858"; private static readonly Color Slate = new Color(0.13f, 0.13f, 0.145f, 1f); private static GameObject _root; private static TextMeshProUGUI _text; private static TMP_Dropdown _pick; private static readonly List<NameStyle> Offered = new List<NameStyle>(); internal static void EnsureCreated(Transform parent) { if ((Object)(object)_root == (Object)null) { Build(parent); } ((TMP_Text)_text).text = BuildText(); FillChoices(parent); } private static void Build(Transform parent) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0048: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) _root = new GameObject("PiCHU_AscentOverview", new Type[1] { typeof(RectTransform) }); _root.transform.SetParent(parent, false); RectTransform component = _root.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(0f, 0f); component.pivot = new Vector2(0f, 0f); component.anchoredPosition = new Vector2(32f, 32f); component.sizeDelta = new Vector2(340f, 270f); GameObject val = new GameObject("Text", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(_root.transform, false); RectTransform component2 = val.GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0f, 0f); component2.anchorMax = new Vector2(0f, 0f); component2.pivot = new Vector2(0f, 0f); component2.anchoredPosition = Vector2.zero; component2.sizeDelta = new Vector2(340f, 180f); _text = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)_text).fontSize = 34f; ((TMP_Text)_text).lineSpacing = 8f; ((TMP_Text)_text).alignment = (TextAlignmentOptions)1025; ((TMP_Text)_text).textWrappingMode = (TextWrappingModes)0; ((Graphic)_text).raycastTarget = false; ApplyPeakFont(_text, parent); _pick = FinalAscentUiKit.Drop(_root.transform, 0f, 0f, 300f, 58f); RectTransform component3 = ((Component)_pick).GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0f, 0f); component3.anchorMax = new Vector2(0f, 0f); component3.pivot = new Vector2(0f, 0f); component3.anchoredPosition = new Vector2(0f, 196f); component3.sizeDelta = new Vector2(300f, 58f); Darken(_pick); _root.AddComponent<AscentChoicePreview>().Bind(_pick, Offered); } private static void Darken(TMP_Dropdown drop) { //IL_0011: 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_008d: Unknown result type (might be due to invalid IL or missing references) Image component = ((Component)drop).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = Slate; } if ((Object)(object)drop.template != (Object)null) { Image component2 = ((Component)drop.template).GetComponent<Image>(); if ((Object)(object)component2 != (Object)null) { ((Graphic)component2).color = Slate; } } TMP_Text[] componentsInChildren = ((Component)drop).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.text == "▾") { ((Graphic)val).color = new Color(0.78f, 0.78f, 0.8f, 1f); } } } private static void FillChoices(Transform parent) { int cleared = AscentTitle.ClearedLocally(); bool finalDone = AscentTitle.FinalDone; Offered.Clear(); List<string> list = new List<string>(); NameStyle[] array = new NameStyle[6] { NameStyle.Auto, NameStyle.Plain, NameStyle.Silver, NameStyle.Gold, NameStyle.Diamond, NameStyle.Rainbow }; foreach (NameStyle nameStyle in array) { if (AscentTitle.Unlocked(nameStyle, cleared, finalDone)) { Offered.Add(nameStyle); list.Add(AscentTitle.TitleOf(nameStyle)); } } ((UnityEventBase)_pick.onValueChanged).RemoveAllListeners(); _pick.ClearOptions(); _pick.AddOptions(list); int num = Offered.IndexOf(AscentTitle.Chosen); _pick.value = ((num >= 0) ? num : 0); _pick.RefreshShownValue(); ((UnityEvent<int>)(object)_pick.onValueChanged).AddListener((UnityAction<int>)delegate(int picked) { if (picked >= 0 && picked < Offered.Count) { AscentTitle.Choose(Offered[picked]); } }); ApplyNameLook(parent); } private static void ApplyNameLook(Transform parent) { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) TMP_Text val = null; AudioLevelSlider[] array = (((Object)(object)parent != (Object)null) ? ((Component)parent).GetComponentsInChildren<AudioLevelSlider>(true) : null); if (array != null) { AudioLevelSlider[] array2 = array; foreach (AudioLevelSlider val2 in array2) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2.playerName != (Object)null) { val = (TMP_Text)(object)val2.playerName; break; } } } if ((Object)(object)val == (Object)null) { AudioLevelSlider val3 = Object.FindFirstObjectByType<AudioLevelSlider>(); val = (TMP_Text)(object)(((Object)(object)val3 != (Object)null && (Object)(object)val3.playerName != (Object)null) ? val3.playerName : _text); } TMP_Text[] componentsInChildren = ((Component)_pick).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val4 in componentsInChildren) { if (!((Object)(object)val4 == (Object)null) && !(val4.text == "▾")) { if ((Object)(object)val != (Object)null && (Object)(object)val.font != (Object)null) { val4.font = val.font; val4.fontSharedMaterial = val.fontSharedMaterial; val4.fontStyle = val.fontStyle; } val4.enableAutoSizing = true; val4.fontSizeMin = 16f; val4.fontSizeMax = 30f; } } } private static void ApplyPeakFont(TextMeshProUGUI text, Transform searchRoot) { TMP_Text val = ((Component)searchRoot).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)val == (Object)null) { val = Object.FindFirstObjectByType<TMP_Text>(); } if ((Object)(object)val != (Object)null && (Object)(object)val.font != (Object)null) { ((TMP_Text)text).font = val.font; ((TMP_Text)text).fontSharedMaterial = val.fontSharedMaterial; } } private static string BuildText() { int num = AscentTitle.ClearedLocally(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("ASCENT\n"); for (int i = 1; i <= 8; i++) { bool flag = i <= num; stringBuilder.Append("<color=").Append(flag ? "#4CD964" : "#585858").Append('>') .Append(i) .Append("</color>"); if (i == 4) { stringBuilder.Append('\n'); } else if (i < 8) { stringBuilder.Append(' '); } } stringBuilder.Append("\n<color=").Append(AscentTitle.FinalDone ? "#4CD964" : "#585858").Append(">FINAL</color>"); return stringBuilder.ToString(); } } internal class AscentChoicePreview : MonoBehaviour { private TMP_Dropdown _pick; private List<NameStyle> _offered; internal void Bind(TMP_Dropdown pick, List<NameStyle> offered) { _pick = pick; _offered = offered; } private void LateUpdate() { if ((Object)(object)_pick == (Object)null || _offered == null || _offered.Count == 0) { return; } int cleared = AscentTitle.ClearedLocally(); bool finalDone = AscentTitle.FinalDone; if ((Object)(object)_pick.captionText != (Object)null) { int index = Mathf.Clamp(_pick.value, 0, _offered.Count - 1); AscentTitle.Paint(_pick.captionText, AscentTitle.Resolve(_offered[index], cleared, finalDone)); } int num = 0; Toggle[] componentsInChildren = ((Component)_pick).GetComponentsInChildren<Toggle>(true); foreach (Toggle val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeSelf && (!((Object)(object)_pick.template != (Object)null) || !((Component)val).transform.IsChildOf((Transform)(object)_pick.template))) { if (num >= _offered.Count) { break; } TMP_Text componentInChildren = ((Component)val).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { AscentTitle.Paint(componentInChildren, AscentTitle.Resolve(_offered[num], cleared, finalDone)); } num++; } } } } [HarmonyPatch(typeof(Character), "Awake")] internal static class AscentSyncAttachPatch { private static void Postfix(Character __instance) { if ((Object)(object)((Component)__instance).GetComponent<AscentSync>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<AscentSync>(); } } } public class AscentSync : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const string Key = "FA_T"; private static string _published; private Character _character; private string _seen; private int _cleared; private NameStyle _style; private bool _final; internal int Cleared { get { Refresh(); return _cleared; } } internal NameStyle Style { get { Refresh(); return _style; } } internal bool FinalDone { get { Refresh(); return _final; } } private void Awake() { _character = ((Component)this).GetComponent<Character>(); } private void Start() { if ((Object)(object)_character != (Object)null && _character.IsLocal) { ((MonoBehaviour)this).StartCoroutine(AnnounceRoutine()); } } internal static void BroadcastLocal() { Publish(); Courtesy(); } private static void Publish() { //IL_0052: 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_0063: Expected O, but got Unknown //IL_006a: Expected O, but got Unknown string text = string.Format(CultureInfo.InvariantCulture, "{0}|{1}|{2}", AscentTitle.ClearedLocally(), (int)AscentTitle.Chosen, AscentTitle.FinalDone ? 1 : 0); if (!(text == _published)) { _published = text; if (PhotonNetwork.LocalPlayer != null) { Player localPlayer = PhotonNetwork.LocalPlayer; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"FA_T", (object)text); localPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Detail("[FinalAscent] Namensfarbe im Raum hinterlegt: " + text + "."); } } } private static void Courtesy() { Character localCharacter = Character.localCharacter; if (!((Object)(object)localCharacter == (Object)null) && !((Object)(object)((MonoBehaviourPun)localCharacter).photonView == (Object)null) && ((MonoBehaviourPun)localCharacter).photonView.IsMine) { ((MonoBehaviourPun)localCharacter).photonView.RPC("RPC_ReceiveTitle", (RpcTarget)1, new object[3] { AscentTitle.ClearedLocally(), (int)AscentTitle.Chosen, AscentTitle.FinalDone }); } } private IEnumerator AnnounceRoutine() { float timeout = 5f; while (timeout > 0f && ((Object)(object)((MonoBehaviourPun)_character).photonView == (Object)null || !((MonoBehaviourPun)_character).photonView.IsMine)) { timeout -= Time.deltaTime; yield return null; } BroadcastLocal(); for (int i = 0; i < 10; i++) { yield return (object)new WaitForSeconds(1f); if ((Object)(object)_character == (Object)null) { break; } Publish(); } } private void Refresh() { if (!((Object)(object)_character == (Object)null) && !((Object)(object)((MonoBehaviourPun)_character).photonView == (Object)null)) { Player owner = ((MonoBehaviourPun)_character).photonView.Owner; if (owner != null && owner.CustomProperties != null && ((Dictionary<object, object>)(object)owner.CustomProperties).TryGetValue((object)"FA_T", out object value) && value is string text && !(text == _seen)) { _seen = text; Parse(text); } } } private void Parse(string line) { string[] array = line.Split('|'); if (array.Length >= 3 && int.TryParse(array[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && int.TryParse(array[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2) && int.TryParse(array[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result3)) { _cleared = result; _style = (NameStyle)result2; _final = result3 != 0; } } [PunRPC] private void RPC_ReceiveTitle(int cleared, int style, bool final) { if (_seen == null) { _cleared = cleared; _style = (NameStyle)style; _final = final; } } } internal enum NameStyle { Auto, Plain, Silver, Gold, Diamond, Rainbow } internal static class AscentTitle { private const string Tag = "[FinalAscent]"; private const string FileName = "TrueFinalAscent.Namensfarbe.txt"; private const string SealFileName = "TrueFinalAscent.Siegel.txt"; private const string OldFileName = "PiCHUPatches.Namensfarbe.txt"; internal const int TotalAscents = 8; private static string _sealText; private static bool _confirmed; private static bool _warned; private static float _lastTry = -99f; private static bool _frozen; private static string[] _who; private static readonly Color32 SilverColor = new Color32((byte)202, (byte)214, (byte)230, byte.MaxValue); private static readonly Color32 GoldColor = new Color32(byte.MaxValue, (byte)178, (byte)0, byte.MaxValue); private static readonly Color32 DiamondColor = new Color32((byte)150, (byte)232, byte.MaxValue, byte.MaxValue); private static string Path => FinalAscentStore.State("TrueFinalAscent.Namensfarbe.txt"); private static string SealPath => FinalAscentStore.State("TrueFinalAscent.Siegel.txt"); private static string ReadPath => FinalAscentStore.ReadPath("TrueFinalAscent.Namensfarbe.txt", "PiCHUPatches.Namensfarbe.txt"); private static string SealReadPath => FinalAscentStore.ReadPath("TrueFinalAscent.Siegel.txt"); internal static bool FinalDone { get { if (_confirmed) { return true; } if (string.IsNullOrEmpty(_sealText) || _sealText == "-") { return false; } if (_frozen && _lastTry > -99f) { return false; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup - _lastTry < 1f) { return false; } _lastTry = realtimeSinceStartup; if (Matches(_sealText)) { _confirmed = true; Plugin.Log.LogInfo((object)"[FinalAscent] Siegel bestaetigt - der Finale Aufstieg gilt als geschafft, der Regenbogen ist waehlbar."); return true; } if (_frozen && !_warned) { _warned = true; Plugin.Log.LogWarning((object)"[FinalAscent] Das Siegel in TrueFinalAscent.Siegel.txt passt zu keiner Kennung dieses Kontos - der Finale Aufstieg gilt als offen. Das passiert, wenn die Zeile von Hand geaendert oder von einem anderen Konto uebernommen wurde. Die Zeile bleibt trotzdem stehen; sie wird nie ueberschrieben."); } return false; } } internal static NameStyle Chosen { get; private set; } = NameStyle.Auto; internal static int ClearedLocally() { AchievementManager instance = Singleton<AchievementManager>.Instance; if ((Object)(object)instance == (Object)null) { return 0; } return Mathf.Clamp(instance.GetMaxAscent() - 1, 0, 8); } internal static bool Unlocked(NameStyle style, int cleared, bool final) { switch (style) { case NameStyle.Auto: case NameStyle.Plain: return true; case NameStyle.Silver: return cleared >= 1; case NameStyle.Gold: return cleared >= 4; case NameStyle.Diamond: return cleared >= 8; case NameStyle.Rainbow: return final; default: return false; } } internal static NameStyle Resolve(NameStyle wanted, int cleared, bool final) { if (wanted != NameStyle.Auto && Unlocked(wanted, cleared, final)) { return wanted; } if (final) { return NameStyle.Rainbow; } if (cleared >= 8) { return NameStyle.Diamond; } if (cleared >= 4) { return NameStyle.Gold; } if (cleared < 1) { return NameStyle.Plain; } return NameStyle.Silver; } internal static string TitleOf(NameStyle style) { return style switch { NameStyle.Plain => FinalAscentText.Get("name.plain"), NameStyle.Silver => FinalAscentText.Get("name.silver"), NameStyle.Gold => FinalAscentText.Get("name.gold"), NameStyle.Diamond => FinalAscentText.Get("name.diamond"), NameStyle.Rainbow => FinalAscentText.Get("name.rainbow"), _ => FinalAscentText.Get("name.auto"), }; } internal static void Choose(NameStyle style) { if (Chosen != style) { Chosen = style; Save(); AscentSync.BroadcastLocal(); Plugin.Log.LogInfo((object)("[FinalAscent] Namensfarbe gewaehlt: " + TitleOf(style) + ".")); } } internal static void MarkFinalDone() { if (!FinalDone) { _confirmed = true; Save(); AscentSync.BroadcastLocal(); Plugin.Log.LogInfo((object)"[FinalAscent] FINALER AUFSTIEG GESCHAFFT - der Regenbogen ist ab jetzt waehlbar, und er bleibt es ueber Spielstarts hinweg (TrueFinalAscent.Siegel.txt)."); } } internal static void Load() { bool flag = Read(SealReadPath, SealPath); if (Read(ReadPath, Path)) { flag = true; } Plugin.Log.LogInfo((object)("[FinalAscent] Namensfarbe uebernommen: " + TitleOf(Chosen) + ", Finaler Aufstieg " + (FinalDone ? "geschafft" : "offen") + ".")); if (flag) { Save(); } } private static bool Read(string from, string want) { string fileName = System.IO.Path.GetFileName(from); try { if (!File.Exists(from)) { return false; } string[] array = File.ReadAllLines(from, Encoding.UTF8); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); int num = text.IndexOf('='); if (text.Length == 0 || text[0] == '#' || num <= 0) { continue; } string text2 = text.Substring(0, num).Trim(); string text3 = text.Substring(num + 1).Trim(); switch (text2) { case "siegel": if (text3 != "-" && !string.IsNullOrEmpty(text3)) { _sealText = text3; } break; case "final": if (text3 == "1") { _confirmed = true; } break; case "farbe": { if (Enum.TryParse<NameStyle>(text3, ignoreCase: true, out var result)) { Chosen = result; } break; } } } return !string.Equals(from, want, StringComparison.OrdinalIgnoreCase); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] " + fileName + " nicht lesbar (" + ex.Message + ") - Vorgaben gelten.")); return false; } } internal static void Save() { try { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# Der geschaffte Finale Aufstieg. Wird geschrieben,"); stringBuilder.AppendLine("# sobald er lebend auf PEAK oder hoeher beendet wurde."); stringBuilder.AppendLine("#"); stringBuilder.AppendLine("# Die Zahlen darin sind an dieses Steam-Konto gebunden"); stringBuilder.AppendLine("# und lassen sich nicht sinnvoll von Hand setzen - wer es"); stringBuilder.AppendLine("# versucht, bekommt beim naechsten Start eine Warnung im"); stringBuilder.AppendLine("# Log und einen offenen Finalen Aufstieg."); stringBuilder.AppendLine("#"); stringBuilder.AppendLine("# Eigene Datei, damit das Zuruecksetzen der Namensfarbe"); stringBuilder.AppendLine("# nicht die Auszeichnung mitnimmt."); stringBuilder.AppendLine(); stringBuilder.AppendLine("siegel = " + SealLine()); File.WriteAllText(SealPath, stringBuilder.ToString(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: true)); StringBuilder stringBuilder2 = new StringBuilder(); stringBuilder2.AppendLine("# Die gewaehlte Namensfarbe. Wird geschrieben, sobald"); stringBuilder2.AppendLine("# im Pausenmenue eine ausgesucht wird."); stringBuilder2.AppendLine("#"); stringBuilder2.AppendLine("# farbe: Auto, Plain, Silver, Gold, Diamond, Rainbow"); stringBuilder2.AppendLine("# Auto nimmt immer die hoechste freigeschaltete."); stringBuilder2.AppendLine("#"); stringBuilder2.AppendLine("# Diese Datei liegt in AppData und NICHT in BepInEx/config:"); stringBuilder2.AppendLine("# ein geteilter r2modman-Profilcode ueberschreibt config,"); stringBuilder2.AppendLine("# und daran soll kein erkletterter Aufstieg zerbrechen."); stringBuilder2.AppendLine(); stringBuilder2.AppendLine($"farbe = {Chosen}"); File.WriteAllText(Path, stringBuilder2.ToString(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: true)); FinalAscentStore.Retire("TrueFinalAscent.Siegel.txt"); FinalAscentStore.Retire("TrueFinalAscent.Namensfarbe.txt", "PiCHUPatches.Namensfarbe.txt"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] TrueFinalAscent.Namensfarbe.txt nicht schreibbar: " + ex.Message)); } } private static string[] Who() { if (_who != null) { return _who; } string text = SteamId(); List<string> list = new List<string>(2); if (text != null) { list.Add("steam:" + text); } list.Add(Environment.MachineName + "|" + Environment.UserName); string[] array = list.ToArray(); if (text != null) { _who = array; _frozen = true; } return array; } private static IEnumerable<string> Identities() { return Who(); } private static string SteamId() { try { Type type = AccessTools.TypeByName("Steamworks.SteamUser"); MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "GetSteamID", (Type[])null, (Type[])null) : null); object obj = ((methodInfo != null) ? methodInfo.Invoke(null, null) : null); if (obj == null) { return null; } FieldInfo fieldInfo = AccessTools.Field(obj.GetType(), "m_SteamID"); string text = ((fieldInfo != null) ? Convert.ToString(fieldInfo.GetValue(obj)) : obj.ToString()); if (string.IsNullOrEmpty(text) || text.Length < 6) { return null; } string text2 = text; foreach (char c in text2) { if (c < '0' || c > '9') { return null; } } return (text == "0") ? null : text; } catch { return null; } } private static string Seal(string identity) { try { using HMACSHA256 hMACSHA = new HMACSHA256(Encoding.UTF8.GetBytes("PiCHUPatches/FinalAscent/Siegel/v1")); byte[] array = hMACSHA.ComputeHash(Encoding.UTF8.GetBytes("final|" + identity)); StringBuilder stringBuilder = new StringBuilder(array.Length * 2); byte[] array2 = array; foreach (byte b in array2) { stringBuilder.Append(b.ToString("x2")); } return stringBuilder.ToString(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Siegel nicht zu rechnen: " + ex.Message)); return "-"; } } private static string SealLine() { List<string> list = new List<string>(); if (!string.IsNullOrEmpty(_sealText) && _sealText != "-") { string[] array = _sealText.Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0 && !list.Contains(text)) { list.Add(text); } } } if (_confirmed) { string[] array = Who(); for (int i = 0; i < array.Length; i++) { string text2 = Seal(array[i]); if (text2 != "-" && !list.Contains(text2)) { list.Add(text2); } } } if (list.Count == 0) { return "-"; } _sealText = string.Join(",", list.ToArray()); return _sealText; } private static string Seals() { List<string> list = new List<string>(); foreach (string item in Identities()) { string text = Seal(item); if (text != "-" && !list.Contains(text)) { list.Add(text); } } if (list.Count != 0) { return string.Join(",", list.ToArray()); } return "-"; } private static bool Matches(string stored) { if (string.IsNullOrEmpty(stored) || stored == "-") { return false; } foreach (string item in Identities()) { string text = Seal(item); if (text == "-") { continue; } string[] array = stored.Split(','); for (int i = 0; i < array.Length; i++) { if (array[i].Trim() == text) { return true; } } } return false; } internal static void Paint(TMP_Text text, NameStyle style) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)text == (Object)null) { return; } ((Graphic)text).color = Color.white; text.ForceMeshUpdate(false, false); TMP_TextInfo textInfo = text.textInfo; int characterCount = textInfo.characterCount; if (characterCount == 0) { return; } for (int i = 0; i < characterCount; i++) { TMP_CharacterInfo val = textInfo.characterInfo[i]; if (val.isVisible) { Color32 val2 = ColorFor(style, i, characterCount); Color32[] colors = textInfo.meshInfo[val.materialReferenceIndex].colors32; int vertexIndex = val.vertexIndex; colors[vertexIndex] = val2; colors[vertexIndex + 1] = val2; colors[vertexIndex + 2] = val2; colors[vertexIndex + 3] = val2; } } for (int j = 0; j < textInfo.meshInfo.Length; j++) { textInfo.meshInfo[j].mesh.colors32 = textInfo.meshInfo[j].colors32; text.UpdateGeometry(textInfo.meshInfo[j].mesh, j); } } private static Color32 ColorFor(NameStyle style, int index, int count) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) float time = Time.time; switch (style) { case NameStyle.Silver: return Shimmer(SilverColor, index, time, 2f, 0.2f); case NameStyle.Gold: return Shimmer(GoldColor, index, time, 2.5f, 0.35f); case NameStyle.Diamond: { float num = Mathf.Max(count, 1); float num2 = time * 0.9f % 1.6f * num - num * 0.3f; float num3 = Mathf.Abs((float)index - num2); float num4 = Mathf.Exp((0f - num3) * num3 * 0.9f); float num6 = default(float); float num7 = default(float); float num5 = default(float); Color.RGBToHSV(Color32.op_Implicit(DiamondColor), ref num5, ref num6, ref num7); num5 = Mathf.Repeat(num5 + Mathf.Sin(time * 1.3f + (float)index * 0.25f) * 0.045f, 1f); return Color32.Lerp(Color32.op_Implicit(Color.HSVToRGB(num5, num6 * (1f - 0.75f * num4), num7)), Color32.op_Implicit(Color.white), num4 * 0.85f); } case NameStyle.Rainbow: return Color32.op_Implicit(Color.HSVToRGB(Mathf.Repeat(time * 0.35f + (float)index * 0.085f, 1f), 0.82f, 1f)); default: return Color32.op_Implicit(Color.white); } } private static Color32 Shimmer(Color32 baseColor, int index, float now, float speed, float intensity) { //IL_001e: 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_002d: Unknown result type (might be due to invalid IL or missing references) float num = 0.5f + 0.5f * Mathf.Sin(now * speed + (float)index * 0.4f); return Color32.Lerp(baseColor, Color32.op_Implicit(Color.white), num * intensity); } } [HarmonyPatch(typeof(Character), "RPCEndGame")] internal static class AscentFinalWinPatch { private static void Postfix() { try { if (!FinalAscent.Active || AscentTitle.FinalDone) { return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { return; } if ((Object)(object)localCharacter.data != (Object)null && localCharacter.data.dead) { Plugin.Log.LogInfo((object)"[FinalAscent] Finaler Aufstieg gewonnen - aber nicht von diesem Spieler: er war am Ziel tot. Kein Regenbogen."); } else if (Character.CheckWinCondition(localCharacter)) { if (Ascents.currentAscent < 0) { Plugin.Log.LogInfo((object)("[FinalAscent] Finaler Aufstieg geschafft - aber auf " + FinalAscentDifficulty.TitleOf(Ascents.currentAscent) + ". Der Regenbogen wird ab PEAK vergeben, nicht auf Tenderfoot.")); } else { AscentTitle.MarkFinalDone(); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Siegpruefung fuer den Regenbogen: " + ex.Message)); } } } [HarmonyPatch(typeof(CharacterAfflictions), "AddAffliction", new Type[] { typeof(Affliction), typeof(bool) })] internal static class EnergyDrinkComboPatch { internal static bool SuppressCombo; private static bool Prefix(CharacterAfflictions __instance, Affliction affliction, bool fromRPC) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 if (Plugin.EnergyComboOn != null && !Plugin.EnergyComboOn.Value) { return true; } if (SuppressCombo || fromRPC || affliction == null) { return true; } if ((int)affliction.GetAfflictionType() != 2) { return true; } if ((Object)(object)__instance.character == (Object)null || !__instance.character.IsLocal) { return true; } Affliction val = default(Affliction); if (!__instance.HasAfflictionType((AfflictionType)2, ref val)) { return true; } EnergyDrinkComboEffect.Trigger(__instance, affliction); return false; } } internal class EnergyDrinkComboEffect : MonoBehaviour { private const float ComboSeconds = 13f; private static EnergyDrinkComboEffect _instance; private void Awake() { _instance = this; } public static void Trigger(CharacterAfflictions afflictions, Affliction incomingEnergyDrink) { if ((Object)(object)_instance == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"EnergyDrinkComboEffect nicht bereit, Combo übersprungen."); } } else { ((MonoBehaviour)_instance).StartCoroutine(_instance.ComboRoutine(afflictions, incomingEnergyDrink)); } } private IEnumerator ComboRoutine(CharacterAfflictions afflictions, Affliction incomingEnergyDrink) { Affliction_FasterBoi val = (Affliction_FasterBoi)incomingEnergyDrink.Copy(); ((Affliction)val).totalTime = 13f; EnergyDrinkComboPatch.SuppressCombo = true; try { afflictions.AddAffliction((Affliction)(object)val, false); afflictions.AddAffliction((Affliction)new Affliction_InfiniteStamina(13f), false); } finally { EnergyDrinkComboPatch.SuppressCombo = false; } ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Energy-Combo: {13f:0}s Energy + Rainbow Stamina aktiviert."); } yield return (object)new WaitForSeconds(13f); for (int i = 0; i < 10; i++) { if ((Object)(object)afflictions == (Object)null || (Object)(object)afflictions.character == (Object)null) { yield break; } afflictions.AddStatus((STATUSTYPE)6, 0.1f, false, true, true, false); yield return (object)new WaitForSeconds(1f); } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)"Energy-Combo: Sleep-Aufbau abgeschlossen (100)."); } } } internal static class FinalAscent { internal const int AscentMarker = 1337; private const int MarkerSpan = 64; internal const string SceneName = "WilIsland"; internal static bool Active { get; set; } internal static int Seed { get; set; } internal static bool Marked(int ascent) { if (ascent >= 1329) { return ascent <= 1401; } return false; } internal static int GradeOf(int ascent) { return Mathf.Clamp(ascent - 1337, -1, 64); } } public class FinalAscentSeedSync : MonoBehaviour { [PunRPC] public void RPC_FinalAscentSetup(int seed, string variants) { FinalAscent.Seed = seed; FinalAscentSetup.RandomVariants = string.IsNullOrEmpty(variants); FinalAscentSetup.Deserialize(variants); Plugin.Log.LogInfo((object)($"[FinalAscent] Vom Host uebernommen: Seed {seed}, Varianten " + (FinalAscentSetup.RandomVariants ? "zufaellig." : variants))); } } [HarmonyPatch(typeof(AirportCheckInKiosk), "Awake")] internal static class FinalAscentSeedSyncAttachPatch { private static void Postfix(AirportCheckInKiosk __instance) { if ((Object)(object)((Component)__instance).GetComponent<FinalAscentSeedSync>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<FinalAscentSeedSync>(); } } } [HarmonyPatch(typeof(AirportCheckInKiosk), "LoadIslandMaster")] internal static class FinalAscentLoadIslandPatch { private static bool Prefix(AirportCheckInKiosk __instance, int ascent, byte[] serializedRunSettings) { if (ascent != 1337 || !PhotonNetwork.IsMasterClient || !FinalAscentSetupWindow.Confirmed) { return true; } FinalAscent.Seed = FinalAscentSetup.ChosenSeed; Plugin.Log.LogInfo((object)string.Format("[FinalAscent] Lade {0} fuer Final Ascent, Seed={1}.", "WilIsland", FinalAscent.Seed)); string text = (FinalAscentSetup.RandomVariants ? "" : FinalAscentSetup.Serialize()); ((MonoBehaviourPun)__instance).photonView.RPC("RPC_FinalAscentSetup", (RpcTarget)0, new object[2] { FinalAscent.Seed, text }); FinalAscentRoom.Publish(FinalAscent.Seed, text); FinalAscentDifficulty.Publish(FinalAscentDifficulty.Chosen); ((MonoBehaviourPun)__instance).photonView.RPC("BeginIslandLoadRPC", (RpcTarget)0, new object[3] { "WilIsland", 1337 + FinalAscentDifficulty.Chosen, serializedRunSettings }); return false; } } [HarmonyPatch(typeof(AirportCheckInKiosk), "BeginIslandLoadRPC")] internal static class FinalAscentBeginLoadPatch { private static void Prefix(string sceneName, ref int ascent) { FinalAscent.Active = FinalAscent.Marked(ascent); if (!FinalAscent.Active) { FinalAscentRoom.ClearRoom("ein normaler Lauf beginnt"); FinalAscentHurtWatch.Reset(); return; } ascent = FinalAscent.GradeOf(ascent); FinalAscentHurtWatch.Reset(); Plugin.Log.LogInfo((object)("[FinalAscent] Lauf als Final Ascent markiert, Schwierigkeit " + FinalAscentDifficulty.TitleOf(ascent) + " (Ascent " + ascent + ").")); } } internal static class FinalAscentAmbience { private const string Tag = "[FinalAscent]"; private const float Unreachable = 999999f; private static readonly FieldInfo PlayedTropicsField = AccessTools.Field(typeof(AmbienceAudio), "playedTropicsOrRoots"); private static readonly FieldInfo PlayedAlpineField = AccessTools.Field(typeof(AmbienceAudio), "playedAlpineOrMesa"); private static readonly FieldInfo PlayedCalderaField = AccessTools.Field(typeof(AmbienceAudio), "playedCalderaOrGloom"); private static readonly FieldInfo PlayedKilnField = AccessTools.Field(typeof(AmbienceAudio), "playedKiln"); private static float _tropicsOriginal; private static float _alpineOriginal; private static float _calderaOriginal; private static float _kilnOriginal; private static float _peakOriginal; private static bool _captured; private static float _tropics = 999999f; private static float _alpine = 999999f; private static float _caldera = 999999f; private static float _kiln = 999999f; private static float _peak = 999999f; private static bool _armed; internal static float TombCeiling { get; private set; } = 450f; internal static void Reset() { _captured = false; _armed = false; TombCeiling = 450f; } private static AmbienceAudio[] FindAll() { return Object.FindObjectsByType<AmbienceAudio>((FindObjectsInactive)1, (FindObjectsSortMode)0); } internal static void Apply() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) AmbienceAudio[] array = FindAll(); if (array.Length != 0) { Capture(array[0]); } ArmStart(); TombCeiling = 450f + Offset((BiomeType)6).y; int num = PushAll(); Plugin.Log.LogInfo((object)(string.Format("{0} Musik: Originale tropics={1:F0} alpine={2:F0} ", "[FinalAscent]", _tropicsOriginal, _alpineOriginal) + $"caldera={_calderaOriginal:F0} kilnY={_kilnOriginal:F0} peak={_peakOriginal:F0}; " + $"hoehere Etappen gesperrt, {num} Instanzen gesetzt. " + $"Gruft-Decke {TombCeiling:F0} statt 450 (Mesa-Versatz).")); } internal static void Adopt(AmbienceAudio ambience) { if (!((Object)(object)ambience == (Object)null)) { Capture(ambience); if (!_armed) { ArmStart(); } Push(ambience); Plugin.Log.LogInfo((object)(string.Format("{0} Musik uebernommen fuer '{1}': tropics={2:F0} ", "[FinalAscent]", ((Object)ambience).name, ambience.tropicsStingerZ) + $"alpine={ambience.alpineStingerZ:F0} caldera={ambience.calderaStingerZ:F0} " + $"kilnY={ambience.kilnStingerY:F0} peak={ambience.peaksTingerZ:F0}")); } } private static void Capture(AmbienceAudio source) { if (!_captured && !((Object)(object)source == (Object)null)) { _tropicsOriginal = source.tropicsStingerZ; _alpineOriginal = source.alpineStingerZ; _calderaOriginal = source.calderaStingerZ; _kilnOriginal = source.kilnStingerY; _peakOriginal = source.peaksTingerZ; _captured = true; } } private static void ArmStart() { _tropics = _tropicsOriginal; _alpine = 999999f; _caldera = 999999f; _kiln = 999999f; _peak = 999999f; _armed = true; } private static void Push(AmbienceAudio ambience) { if (!((Object)(object)ambience == (Object)null) && _armed) { ambience.tropicsStingerZ = _tropics; ambience.alpineStingerZ = _alpine; ambience.calderaStingerZ = _caldera; ambience.kilnStingerY = _kiln; ambience.peaksTingerZ = _peak; } } private static int PushAll() { AmbienceAudio[] array = FindAll(); AmbienceAudio[] array2 = array; for (int i = 0; i < array2.Length; i++) { Push(array2[i]); } return array.Length; } internal static void OnStageAdvanced(BiomeType from, BiomeType to) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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) FieldInfo fieldInfo; if ((int)to == 7) { _tropics = _tropicsOriginal + Offset((BiomeType)7).z; fieldInfo = PlayedTropicsField; } else if ((int)to == 6) { _alpine = _alpineOriginal + Offset((BiomeType)6).z; fieldInfo = PlayedAlpineField; } else if ((int)to == 8) { _caldera = _calderaOriginal + Offset((BiomeType)8).z; fieldInfo = PlayedCalderaField; } else { if ((int)to != 9) { return; } _kiln = _kilnOriginal + Offset((BiomeType)8).y; _peak = _peakOriginal + Offset((BiomeType)8).z; fieldInfo = PlayedKilnField; } AmbienceAudio[] array = FindAll(); foreach (AmbienceAudio val in array) { fieldInfo?.SetValue(val, false); Push(val); } Plugin.Detail(string.Format("{0} Musik fuer {1} scharf (Schwelle und Flag zurueckgesetzt).", "[FinalAscent]", to)); } internal static void ArmForRestore(IList<BiomeType> chain, int target) { //IL_0038: 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) if (_captured && chain != null && chain.Count != 0) { if (target < 0) { target = 0; } if (target >= chain.Count) { target = chain.Count - 1; } ArmStart(); for (int i = 1; i <= target; i++) { Advance(chain[i]); } AmbienceAudio[] array = FindAll(); foreach (AmbienceAudio obj in array) { MarkHeard(obj, chain, target); Push(obj); } Plugin.Log.LogInfo((object)(string.Format("{0} Musik auf die wiederhergestellte Etappe gestellt ({1}): ", "[FinalAscent]", chain[target]) + $"tropics={_tropics:F0} alpine={_alpine:F0} caldera={_caldera:F0} " + $"kilnY={_kiln:F0} peak={_peak:F0}. Alles darunter gilt als gehoert - " + "sonst spielten alle verpassten Stinger auf einmal.")); } } private static void Advance(BiomeType to) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_0040: 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_0072: Unknown result type (might be due to invalid IL or missing references) if ((int)to == 7) { _tropics = _tropicsOriginal + Offset((BiomeType)7).z; } else if ((int)to == 6) { _alpine = _alpineOriginal + Offset((BiomeType)6).z; } else if ((int)to == 8) { _caldera = _calderaOriginal + Offset((BiomeType)8).z; } else if ((int)to == 9) { _kiln = _kilnOriginal + Offset((BiomeType)8).y; _peak = _peakOriginal + Offset((BiomeType)8).z; } } private static void MarkHeard(AmbienceAudio one, IList<BiomeType> chain, int target) { Heard(one, PlayedTropicsField, chain, target, (BiomeType)7); Heard(one, PlayedAlpineField, chain, target, (BiomeType)6); Heard(one, PlayedCalderaField, chain, target, (BiomeType)8); Heard(one, PlayedKilnField, chain, target, (BiomeType)9); } private static void Heard(AmbienceAudio one, FieldInfo flag, IList<BiomeType> chain, int target, BiomeType triggeredBy) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (flag == null) { return; } int num = -1; for (int i = 0; i < chain.Count; i++) { if (chain[i] == triggeredBy) { num = i; break; } } flag.SetValue(one, num >= 0 && num < target); } internal static void OnSegmentEntered(Segment segment) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected I4, but got Unknown //IL_001b: 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_004b: 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) switch (segment - 2) { default: return; case 0: _alpine = _alpineOriginal + Offset((BiomeType)2).z; break; case 1: _caldera = _calderaOriginal + Offset((BiomeType)3).z; break; case 2: _kiln = _kilnOriginal + Offset((BiomeType)3).y; _peak = 999999f; break; } int num = PushAll(); Plugin.Detail(string.Format("{0} Musik fuer Segment {1} scharf ({2} Instanzen): ", "[FinalAscent]", segment, num) + $"alpine={_alpine:F0} caldera={_caldera:F0} kilnY={_kiln:F0} peak={_peak:F0}"); } private static Vector3 Offset(BiomeType biome) { //IL_0005: 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_000f: Unknown result type (might be due to invalid IL or missing references) if (!FinalAscentBuilder.Offsets.TryGetValue(biome, out var value)) { return Vector3.zero; } return value; } } [HarmonyPatch(typeof(AmbienceAudio), "Update")] internal static class FinalAscentTombCeiling { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> code) { List<CodeInstruction> list = new List<CodeInstruction>(code); int num = 0; foreach (CodeInstruction item in list) { if (item.opcode == OpCodes.Ldc_R4 && item.operand is float num2 && Mathf.Approximately(num2, 450f)) { num++; } } if (num != 1) { Plugin.Log.LogWarning((object)($"[FinalAscent] Gruft-Decke: {num} Stellen mit 450 statt genau einer - " + "es wird NICHTS getauscht, die Gruft bleibt wie in Vanilla.")); foreach (CodeInstruction item2 in list) { yield return item2; } yield break; } foreach (CodeInstruction item3 in list) { if (item3.opcode == OpCodes.Ldc_R4 && item3.operand is float num3 && Mathf.Approximately(num3, 450f)) { yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.PropertyGetter(typeof(FinalAscentAmbience), "TombCeiling")); } else { yield return item3; } } } } [HarmonyPatch(typeof(GameUtils), "InstantiateAndGrab")] internal static class FinalAscentGrabProbe { private static void Prefix(Item item, Character character) { string text = "unlesbar"; try { StackTrace stackTrace = new StackTrace(1, fNeedFileInfo: false); for (int i = 0; i < stackTrace.FrameCount && i < 5; i++) { MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod(); if (!(methodBase?.DeclaringType == null) && !(methodBase.DeclaringType.Namespace == "HarmonyLib")) { text = methodBase.DeclaringType.Name + "." + methodBase.Name; break; } } } catch { } Plugin.Log.LogWarning((object)("[FinalAscent] GEGENSTAND ERHALTEN (" + (PhotonNetwork.IsMasterClient ? "HOST" : "GAST") + "): '" + (((Object)(object)item != (Object)null) ? ((Object)((Component)item).gameObject).name : "NICHTS") + "' fuer " + (((Object)(object)character != (Object)null) ? ((Object)character).name : "?") + ", bestimmt von " + text + ".")); } } [HarmonyPatch(typeof(Spawner), "GetObjectsToSpawn")] internal static class FinalAscentAmuletProbe { private const string Tag = "[FinalAscent]"; private const int Limit = 400; private static int _said; internal static void Reset() { _said = 0; } private static void Postfix(Spawner __instance, int spawnCount, List<GameObject> __result) { //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Invalid comparison between Unknown and I4 //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return; } string text; try { text = FinalAscentDelivery.ScenePathOf(((Component)__instance).transform); } catch { text = ((Object)__instance).name; } if (_said >= 400) { if (_said == 400) { _said++; Plugin.Log.LogWarning((object)string.Format("{0} STATUEN-GRIFF: ab hier still ({1} Zeilen erreicht).", "[FinalAscent]", 400)); } return; } _said++; StringBuilder stringBuilder = new StringBuilder(); if (__result == null) { stringBuilder.Append("NICHTS (null)"); } else { foreach (GameObject item in __result) { if (stringBuilder.Length > 0) { stringBuilder.Append(", "); } stringBuilder.Append(((Object)(object)item == (Object)null) ? "LEER" : ((Object)item).name); } if (stringBuilder.Length == 0) { stringBuilder.Append("leere Liste"); } } Plugin.Log.LogWarning((object)("[FinalAscent] STATUEN-GRIFF (" + (PhotonNetwork.IsMasterClient ? "HOST" : "GAST") + "): '" + text + "'")); Plugin.Log.LogWarning((object)(string.Format("{0} Betriebsart {1}, Anzahl {2}, ", "[FinalAscent]", __instance.spawnMode, spawnCount) + $"Topf {__instance.spawnPool}, Rueckfall " + "'" + (((Object)(object)__instance.fallbackSpawn != (Object)null) ? ((Object)__instance.fallbackSpawn).name : "keiner") + "', Einzelstueck '" + (((Object)(object)__instance.spawnedObjectPrefab != (Object)null) ? ((Object)__instance.spawnedObjectPrefab).name : "keins") + "'.")); Plugin.Log.LogWarning((object)string.Format("{0} HERAUS KAM: {1}", "[FinalAscent]", stringBuilder)); if ((int)__instance.spawnMode != 2 || __instance.heightBasedSpawnPools == null) { return; } StringBuilder stringBuilder2 = new StringBuilder(); foreach (HeightBasedSpawnListEntry heightBasedSpawnPool in __instance.heightBasedSpawnPools) { if (heightBasedSpawnPool != null) { if (stringBuilder2.Length > 0) { stringBuilder2.Append(" | "); } stringBuilder2.Append(heightBasedSpawnPool.spawnPool).Append(" ab z=").Append(heightBasedSpawnPool.minimumZ.ToString("F0")) .Append(" y=") .Append(heightBasedSpawnPool.minimumHeight.ToString("F0")); if (heightBasedSpawnPool.hasBiomeRequirement) { stringBuilder2.Append(" nur ").Append(heightBasedSpawnPool.biomeRequirement); } } } Plugin.Log.LogWarning((object)("[FinalAscent] Hoehen-Tabelle (Spawner steht auf z=" + $"{((Component)__instance).transform.position.z:F0}): {stringBuilder2}")); } } internal static class FinalAscentApocalypse { private const string Tag = "[FinalAscent]"; internal const string RoomKey = "APO"; private static bool _seen; private static bool _everSeen; internal const bool Shipped = false; internal static bool Wanted { get; private set; } internal static bool Active => false; internal static bool FromRoom(out bool value) { value = false; if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null || ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties == null) { return false; } if (!((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"APO", out object value2) || !(value2 is bool)) { return false; } value = (bool)value2; return true; } internal static void Restore(bool on) { Wanted = on; } internal static void Choose(bool on) { if (Wanted != on || !_everSeen || _seen != on) { Wanted = on; FinalAscentSetupMemory.Save(); Publish(); Plugin.Log.LogInfo((object)("[FinalAscent] Apokalypse-Modus " + (on ? "EIN" : "AUS") + " - gilt fuer jeden Lauf, der aus diesem Raum startet.")); } } private static void Publish() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0035: Expected O, but got Unknown if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null) { Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"APO", (object)Wanted); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } internal static void Claim() { if (!FromRoom(out var _)) { Publish(); } } internal static bool Adopt() { if (!FromRoom(out var value)) { return false; } if (_everSeen && _seen == value) { return false; } _everSeen = true; _seen = value; if (Wanted == value) { return false; } Wanted = value; Plugin.Log.LogInfo((object)("[FinalAscent] Apokalypse-Modus aus dem Raum uebernommen: " + (value ? "EIN" : "AUS") + ".")); return true; } } [HarmonyPatch(typeof(AscentUI), "Start")] internal static class FinalAscentApocalypseLabelPatch { private static void Postfix(AscentUI __instance) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.text == (Object)null) && FinalAscentApocalypse.Active) { ((Graphic)__instance.text).color = FinalAscentUiKit.Orange; Plugin.Detail("[FinalAscent] Moduslabel orange - der Apokalypse-Modus gilt" + (string.IsNullOrEmpty(((TMP_Text)__instance.text).text) ? ", aber Vanilla laesst das Label bei Ascent 0 leer." : ".")); } } } [HarmonyPatch(typeof(AirportCheckInKiosk), "BeginIslandLoadRPC")] internal static class FinalAscentApocalypseStartPatch { private static void Postfix() { Plugin.Log.LogInfo((object)("[FinalAscent] Apokalypse-Modus: " + (FinalAscentApocalypse.Active ? "EIN" : "AUS") + " (aus dem Raum: " + (RoomHas() ? "ja" : "nein, eigene Erinnerung") + ").")); } private static bool RoomHas() { bool value; return FinalAscentApocalypse.FromRoom(out value); } } [HarmonyPatch(typeof(BoardingPass), "UpdateAscent")] internal static class FinalAscentApocalypsePassPatch { [HarmonyPriority(0)] private static void Postfix(BoardingPass __instance) { } } internal sealed class FinalAscentApocalypsePanel : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const string NodeName = "FA_Apocalypse"; private const float DropLines = 2.8f; private const float RowLines = 2.3f; private static FinalAscentApocalypsePanel _instance; private static Canvas _canvas; private BoardingPass _pass; private RectTransform _rect; private RectTransform _card; private CanvasGroup _group; private Toggle _toggle; private TextMeshProUGUI _label; private float _size = 24f; private float _lastLook; private bool _told; private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4]; internal static void Ensure(BoardingPass pass) { if (!((Object)(object)pass == (Object)null) && !((Object)(object)pass.ascentDesc == (Object)null)) { FinalAscentApocalypse.Claim(); if ((Object)(object)_instance == (Object)null || (Object)(object)_instance._toggle == (Object)null) { Build(pass); } if ((Object)(object)_instance != (Object)null) { _instance._pass = pass; _instance._card = CardOf(pass); FinalAscentUiKit.PutOnTop(_canvas); _instance.Show(); _instance.Follow(); } } } private static void Build(BoardingPass pass) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0071: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00e5: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) FinalAscentUiKit.Sample(pass); RectTransform val = CardOf(pass); Retire(((Component)pass).transform, ((Transform)pass.ascentDesc.rectTransform).parent); float num = ((pass.ascentDesc.fontSize > 1f) ? pass.ascentDesc.fontSize : 24f); float num2 = num * 2.3f; GameObject val2 = new GameObject("FA_ApocalypseCanvas"); Object.DontDestroyOnLoad((Object)val2); Canvas val3 = val2.AddComponent<Canvas>(); val3.renderMode = (RenderMode)0; val2.AddComponent<GraphicRaycaster>(); _canvas = val3; FinalAscentUiKit.PutOnTop(val3); Transform transform = val2.transform; GameObject val4 = new GameObject("FA_Apocalypse", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent(transform, false); RectTransform component = val4.GetComponent<RectTransform>(); Vector2 val5 = default(Vector2); ((Vector2)(ref val5))..ctor(0.5f, 0.5f); component.anchorMax = val5; component.anchorMin = val5; component.pivot = new Vector2(0.5f, 1f); Rect rect = val.rect; component.sizeDelta = new Vector2(((Rect)(ref rect)).width, num2); _instance = val4.AddComponent<FinalAscentApocalypsePanel>(); _instance._rect = component; _instance._card = val; _instance._size = num; _instance._group = val4.AddComponent<CanvasGroup>(); _instance._group.alpha = 0f; FinalAscentApocalypsePanel instance = _instance; Transform transform2 = val4.transform; rect = val.rect; instance._toggle = FinalAscentUiKit.Check(transform2, 0f, 0f, ((Rect)(ref rect)).width, num2, Caption(), num); _instance._label = ((Component)_instance._toggle).GetComponentInChildren<TextMeshProUGUI>(true); ((UnityEvent<bool>)(object)_instance._toggle.onValueChanged).AddListener((UnityAction<bool>)delegate(bool on) { FinalAscentApocalypse.Choose(on); _instance.Show(); }); Plugin.Detail("[FinalAscent] Apokalypse-Haken gebaut an '" + ((Object)transform).name + "', gemessen an " + $"'{((Object)val).name}'. Schrift {num:0.#}, Zeile {component.sizeDelta}. " + "Beschnitten von: " + Clipper(val4.transform) + "."); } private void Reposition() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0085: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00cd: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_rect == (Object)null) && !((Object)(object)_card == (Object)null)) { Transform parent = ((Transform)_rect).parent; if (!((Object)(object)parent == (Object)null)) { _card.GetWorldCorners(_corners); Vector3 val = _corners[0]; Vector3 val2 = _corners[3]; float num = Vector3.Distance(parent.InverseTransformPoint(val), parent.InverseTransformPoint(val2)); _rect.sizeDelta = new Vector2(num, _size * 2.3f); ((Transform)_rect).position = (val + val2) * 0.5f; RectTransform rect = _rect; rect.anchoredPosition -= new Vector2(0f, _size * 2.8f); } } } private void Follow() { if (!((Object)(object)_group == (Object)null)) { bool num = (Object)(object)_pass != (Object)null && ((Component)_pass).gameObject.activeInHierarchy; float num2 = 0f; if (num) { num2 = (((Object)(object)_pass.canvasGroup != (Object)null) ? _pass.canvasGroup.alpha : 1f); } _group.alpha = num2; _group.blocksRaycasts = num2 > 0.5f; _group.interactable = num2 > 0.5f; if (num2 > 0f) { Reposition(); Report(); } } } private void Report() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (!_told && !((Object)(object)_rect == (Object)null)) { _told = true; ManualLogSource log = Plugin.Log; string text = string.Format("{0} Apokalypse-Haken sichtbar: Mitte {1}, Groesse ", "[FinalAscent]", ((Transform)_rect).position); Rect rect = _rect.rect; log.LogInfo((object)(text + $"{((Rect)(ref rect)).size}, Bildschirm {Screen.width}x{Screen.height}, " + $"Deckkraft {_group.alpha:0.00}, Sortierung " + string.Format("{0}, Text '{1}'.", ((Object)(object)_canvas != (Object)null) ? _canvas.sortingOrder : (-1), ((Object)(object)_label != (Object)null) ? ((TMP_Text)_label).text.Replace("\n", " / ") : "-"))); } } private void Show() { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_toggle == (Object)null)) { _toggle.SetIsOnWithoutNotify(FinalAscentApocalypse.Wanted); Transform val = ((Component)_toggle).transform.Find("Box"); Transform val2 = (((Object)(object)val != (Object)null) ? val.Find("Mark") : null); if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(_toggle.isOn); } if ((Object)(object)_label != (Object)null) { ((TMP_Text)_label).text = Caption(); ((Graphic)_label).color = (FinalAscentApocalypse.Wanted ? FinalAscentUiKit.Orange : FinalAscentUiKit.Chalk); } } } private static string Caption() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) string text = ColorUtility.ToHtmlStringRGB(FinalAscentUiKit.ChalkDim); return FinalAscentText.Get("apo.label") + "\n<size=68%><color=#" + text + ">" + FinalAscentText.Get("apo.note") + "</color></size>"; } private void Update() { Follow(); if (!(Time.unscaledTime - _lastLook < 1f)) { _lastLook = Time.unscaledTime; if (FinalAscentApocalypse.Adopt()) { Show(); } } } private static RectTransform CardOf(BoardingPass pass) { Transform obj = ((Component)pass).transform.Find("Panel"); RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null); if (!((Object)(object)val != (Object)null)) { return pass.ascentDesc.rectTransform; } return val; } private static void Retire(params Transform[] places) { foreach (Transform val in places) { Transform val2 = (((Object)(object)val != (Object)null) ? val.Find("FA_Apocalypse") : null); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)((Component)val2).gameObject); } } } private static string Clipper(Transform from) { Transform parent = from.parent; while ((Object)(object)parent != (Object)null) { if ((Object)(object)((Component)parent).GetComponent<RectMask2D>() != (Object)null) { return "RectMask2D an '" + ((Object)parent).name + "'"; } if ((Object)(object)((Component)parent).GetComponent<Mask>() != (Object)null) { return "Mask an '" + ((Object)parent).name + "'"; } parent = parent.parent; } return "niemandem"; } } internal static class FinalAscentBaked { private const string Tag = "[FinalAscent]"; private const string Magic = "PiCHUInsel 1|"; internal const string FileName = "TrueFinalAscent.Insel.dat"; internal static void Save(byte[] packed, int objects) { if (packed == null || packed.Length == 0) { return; } try { string s = "PiCHUInsel 1|" + FinalAscent.Seed.ToString(CultureInfo.InvariantCulture) + "|" + objects.ToString(CultureInfo.InvariantCulture) + "|" + FinalAscentSetup.SerializeChosen() + "|" + FinalAscentBuilder.SummitNote() + "\n"; byte[] bytes = Encoding.UTF8.GetBytes(s); byte[] array = new byte[bytes.Length + packed.Length]; Buffer.BlockCopy(bytes, 0, array, 0, bytes.Length); Buffer.BlockCopy(packed, 0, array, bytes.Length, packed.Length); if (Plugin.Diagnosing) { File.WriteAllBytes(FinalAscentStore.Note("TrueFinalAscent.Insel.dat"), array); Plugin.Log.LogInfo((object)(string.Format("{0} GEBACKENE INSEL abgelegt: {1} KB ", "[FinalAscent]", array.Length / 1024) + string.Format("({0} Objekte, Seed {1}) als {2}. ", objects, FinalAscent.Seed, "TrueFinalAscent.Insel.dat") + "Zum Vergleich: PEAKs eigene Karten wiegen 154 bis 177 MB je Stueck.")); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Gebackene Insel liess sich nicht ablegen: " + ex.Message)); } } internal static string Find() { try { string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "", "TrueFinalAscent.Insel.dat"); if (File.Exists(text)) { return text; } string text2 = FinalAscentStore.Note("TrueFinalAscent.Insel.dat"); if (File.Exists(text2)) { return text2; } string text3 = Path.Combine(Paths.ConfigPath, "TrueFinalAscent.Insel.dat"); if (File.Exists(text3)) { return text3; } } catch (Exception ex) { Plugin.Detail("[FinalAscent] Suche nach gebackener Insel misslungen: " + ex.Message); } return null; } internal static bool TryLoad(out byte[] packed, out string choices, out string summit) { packed = null; choices = null; summit = null; string text = Find(); if (text == null) { return false; } try { byte[] array = File.ReadAllBytes(text); int num = Array.IndexOf(array, (byte)10); if (num <= 0) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + text + "' hat keine lesbare Kopfzeile - sie wird uebergangen.")); return false; } string text2 = Encoding.UTF8.GetString(array, 0, num); if (!text2.StartsWith("PiCHUInsel 1|", StringComparison.Ordinal)) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + text + "' ist keine gebackene Insel dieser Fassung - sie wird uebergangen.")); return false; } string[] array2 = text2.Substring("PiCHUInsel 1|".Length).Split('|'); if (array2.Length < 4) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + text + "' hat eine unvollstaendige Kopfzeile " + $"({array2.Length} Felder) - sie wird uebergangen.")); return false; } choices = array2[2]; summit = array2[3]; packed = new byte[array.Length - num - 1]; Buffer.BlockCopy(array, num + 1, packed, 0, packed.Length); Plugin.Log.LogInfo((object)(string.Format("{0} GEBACKENE INSEL gefunden: {1} ({2} KB, ", "[FinalAscent]", text, array.Length / 1024) + array2[1] + " Objekte, gebacken mit Seed " + array2[0] + "). Auf diesem Rechner wird weder generiert noch gewartet - es wird nur ausgepackt.")); return true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + text + "' liess sich nicht lesen: " + ex.Message)); return false; } } internal static void Announce() { string text = Find(); if (text == null) { Plugin.Log.LogInfo((object)"[FinalAscent] Keine gebackene Insel vorhanden - der Berg entsteht wie bisher: der Host generiert, die anderen bekommen sein Paket geschickt. Der Host legt nach dem Packen eine Datei 'TrueFinalAscent.Insel.dat' ab; wer sie auf ALLE Rechner kopiert, laedt danach ueberall dieselbe Insel."); } else { Plugin.Log.LogInfo((object)("[FinalAscent] Gebackene Insel liegt bereit: " + text)); } } } internal static class FinalAscentBanner { private const string Tag = "[FinalAscent]"; private const float Seconds = 4f; private static AudioClip _squeak; private static bool _looked; internal static void Show(string text, Color colour, AudioClip stinger) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) GUIManager instance = GUIManager.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.fogRises == (Object)null) { Plugin.Log.LogWarning((object)"[FinalAscent] Keine Einblendung moeglich - GUIManager oder 'fogRises' fehlt."); return; } GameObject val = Object.Instantiate<GameObject>(instance.fogRises, instance.fogRises.transform.parent, false); ((Object)val).name = "FA_Banner"; val.SetActive(true); int num = 0; TextMeshProUGUI[] componentsInChildren = val.GetComponentsInChildren<TextMeshProUGUI>(true); foreach (TextMeshProUGUI obj in componentsInChildren) { ((TMP_Text)obj).text = text; ((Graphic)obj).color = colour; num++; } Text[] componentsInChildren2 = val.GetComponentsInChildren<Text>(true); foreach (Text obj2 in componentsInChildren2) { obj2.text = text; ((Graphic)obj2).color = colour; num++; } if ((Object)(object)stinger != (Object)null) { instance.ForcePlayStinger(stinger); } Object.Destroy((Object)(object)val, 4f); Plugin.Log.LogInfo((object)(string.Format("{0} Einblendung '{1}' - {2} Schriftzug(e) umgeschrieben, ", "[FinalAscent]", text, num) + "Klang " + (((Object)(object)stinger != (Object)null) ? ((Object)stinger).name : "keiner") + ".")); } internal static AudioClip Squeak() { if (_looked) { return _squeak; } _looked = true; SFX_Instance[] array = Resources.FindObjectsOfTypeAll<SFX_Instance>(); string text = ""; SFX_Instance val = null; SFX_Instance[] array2 = array; foreach (SFX_Instance val2 in array2) { if ((Object)(object)val2 == (Object)null || val2.clips == null || val2.clips.Length == 0) { continue; } string text2 = ((Object)val2).name.ToLowerInvariant(); if (text2.Contains("bing") || text2.Contains("bong") || text2.Contains("squeak") || text2.Contains("squeeze") || text2.Contains("squish") || text2.Contains("honk")) { text = text + ((text.Length > 0) ? ", " : "") + ((Object)val2).name; if ((Object)(object)val == (Object)null || text2.Contains("bing")) { val = val2; } } } _squeak = (((Object)(object)val != (Object)null) ? val.GetClip() : null); Plugin.Log.LogInfo((object)(string.Format("{0} Quietscher gesucht in {1} Klaengen. Kandidaten: ", "[FinalAscent]", array.Length) + ((text.Length > 0) ? text : "keine") + ". Genommen: " + (((Object)(object)val != (Object)null) ? ((Object)val).name : "keiner") + ".")); return _squeak; } } internal static class FinalAscentBiomeAudit { private const string Tag = "[FinalAscent]"; private const string KeyPrefix = "FAbio"; private static readonly HashSet<int> _done = new HashSet<int>(); private static bool _running; internal static void Begin() { if (!_running && !((Object)(object)Plugin.Instance == (Object)null)) { _running = true; _done.Clear(); ((MonoBehaviour)Plugin.Instance).StartCoroutine(Watch()); } } private static IEnumerator Watch() { WaitForSecondsRealtime beat = new WaitForSecondsRealtime(1f); while (FinalAscent.Active) { yield return beat; if (FinalAscentBuilder.Building || !FinalAscentBuilder.Ready) { continue; } FinalAscentStage here = FinalAscentSegments.CurrentStage; if (here != null) { int key = FinalAscentSegments.KeyOf(here); if (_done.Add(key)) { yield return Settled(here); yield return (object)new WaitForSecondsRealtime(5f); yield return Audit(here, key); } } } _running = false; } private static IEnumerator Settled(FinalAscentStage stage) { WaitForSecondsRealtime beat = new WaitForSecondsRealtime(1f); int lastSeen = -1; int steady = 0; float waited = 0f; while (waited < 60f) { bool num = (Object)(object)stage.Root != (Object)null && stage.Root.activeInHierarchy; int num2 = (num ? VisibleIn(stage.Presence) : 0); if (num && num2 > 0 && num2 == lastSeen) { steady++; if (steady >= 2) { yield break; } } else { steady = 0; } lastSeen = num2; waited += 1f; yield return beat; } Plugin.Log.LogWarning((object)("[FinalAscent] '" + stage.Title + "' steht nach einer Minute immer noch nicht vollstaendig - gemessen wird trotzdem, die Zahlen sagen den Rest.")); } private static int VisibleIn(BiomeType type) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) int num = 0; Biome[] array = Object.FindObjectsByType<Biome>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Biome val in array) { if ((Object)(object)val == (Object)null || val.biomeType != type) { continue; } Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null && val2.enabled && ((Component)val2).gameObject.activeInHierarchy) { num++; } } } return num; } private static IEnumerator Audit(FinalAscentStage stage, int key) { Dictionary<Transform, Vector3> still = Snapshot(stage.Presence); yield return (object)new WaitForSecondsRealtime(1f); string text = PrintOf(stage.Presence, still); Plugin.Log.LogInfo((object)(string.Format("{0} ETAPPE STEHT - '{1}' ({2}) gemessen: {3} ", "[FinalAscent]", stage.Title, stage.Presence, text) + "(Props/Pruefsumme/sichtbar/fest/bewegliche-ausgenommen)")); StringBuilder stringBuilder = new StringBuilder(); Transform[] array = Object.FindObjectsByType<Transform>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Transform val in array) { if (!((Object)(object)val == (Object)null) && ((Object)val).name.EndsWith("_Campfire") && !((Object)(object)val.parent == (Object)null)) { stringBuilder.Append((stringBuilder.Length > 0) ? ", " : "").Append(((Object)val).name).Append(' ') .Append(((Component)val).gameObject.activeInHierarchy ? "AN" : (((Component)val).gameObject.activeSelf ? "elternteil-aus" : "AUS")); } } if (stringBuilder.Length > 0) { Plugin.Log.LogInfo((object)string.Format("{0} Lagerfeuer-Plaetze: {1}", "[FinalAscent]", stringBuilder)); } if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null) { string text2 = "FAbio" + key; if (PhotonNetwork.IsMasterClient) { Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val2 = new Hashtable(); ((Dictionary<object, object>)val2).Add((object)text2, (object)text); currentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); } else if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(CompareLater(stage, text2, text)); } } } private static IEnumerator CompareLater(FinalAscentStage stage, string prop, string print) { WaitForSecondsRealtime beat = new WaitForSecondsRealtime(2f); float waited = 0f; while (waited < 120f) { Hashtable val = ((PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null) ? ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties : null); if (val != null && ((Dictionary<object, object>)(object)val).TryGetValue((object)prop, out object value) && value is string text) { if (text == print) { Plugin.Log.LogInfo((object)("[FinalAscent] '" + stage.Title + "' DECKUNGSGLEICH mit dem Host - dieselbe Landschaft, im selben Spielmoment gemessen.")); yield break; } Plugin.Log.LogError((object)("[FinalAscent] '" + stage.Title + "' WEICHT AB: Host " + text + ", hier " + print)); yield break; } waited += 2f; yield return beat; } Plugin.Log.LogInfo((object)("[FinalAscent] Der Host hat fuer '" + stage.Title + "' auch nach zwei Minuten nichts hinterlegt - er war dort wohl wirklich noch nicht.")); } private static string PrintOf(BiomeType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return PrintOf(type, null); } private static string PrintOf(BiomeType type, Dictionary<Transform, Vector3> still) { //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) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) int num = 0; long num2 = 0L; int num3 = 0; int num4 = 0; int num5 = 0; Biome[] array = Object.FindObjectsByType<Biome>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Biome val in array) { if ((Object)(object)val == (Object)null || val.biomeType != type) { continue; } PropSpawner[] componentsInChildren = ((Component)val).GetComponentsInChildren<PropSpawner>(true); foreach (PropSpawner val2 in componentsInChildren) { for (int k = 0; k < ((Component)val2).transform.childCount; k++) { Transform child = ((Component)val2).transform.GetChild(k); if (((Object)child).name.StartsWith("MushroomZombieSpawner")) { continue; } num++; Vector3 val3 = ((Component)val).transform.InverseTransformPoint(child.position); if (still != null) { if (still.TryGetValue(child, out var value)) { Vector3 val4 = value - val3; if (!(((Vector3)(ref val4)).sqrMagnitude > 0.0001f)) { goto IL_00ce; } } num5++; continue; } goto IL_00ce; IL_00ce: long num6 = 1469598103934665603L; num6 = (num6 ^ Mathf.RoundToInt(val3.x * 100f)) * 1099511628211L; num6 = (num6 ^ Mathf.RoundToInt(val3.y * 100f)) * 1099511628211L; num6 = (num6 ^ Mathf.RoundToInt(val3.z * 100f)) * 1099511628211L; num2 += num6; } } Renderer[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Renderer>(true); foreach (Renderer val5 in componentsInChildren2) { if ((Object)(object)val5 != (Object)null && val5.enabled && ((Component)val5).gameObject.activeInHierarchy) { num3++; } } Collider[] componentsInChildren3 = ((Component)val).GetComponentsInChildren<Collider>(true); foreach (Collider val6 in componentsInChildren3) { if ((Object)(object)val6 != (Object)null && val6.enabled && ((Component)val6).gameObject.activeInHierarchy) { num4++; } } } if (still != null) { return $"{num}/{num2 & 0xFFFFFF:X6}/{num3}s/{num4}k/{num5}b"; } return $"{num}/{num2 & 0xFFFFFF:X6}/{num3}s/{num4}k"; } private static Dictionary<Transform, Vector3> Snapshot(BiomeType type) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Dictionary<Transform, Vector3> dictionary = new Dictionary<Transform, Vector3>(); Biome[] array = Object.FindObjectsByType<Biome>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Biome val in array) { if ((Object)(object)val == (Object)null || val.biomeType != type) { continue; } PropSpawner[] componentsInChildren = ((Component)val).GetComponentsInChildren<PropSpawner>(true); foreach (PropSpawner val2 in componentsInChildren) { for (int k = 0; k < ((Component)val2).transform.childCount; k++) { Transform child = ((Component)val2).transform.GetChild(k); dictionary[child] = ((Component)val).transform.InverseTransformPoint(child.position); } } } return dictionary; } } [HarmonyPatch(typeof(DayNightManager), "Update")] internal static class FinalAscentDayHold { private const string Tag = "[FinalAscent]"; private static float _held; private static bool _holding; private static bool _announced; private static bool ShouldHold() { if (FinalAscent.Active && !FinalAscentRoom.JoinedLate) { return FinalAscentBuilder.Building; } return false; } private static void Prefix(DayNightManager __instance) { _holding = ShouldHold(); if (_holding && !((Object)(object)__instance == (Object)null)) { _held = __instance.timeOfDay; if (!_announced) { _announced = true; Plugin.Log.LogInfo((object)("[FinalAscent] Die Tageszeit steht still, solange der Berg entsteht " + $"(bei {_held:F1} Uhr). Nachzuegler halten sie nicht an.")); } } } private static void Postfix(DayNightManager __instance) { if (!((Object)(object)__instance == (Object)null)) { if (_holding) { __instance.timeOfDay = _held; } else if (_announced) { _announced = false; Plugin.Log.LogInfo((object)("[FinalAscent] Der Berg steht - die Tageszeit laeuft wieder " + $"(bei {__instance.timeOfDay:F1} Uhr).")); } } } } internal sealed class FinalAscentBloodMoon : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const float Nearest = 12f; private const float Furthest = 25f; private const int Fewest = 2; private const int Most = 3; private const int Tries = 8; private bool _called; private readonly List<int> _brood = new List<int>(); private static readonly HashSet<string> Refused = new HashSet<string>(); private static FinalAscentBloodMoon _instance; private static bool _enlisted; private const float Angry = 22f; private const float Faster = 1.35f; internal static void Run(bool on) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if (on && (Object)(object)_instance == (Object)null) { GameObject val = new GameObject("FA_BloodMoon"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent<FinalAscentBloodMoon>(); } if (!((Object)(object)_instance == (Object)null)) { if (on) { _instance._called = false; Enlist(); } else { _instance.Dismiss(); } } } private void Update() { if (FinalAscentBloodMoonSky.Wanted || !(FinalAscentBloodMoonSky.Lift <= 0f)) { Character localCharacter = Character.localCharacter; DayNightManager instance = DayNightManager.instance; if (!((Object)(object)localCharacter == (Object)null) && !((Object)(object)instance == (Object)null) && !((Object)(object)instance.moon == (Object)null) && !(instance.moon.intensity < 1f) && !_called && PhotonNetwork.IsMasterClient) { _called = true; Call(); } } } private static void Enlist() { if (_enlisted) { return; } object prefabPool = PhotonNetwork.PrefabPool; if (prefabPool == null) { Plugin.Log.LogInfo((object)"[FinalAscent] Blutmond: PUNs Vorlagenverwaltung steht noch nicht - wird beim naechsten Anlauf erneut versucht."); return; } List<GameObject> list = Pool(); if (list.Count == 0) { Plugin.Log.LogInfo((object)"[FinalAscent] Blutmond: noch keine Vorlagen zum Anmelden gefunden."); return; } MethodInfo method = prefabPool.GetType().GetMethod("TryRegisterPrefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(string), typeof(GameObject) }, null); Dictionary<string, GameObject> dictionary = null; if (method == null) { FieldInfo[] fields = prefabPool.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < fields.Length; i++) { dictionary = fields[i].GetValue(prefabPool) as Dictionary<string, GameObject>; if (dictionary != null) { break; } } } if (method == null && dictionary == null) { Plugin.Log.LogWarning((object)("[FinalAscent] Blutmond: an '" + prefabPool.GetType().Name + "' fuehrt weder eine Anmeldung noch ein Verzeichnis vorbei - es bleibt beim Zombie.")); return; } string text = ""; foreach (GameObject item in list) { if (method != null) { method.Invoke(prefabPool, new object[2] { ((Object)item).name, item }); } else { dictionary[((Object)item).name] = item; } text = text + ((text.Length > 0) ? ", " : "") + ((Object)item).name; } text += ((method != null) ? " (angemeldet)" : " (eingetragen)"); _enlisted = true; Refused.Clear(); Plugin.Log.LogInfo((object)("[FinalAscent] Blutmond: Vorlagen bei PUN angemeldet - " + text + ".")); } private void Call() { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) Enlist(); List<GameObject> list = Pool(); if (list.Count == 0) { Plugin.Log.LogWarning((object)"[FinalAscent] Blutmond: keine Kreaturenvorlagen gefunden - es bleibt bei rotem Licht."); return; } List<Character> list2 = Living(); if (list2.Count == 0) { Plugin.Log.LogWarning((object)"[FinalAscent] Blutmond: niemand auf den Beinen - es bleibt bei rotem Licht."); return; } int num = 0; int num2 = 0; for (int i = 0; i < list2.Count; i++) { Character val = list2[i]; if ((Object)(object)val == (Object)null) { continue; } int num3 = Random.Range(2, 4); num += num3; for (int j = 0; j < num3; j++) { GameObject val2 = list[Random.Range(0, list.Count)]; if (Refused.Contains(((Object)val2).name) || !Ground(val.Center, out var where)) { continue; } GameObject val3 = Birth(val2, where); if ((Object)(object)val3 != (Object)null) { Rouse(val3); PhotonView componentInChildren = val3.GetComponentInChildren<PhotonView>(true); if ((Object)(object)componentInChildren != (Object)null) { _brood.Add(componentInChildren.ViewID); } num2++; } } } Plugin.Log.LogInfo((object)(string.Format("{0} Blutmond ruft: {1} auf den Beinen, {2} ", "[FinalAscent]", list2.Count, num) + $"gewuerfelt, {num2} abgesetzt, Vorrat {list.Count} Arten.")); } private static List<Character> Living() { List<Character> allPlayerCharacters = PlayerHandler.GetAllPlayerCharacters(); List<Character> list = new List<Character>(); for (int i = 0; i < allPlayerCharacters.Count; i++) { Character val = allPlayerCharacters[i]; if ((Object)(object)val != (Object)null && (Object)(object)val.data != (Object)null && !val.data.dead && !val.data.fullyPassedOut) { list.Add(val); } } if (list.Count == 0 && (Object)(object)Character.localCharacter != (Object)null) { list.Add(Character.localCharacter); } return list; } private static void Rouse(GameObject born) { MushroomZombie componentInChildren = born.GetComponentInChildren<MushroomZombie>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.currentState = (State)1; return; } Mob[] componentsInChildren = born.GetComponentsInChildren<Mob>(true); foreach (Mob obj in componentsInChildren) { obj.aggroDistance = Mathf.Max(obj.aggroDistance, 22f); obj.movementSpeed *= 1.35f; obj.turnRate *= 1.35f; obj.sleeping = false; } VenusFlyTrap[] componentsInChildren2 = born.GetComponentsInChildren<VenusFlyTrap>(true); foreach (VenusFlyTrap obj2 in componentsInChildren2) { obj2.cooldownTime *= 0.5f; obj2.poisonDamage *= 1.5f; } } private static bool Ground(Vector3 hub, out Vector3 where) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return FinalAscentSpot.OnGround(hub, 12f, 25f, 8, out where); } private static GameObject Birth(GameObject prefab, Vector3 where) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) try { GameObject obj = PhotonNetwork.Instantiate(((Object)prefab).name, where, Quaternion.Euler(0f, Random.value * 360f, 0f), (byte)0, (object[])null); if ((Object)(object)obj == (Object)null) { Refused.Add(((Object)prefab).name); Plugin.Log.LogWarning((object)("[FinalAscent] Blutmond: '" + ((Object)prefab).name + "' liess sich nicht absetzen.")); } return obj; } catch (Exception ex) { Refused.Add(((Object)prefab).name); Plugin.Log.LogWarning((object)("[FinalAscent] Blutmond: '" + ((Object)prefab).name + "' nicht vernetzbar (" + ex.GetType().Name + ") - faellt fuer diese Sitzung aus dem Vorrat.")); return null; } } private static List<GameObject> Pool() { List<GameObject> list = new List<GameObject>(); Gather<MushroomZombie>(list); Gather<Beetle>(list); Gather<Scorpion>(list); Gather<VenusFlyTrap>(list); return list; } private static void Gather<T>(List<GameObject> into) where T : Component { //IL_002b: 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) T[] array = Resources.FindObjectsOfTypeAll<T>(); foreach (T val in array) { if (!((Object)(object)val == (Object)null)) { Scene scene = ((Component)val).gameObject.scene; if (!((Scene)(ref scene)).IsValid() && !Refu