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 ConfiguredTexts = new Dictionary(); internal static int GetClearedCount(Character character) { if ((Object)(object)character == (Object)null) { return 0; } AscentSync component = ((Component)character).GetComponent(); 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() : 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 Offered = new List(); 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(); 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(); 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(); ((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(); 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().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(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = Slate; } if ((Object)(object)drop.template != (Object)null) { Image component2 = ((Component)drop.template).GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Graphic)component2).color = Slate; } } TMP_Text[] componentsInChildren = ((Component)drop).GetComponentsInChildren(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 list = new List(); 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)(object)_pick.onValueChanged).AddListener((UnityAction)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(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(); val = (TMP_Text)(object)(((Object)(object)val3 != (Object)null && (Object)(object)val3.playerName != (Object)null) ? val3.playerName : _text); } TMP_Text[] componentsInChildren = ((Component)_pick).GetComponentsInChildren(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(true); if ((Object)(object)val == (Object)null) { val = Object.FindFirstObjectByType(); } 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("') .Append(i) .Append(""); if (i == 4) { stringBuilder.Append('\n'); } else if (i < 8) { stringBuilder.Append(' '); } } stringBuilder.Append("\nFINAL"); return stringBuilder.ToString(); } } internal class AscentChoicePreview : MonoBehaviour { private TMP_Dropdown _pick; private List _offered; internal void Bind(TMP_Dropdown pick, List 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(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(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() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } } } 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(); } 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)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)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.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(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 list = new List(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 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 list = new List(); 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 list = new List(); 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() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } } } [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((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 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 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 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 Transpiler(IEnumerable code) { List list = new List(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 __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)((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)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(); val3.renderMode = (RenderMode)0; val2.AddComponent(); _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(); 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(); _instance._rect = component; _instance._card = val; _instance._size = num; _instance._group = val4.AddComponent(); _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(true); ((UnityEvent)(object)_instance._toggle.onValueChanged).AddListener((UnityAction)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" + FinalAscentText.Get("apo.note") + ""; } 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() != (Object)null) { return "RectMask2D an '" + ((Object)parent).name + "'"; } if ((Object)(object)((Component)parent).GetComponent() != (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(instance.fogRises, instance.fogRises.transform.parent, false); ((Object)val).name = "FA_Banner"; val.SetActive(true); int num = 0; TextMeshProUGUI[] componentsInChildren = val.GetComponentsInChildren(true); foreach (TextMeshProUGUI obj in componentsInChildren) { ((TMP_Text)obj).text = text; ((Graphic)obj).color = colour; num++; } Text[] componentsInChildren2 = val.GetComponentsInChildren(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(); 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 _done = new HashSet(); 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((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Biome val in array) { if ((Object)(object)val == (Object)null || val.biomeType != type) { continue; } Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren(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 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((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)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)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 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((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Biome val in array) { if ((Object)(object)val == (Object)null || val.biomeType != type) { continue; } PropSpawner[] componentsInChildren = ((Component)val).GetComponentsInChildren(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(true); foreach (Renderer val5 in componentsInChildren2) { if ((Object)(object)val5 != (Object)null && val5.enabled && ((Component)val5).gameObject.activeInHierarchy) { num3++; } } Collider[] componentsInChildren3 = ((Component)val).GetComponentsInChildren(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 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 dictionary = new Dictionary(); Biome[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Biome val in array) { if ((Object)(object)val == (Object)null || val.biomeType != type) { continue; } PropSpawner[] componentsInChildren = ((Component)val).GetComponentsInChildren(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 _brood = new List(); private static readonly HashSet Refused = new HashSet(); 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(); } 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 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 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; 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 list = Pool(); if (list.Count == 0) { Plugin.Log.LogWarning((object)"[FinalAscent] Blutmond: keine Kreaturenvorlagen gefunden - es bleibt bei rotem Licht."); return; } List 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(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 Living() { List allPlayerCharacters = PlayerHandler.GetAllPlayerCharacters(); List list = new List(); 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(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.currentState = (State)1; return; } Mob[] componentsInChildren = born.GetComponentsInChildren(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(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 Pool() { List list = new List(); Gather(list); Gather(list); Gather(list); Gather(list); return list; } private static void Gather(List 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(); foreach (T val in array) { if (!((Object)(object)val == (Object)null)) { Scene scene = ((Component)val).gameObject.scene; if (!((Scene)(ref scene)).IsValid() && !Refused.Contains(((Object)((Component)val).gameObject).name)) { into.Add(((Component)val).gameObject); break; } } } } private void Dismiss() { if (!PhotonNetwork.IsMasterClient) { _brood.Clear(); return; } int num = 0; int num2 = 0; int num3 = 0; foreach (int item in _brood) { PhotonView val = PhotonView.Find(item); if ((Object)(object)val == (Object)null) { num3++; continue; } GameObject gameObject = ((Component)val).gameObject; MushroomZombie componentInChildren = gameObject.GetComponentInChildren(true); Character componentInChildren2 = gameObject.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren2 != (Object)null && (Object)(object)componentInChildren2.data != (Object)null) { componentInChildren.currentState = (State)6; componentInChildren2.data.SetSkeleton(true); num++; } else { PhotonNetwork.Destroy(gameObject); num2++; } } Plugin.Log.LogInfo((object)(string.Format("{0} Blutmond zieht ab - {1} gerufen: {2} zu Knochen, ", "[FinalAscent]", _brood.Count, num) + $"{num2} entfernt, {num3} waren schon fort.")); _brood.Clear(); } } [HarmonyPatch(typeof(DayNightManager), "UpdateCycle")] internal static class FinalAscentBloodMoonSky { private const float Glowing = 6.2f; private const float FadeSeconds = 6f; internal static bool Wanted; internal static float Lift; private static readonly Color Moonlight = new Color(1f, 0.3f, 0.24f, 1f); private static readonly Color SkyHigh = new Color(0.17f, 0.03f, 0.032f, 1f); private static readonly Color SkyMid = new Color(0.27f, 0.05f, 0.045f, 1f); private static readonly Color SkyLow = new Color(0.37f, 0.085f, 0.065f, 1f); private static readonly int TopKey = Shader.PropertyToID("SkyTopColor"); private static readonly int MidKey = Shader.PropertyToID("SkyMidColor"); private static readonly int LowKey = Shader.PropertyToID("SkyBottomColor"); private static void Prefix(DayNightManager __instance) { bool flag = Wanted && __instance.isDay < 0.5f; Lift = Mathf.MoveTowards(Lift, flag ? 1f : 0f, Time.deltaTime / 6f); } private static void Postfix(DayNightManager __instance) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (!(Lift <= 0f) && !((Object)(object)__instance.moon == (Object)null)) { float num = Mathf.Lerp(__instance.moon.intensity, 6.2f, Lift); if (num > __instance.moon.intensity) { __instance.moon.intensity = num; } __instance.moon.color = Color.Lerp(__instance.moon.color, Moonlight, Lift); if ((Object)(object)__instance.sun != (Object)null) { __instance.sun.color = Color.Lerp(__instance.sun.color, Moonlight, Lift); } Shader.SetGlobalColor(TopKey, Color.Lerp(Shader.GetGlobalColor(TopKey), SkyHigh, Lift)); Shader.SetGlobalColor(MidKey, Color.Lerp(Shader.GetGlobalColor(MidKey), SkyMid, Lift)); Shader.SetGlobalColor(LowKey, Color.Lerp(Shader.GetGlobalColor(LowKey), SkyLow, Lift)); } } } internal sealed class FinalAscentBlueMoon : MonoBehaviour { internal float rate = 2f; internal float amount = 0.025f; private const float Reach = 1000f; private const float Moonlit = 1f; private static readonly STATUSTYPE[] Order; private float counter; private bool _told; private bool _sung; private static FinalAscentBlueMoon _instance; private float _debt; 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_BlueMoon"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } if (!((Object)(object)_instance == (Object)null)) { _instance.counter = 0f; _instance._told = false; if (on) { _instance._sung = false; } } } private void Sing() { if (_sung) { return; } _sung = true; AmbienceAudio val = Object.FindFirstObjectByType(); if ((Object)(object)val == (Object)null || (Object)(object)val.mainMusic == (Object)null || (Object)(object)val.climbStingerPeak == (Object)null) { Plugin.Log.LogWarning((object)"[FinalAscent] Blauer Mond: keine Gipfelmusik gefunden."); return; } val.mainMusic.clip = val.climbStingerPeak; val.mainMusic.volume = 0.6f; val.mainMusic.loop = false; val.mainMusic.Play(); FieldInfo field = typeof(AmbienceAudio).GetField("priorityMusicTimer", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { field.SetValue(val, 120f); } Plugin.Log.LogInfo((object)("[FinalAscent] Blauer Mond: '" + ((Object)val.climbStingerPeak).name + "' gespielt" + ((field != null) ? "" : " - Vorrangzeit nicht erreichbar") + ".")); } private void Update() { //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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_008c: Unknown result type (might be due to invalid IL or missing references) if (!FinalAscentBlueMoonSky.Wanted && FinalAscentBlueMoonSky.Lift <= 0f) { return; } 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) { return; } Transform transform = ((Component)instance.moon).transform; RaycastHit val = HelperFunctions.LineCheck(localCharacter.Center + transform.forward * -1000f, localCharacter.Center, (LayerType)0, 0f, (QueryTriggerInteraction)1); if (!((Object)(object)((RaycastHit)(ref val)).transform != (Object)null) || !((Object)(object)((RaycastHit)(ref val)).transform.root != (Object)(object)((Component)localCharacter).transform.root)) { Sing(); counter += Time.deltaTime; if (!(counter <= rate)) { counter = 0f; Bless(localCharacter); } } } private void Bless(Character me) { CharacterAfflictions afflictions = me.refs.afflictions; if ((Object)(object)afflictions == (Object)null) { return; } for (int i = 0; i < Order.Length; i++) { if (!(Level(me, Order[i]) <= 0.0005f)) { Ease(me, afflictions, Order[i]); return; } } me.AddExtraStamina(amount); Tell($"nichts zu heilen - {amount * 100f:0.#} Bonusausdauer"); } private static float Level(Character me, STATUSTYPE type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0023: Unknown result type (might be due to invalid IL or missing references) if ((int)type == 13) { return (float)me.data.petrifyAmount / 100f; } return me.refs.afflictions.GetCurrentStatus(type); } private void Ease(Character me, CharacterAfflictions afflictions, STATUSTYPE type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) if ((int)type == 13) { _debt += amount * 100f; int num = Mathf.FloorToInt(_debt); if (num > 0) { _debt -= num; afflictions.SubtractStatus(type, (float)num / 100f, false, false); Tell($"loest {num} Punkte Versteinerung"); } } else { afflictions.SubtractStatus(type, amount, false, false); Tell($"lindert {type} um {amount * 100f:0.#}"); } } private void Tell(string what) { if (!_told) { _told = true; Plugin.Log.LogInfo((object)("[FinalAscent] Blauer Mond " + what + ".")); } } static FinalAscentBlueMoon() { STATUSTYPE[] array = new STATUSTYPE[8]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); Order = (STATUSTYPE[])(object)array; } } [HarmonyPatch(typeof(DayNightManager), "UpdateCycle")] internal static class FinalAscentBlueMoonSky { private const float Glowing = 7.5f; private const float FadeSeconds = 6f; internal static bool Wanted; internal static float Lift; private static readonly Color Moonlight = new Color(0.6f, 0.74f, 1f, 1f); private static readonly Color SkyHigh = new Color(0.075f, 0.13f, 0.29f, 1f); private static readonly Color SkyMid = new Color(0.135f, 0.215f, 0.415f, 1f); private static readonly Color SkyLow = new Color(0.21f, 0.325f, 0.545f, 1f); private static readonly int TopKey = Shader.PropertyToID("SkyTopColor"); private static readonly int MidKey = Shader.PropertyToID("SkyMidColor"); private static readonly int LowKey = Shader.PropertyToID("SkyBottomColor"); private static void Prefix(DayNightManager __instance) { bool flag = Wanted && __instance.isDay < 0.5f; Lift = Mathf.MoveTowards(Lift, flag ? 1f : 0f, Time.deltaTime / 6f); } private static void Postfix(DayNightManager __instance) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (!(Lift <= 0f) && !((Object)(object)__instance.moon == (Object)null)) { float num = Mathf.Lerp(__instance.moon.intensity, 7.5f, Lift); if (num > __instance.moon.intensity) { __instance.moon.intensity = num; } __instance.moon.color = Color.Lerp(__instance.moon.color, Moonlight, Lift); if ((Object)(object)__instance.sun != (Object)null) { __instance.sun.color = Color.Lerp(__instance.sun.color, Moonlight, Lift); } Shader.SetGlobalColor(TopKey, Color.Lerp(Shader.GetGlobalColor(TopKey), SkyHigh, Lift)); Shader.SetGlobalColor(MidKey, Color.Lerp(Shader.GetGlobalColor(MidKey), SkyMid, Lift)); Shader.SetGlobalColor(LowKey, Color.Lerp(Shader.GetGlobalColor(LowKey), SkyLow, Lift)); } } } internal static class FinalAscentBridges { private const string Tag = "[FinalAscent]"; internal static void Disarm() { try { BreakableBridge[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); if (array.Length == 0) { return; } int num = 0; int num2 = 0; int num3 = 0; BreakableBridge[] array2 = array; foreach (BreakableBridge val in array2) { if ((Object)(object)val == (Object)null) { continue; } bool flag = false; CollisionModifier[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (CollisionModifier val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null)) { num++; if (val2.onCollide != null) { flag = true; } if (val2.applyEffects) { num2++; val2.applyEffects = false; } } } if (!flag) { num3++; } } if (num2 == 0) { Plugin.Log.LogInfo((object)(string.Format("{0} Bruecken: {1} Stueck mit {2} Planken, ", "[FinalAscent]", array.Length, num) + "alle bereits entschaerft - Vanillas Awake hat gegriffen.")); return; } Plugin.Log.LogInfo((object)(string.Format("{0} Bruecken entschaerft: {1} von {2} Planken an ", "[FinalAscent]", num2, num) + $"{array.Length} Bruecken trugen noch scharfen Einsturzschaden " + "und haetten bei Beruehrung getoetet. Vanillas eigene Regel (BreakableBridge.Awake: applyEffects = false) nachgeholt.")); if (num3 > 0) { Plugin.Log.LogWarning((object)(string.Format("{0} ACHTUNG: bei {1} Bruecken ist auch der ", "[FinalAscent]", num3) + "Einsturz-Haken leer - dort lief das Awake gar nicht, und sie duerften nicht mehr zusammenbrechen. Eigener Fehler, eigene Suche.")); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Bruecken-Entschaerfung misslang: " + ex.Message)); } } } internal static class FinalAscentBuilder { private struct WallAnchor { public GameObject wall; public Vector3 originalPosition; public BiomeType alignTo; public string label; public BiomeType? cloneFor; public int segmentIndex; } private class StageWallPair { internal GameObject Top; internal GameObject Bottom; } internal static class HeightFog { private static readonly int HeightFogHeight = Shader.PropertyToID("HeightFogHeight"); private static float _lift; private static float _base; private static float _lastWritten = float.NaN; internal static void SetLift(float lift, string why) { if (!Mathf.Approximately(_lift, lift)) { _lift = lift; _lastWritten = float.NaN; Plugin.Detail(string.Format("{0} Hoehennebel folgt {1} um {2:F0} nach oben.", "[FinalAscent]", why, lift)); } } internal static void Reset() { _lift = 0f; _lastWritten = float.NaN; } internal static void Tick() { if (_lift != 0f) { float globalFloat = Shader.GetGlobalFloat(HeightFogHeight); if (float.IsNaN(_lastWritten) || Mathf.Abs(globalFloat - _lastWritten) > 0.01f) { _base = globalFloat; } _lastWritten = _base + _lift; Shader.SetGlobalFloat(HeightFogHeight, _lastWritten); } } } private const string Tag = "[FinalAscent]"; private static readonly MethodInfo DetectBiomesMethod = AccessTools.Method(typeof(MapHandler), "DetectBiomes", (Type[])null, (Type[])null); private static readonly Vector3 CalderaOffset = new Vector3(9.8f, 601.7f, 1116.8f); internal static readonly Vector3 KilnCampfireShift = new Vector3(-1.8f, 0f, -28.8f); internal const float KilnCampfireLift = 0f; private static readonly Vector3 GloomVanillaFoot = new Vector3(2.8f, 836.7f, 1216.9f); private static readonly Vector3 GloomOffset = KilnSummitPoint() - GloomVanillaFoot + new Vector3(0f, -5f, -40f); internal const float GloomLift = -5f; internal const float GloomPull = 40f; internal static readonly Dictionary Offsets = new Dictionary { { (BiomeType)0, Vector3.zero }, { (BiomeType)1, Vector3.zero }, { (BiomeType)7, new Vector3(-0.7f, 279.7f, 423f) }, { (BiomeType)2, new Vector3(-0.7f, 279.7f, 423f) }, { (BiomeType)6, new Vector3(12.6f, 596.5f, 1107.7f) }, { (BiomeType)3, CalderaOffset }, { (BiomeType)8, GloomOffset }, { (BiomeType)5, GloomOffset }, { (BiomeType)9, GloomOffset } }; internal const float MesaLift = 20f; internal static readonly List> StageMarkers = new List>(); private static readonly Dictionary StepKeys = new Dictionary { { "Gipfel auf die Zitadelle legen", "load.prepare" }, { "Biome aktivieren und versetzen", "load.prepare" }, { "Innenraum der Zitadelle aufschliessen", "load.prepare" }, { "Unbeantwortbare Bedingungen stummschalten", "load.prepare" }, { "Physik abgleichen", "load.prepare" }, { "Hoehenschranken der Spawner nachziehen", "load.prepare" }, { "Wuerfel auf den Seed setzen", "load.prepare" }, { "Generierung", "load.gen" }, { "Nahtstellen vermessen", "load.measure" }, { "Kuppe des Kiln vermessen", "load.measure" }, { "Nebel-Ursprünge und -Aussparungen nachziehen", "load.measure" }, { "Nebelwaende nachziehen", "load.measure" }, { "Wetterzonen neu einmessen", "load.measure" }, { "Lichtdaten neu backen", "load.light" }, { "Segmente verdrahten", "load.wire" }, { "Rufnummern rechnen", "load.wire" }, { "Aufsteigende Gefahren nachziehen", "load.wire" }, { "Gipfelhoehe fuer den Endscreen messen", "load.wire" }, { "Statuen zaehlen", "load.wire" }, { "Etappenstand festhalten", "load.wire" }, { "Beobachter abschalten", "load.wire" }, { "Lagerfeuer zaehlen", "load.wire" }, { "Ausgangslage festhalten", "load.prepare" }, { "Fassungen abgleichen", "load.prepare" }, { "Welt vollstaendig anschalten", "load.prepare" } }; private static readonly Dictionary StageWalls = new Dictionary(); private static GameObject _mesaBandBottom; private static bool _mesaBandBottomDropped; private static Transform _wallHolder; private static readonly Dictionary FogChildNames = new Dictionary { { "Beach", (BiomeType)0 }, { "Tropics", (BiomeType)1 }, { "Roots", (BiomeType)7 }, { "Alpine", (BiomeType)2 }, { "Mesa", (BiomeType)6 }, { "Caldera", (BiomeType)3 }, { "Volcano", (BiomeType)3 }, { "Tundra", (BiomeType)2 }, { "Glacier", (BiomeType)2 }, { "Peak", (BiomeType)5 } }; private static Vector3? _measuredSummit; private static Dictionary _pristineOffsets; private static readonly Dictionary WindHeightOriginals = new Dictionary(); internal static bool Done { get; private set; } internal static bool Building { get; private set; } internal static bool Awaited { get; private set; } internal static bool Ready { get; private set; } internal static void Expect() { Awaited = true; Ready = false; } internal static void MarkReady() { Ready = true; Awaited = false; FinalAscentRoster.Begin(); FinalAscentItemResync.Listen(); FinalAscentItemResync.AskWhenReady(); FinalAscentBiomeAudit.Begin(); } internal static void MarkBuilt() { Awaited = false; } internal static void Cancel() { Awaited = false; Ready = true; } internal static IEnumerator BuildRoutine() { if (Building) { yield break; } Building = true; FinalAscentVoidGuard.Reset(); FinalAscentRoster.Latch(); Done = false; Ready = false; float patience = 45f; bool waitedForRoom = false; while (patience > 0f && PhotonNetwork.IsConnected && !PhotonNetwork.InRoom) { waitedForRoom = true; patience -= Time.deltaTime; FinalAscentKeepAlive.Tick(); yield return null; } if (waitedForRoom) { Plugin.Log.LogInfo((object)("[FinalAscent] Auf den Raumbeitritt gewartet - Zustand jetzt " + $"{PhotonNetwork.NetworkClientState}, im Raum={PhotonNetwork.InRoom}.")); } if (PhotonNetwork.IsConnected && !PhotonNetwork.InRoom) { Plugin.Log.LogWarning((object)("[FinalAscent] Auch nach 45s nicht im Raum " + $"({PhotonNetwork.NetworkClientState}) - der Bau laeuft trotzdem, " + "aber die Post bleibt in Bewegung.")); } FinalAscentDelivery.ClientMode = FinalAscent.Active && PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode && !PhotonNetwork.IsMasterClient; FinalAscentDelivery.Listen(); if (FinalAscentDelivery.ClientMode) { Plugin.Log.LogInfo((object)"[FinalAscent] Auslieferungs-Pfad: dieser Rechner generiert nicht, er wartet auf das Inselpaket des Hosts."); } int lastColliders = -1; int lastViews = -1; int stable = 0; int waitedFrames = 0; patience = Time.realtimeSinceStartup; while (waitedFrames < 900) { int num = Object.FindObjectsByType((FindObjectsSortMode)0).Length; int num2 = 0; ValueIterator enumerator = PhotonNetwork.PhotonViewCollection.GetEnumerator(); try { while (enumerator.MoveNext()) { _ = enumerator.Current; num2++; } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } if (num == lastColliders && num2 == lastViews) { stable++; } else { stable = 0; lastColliders = num; lastViews = num2; } if (stable >= 20 && Time.realtimeSinceStartup - patience >= 0.5f) { break; } waitedFrames++; FinalAscentKeepAlive.Tick(); yield return null; } if (waitedFrames >= 900) { Plugin.Log.LogWarning((object)(string.Format("{0} Die Szene kam in {1} Bildern nicht zur Ruhe ", "[FinalAscent]", 900) + $"(zuletzt {lastColliders} Kollider, {lastViews} Rufnummern) - " + "der Bau beginnt trotzdem. Weicht der Berg ab, ist das die erste Spur.")); } else { Plugin.Log.LogInfo((object)(string.Format("{0} Szene angekommen nach {1} Bildern: ", "[FinalAscent]", waitedFrames) + $"{lastColliders} aktive Kollider, {lastViews} Rufnummern, " + "zwanzig Bilder ohne Nachzuegler. Erst jetzt haelt die Post an.")); } if (PhotonNetwork.IsConnected && PhotonNetwork.InRoom && !FinalAscentDelivery.ClientMode) { PhotonNetwork.IsMessageQueueRunning = false; } SimulationMode simulationWas = Physics.simulationMode; Physics.simulationMode = (SimulationMode)2; List> masked = new List>(); Camera[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (Camera val in array) { if (!((Object)(object)val == (Object)null) && val.cullingMask != 0) { masked.Add(new KeyValuePair(val, val.cullingMask)); val.cullingMask = 0; } } Plugin.Log.LogInfo((object)string.Format("{0} {1} Kameras zeichnen waehrend des Aufbaus nichts.", "[FinalAscent]", masked.Count)); FinalAscentKeepAlive.Begin(); FinalAscentLoadHud.Show(); FinalAscentFrames.Mark(); try { foreach (object item in FinalAscentFrames.Through(BuildInner())) { yield return item; } } finally { FinalAscentKeepAlive.End(); foreach (KeyValuePair item2 in masked) { if ((Object)(object)item2.Key != (Object)null) { item2.Key.cullingMask = item2.Value; } } Physics.simulationMode = simulationWas; if (PhotonNetwork.IsConnected) { PhotonNetwork.IsMessageQueueRunning = true; } Building = false; Done = true; } } private static IEnumerator BuildInner() { StageMarkers.Clear(); FinalAscentAmbience.Reset(); HeightFog.Reset(); WindHeightOriginals.Clear(); FinalAscentWorld.Clear(); FinalAscentLight.Reset(); FinalAscentDiceWatch.Reset(); FinalAscentHeightmap.Reset(); FinalAscentTombEntrance.Reset(); FinalAscentBaked.Announce(); FinalAscentHeights.Reset(); _measuredSummit = null; ResetOffsets(); FinalAscentTerrainRandomiser.StepAside(); LevelGeneration levelGen = Object.FindFirstObjectByType(); if ((Object)(object)levelGen == (Object)null) { Plugin.Log.LogError((object)"[FinalAscent] Kein LevelGeneration in der Szene. Laeuft der Lauf auf WilIsland?"); yield break; } List walls = CaptureWalls(); Random.InitState(FinalAscent.Seed); Plugin.Log.LogInfo((object)string.Format("{0} Umbau startet, Seed={1}.", "[FinalAscent]", FinalAscent.Seed)); FinalAscentSpawnSegmentPatch.Forget(); Step("Gipfel auf die Zitadelle legen", delegate { MovePeakToCitadel(levelGen); }); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Biome aktivieren und versetzen", delegate { ActivateAndOffsetBiomes(levelGen); }); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Innenraum der Zitadelle aufschliessen", delegate { OpenCitadelInterior(levelGen); }); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Unbeantwortbare Bedingungen stummschalten", MuteUnanswerableConstraints); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Physik abgleichen", (Action)Physics.SyncTransforms); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Hoehenschranken der Spawner nachziehen", delegate { FixAbsoluteHeights(levelGen); }); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Fassungen abgleichen", delegate { FinalAscentVersions.Announce("1.0.4"); FinalAscentVersions.ReportLater("1.0.4"); }); Step("Welt vollstaendig anschalten", WakeWholeMap); int last = -1; int stable = 0; int waitedFrames = 0; while (waitedFrames < 600) { int num = Object.FindObjectsByType((FindObjectsSortMode)0).Length; if (num == last) { stable++; } else { stable = 0; last = num; } if (stable >= 20) { break; } waitedFrames++; FinalAscentKeepAlive.Tick(); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); } FinalAscentFrames.Mark(); Plugin.Log.LogInfo((object)(string.Format("{0} Einrichtung der geweckten Welt fertig nach {1} ", "[FinalAscent]", waitedFrames) + $"Bildern: {last} aktive Kollider, zwanzig Bilder unveraendert." + ((waitedFrames >= 600) ? " (ABBRUCH nach Frist - erste Spur bei Abweichungen.)" : ""))); Step("Ausgangslage festhalten", ReportWorldBefore); Quiet("Kollider-Inventur", FinalAscentColliderCensus.TakeAndCompare); Step("Wuerfel auf den Seed setzen", delegate { Random.InitState(FinalAscent.Seed); FinalAscentFrames.Split(); Plugin.Log.LogInfo((object)string.Format("{0} Wuerfel auf Seed {1} gesetzt.", "[FinalAscent]", FinalAscent.Seed)); }); if (!FinalAscentDelivery.ClientMode) { foreach (object item in FinalAscentFrames.Through(StepThrough("Generierung", RunGeneration(levelGen)))) { yield return item; } Step("Kuppe des Kiln vermessen", delegate { MeasureSummitAndFollow(levelGen); }); FinalAscentWorldCensus.Take("bauende"); FinalAscentDiceWatch.Report(); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); Step("Anstrich der Fassungen einsammeln", FinalAscentPaint.Collect); Quiet("Inselpaket ausliefern", FinalAscentDelivery.PackAndShip); } else { foreach (object item2 in FinalAscentFrames.Through(StepThrough("Karte auspacken", FinalAscentDelivery.WaitAndApply(() => RunGeneration(levelGen), levelGen)))) { yield return item2; } } Step("Nahtstellen vermessen", delegate { ProbeSeams(levelGen); }); Step("Saegen neu ankern", FinalAscentSaws.Reanchor); Step("Lava neu vermessen", FinalAscentLava.Remeasure); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Nebel-Ursprünge und -Aussparungen nachziehen", MoveFogHelpers); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Nebelwaende nachziehen", delegate { RepositionWalls(walls, levelGen); }); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Wetterzonen neu einmessen", RefreshWeatherBounds); Quiet("Nebel-Kette neu stanzen", FinalAscentZones.RepunchCutouts); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Lichtdaten neu backen", FinalAscentLight.StartBake); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); if (FinalAscentLightBake.Busy || FinalAscentLight.Baking) { FinalAscentFrames.Hold(); while (FinalAscentLightBake.Busy || FinalAscentLight.Baking) { yield return null; } FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); } Step("Segmente verdrahten", FinalAscentSegments.Wire); Step("Verpasste Beitritts-Meldungen nachholen", FinalAscentJoinCatchup.Run); Step("Scoutmaster-Reichweite anheben", FinalAscentScoutmaster.Raise); Quiet("Grossen Geist ausmessen", FinalAscentGhostBallProbe.Report); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Rufnummern rechnen", FinalAscentViewIDs.Assign); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Aufsteigende Gefahren nachziehen", FinalAscentRises.Recalibrate); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Gipfelhoehe fuer den Endscreen messen", FinalAscentHeights.Measure); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); Step("Statuen zaehlen", FinalAscentGeneration.CountStatues); Step("Beobachter abschalten", FinalAscentNoLookers.SilenceAll); Step("Lagerfeuer zaehlen", FinalAscentFireReport.Report); Step("Vorlagen-Probe", FinalAscentPaint.ProbeVariantPrefabs); Step("Schaustueck-Nummern vergeben", FinalAscentFakeItems.Renumber); Step("Schwierigkeit setzen", FinalAscentDifficulty.Apply); Step("Bruecken entschaerfen", FinalAscentBridges.Disarm); Step("Doppelladungen suchen", FinalAscentDoubleLoad.Report); Step("Etappenstand festhalten", FinalAscentSegments.ReportStages); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); } private static IEnumerator StepThrough(string name, IEnumerator inner) { Announce(name); FinalAscentKeepAlive.Doing(name); FinalAscentKeepAlive.Tick(); float started = Time.realtimeSinceStartup; foreach (object item in FinalAscentFrames.Through(inner)) { yield return item; } FinalAscentKeepAlive.Tick(); Plugin.Log.LogInfo((object)string.Format("{0} OK: {1} ({2:F1}s)", "[FinalAscent]", name, Time.realtimeSinceStartup - started)); } private static void Announce(string name) { StepKeys.TryGetValue(name, out var value); FinalAscentLoadHud.Phase(value, FinalAscentText.Get("load.build")); FinalAscentLoadHud.Detail(name); } private static void Quiet(string name, Action action) { try { FinalAscentKeepAlive.Tick(); action(); FinalAscentKeepAlive.Tick(); Plugin.Log.LogInfo((object)("[FinalAscent] OK: " + name)); } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("{0} FEHLER in '{1}': {2}", "[FinalAscent]", name, arg)); } } private static void Step(string name, Action action) { try { Announce(name); FinalAscentKeepAlive.Doing(name); FinalAscentKeepAlive.Tick(); float realtimeSinceStartup = Time.realtimeSinceStartup; action(); FinalAscentKeepAlive.Tick(); Plugin.Log.LogInfo((object)string.Format("{0} OK: {1} ({2:F1}s)", "[FinalAscent]", name, Time.realtimeSinceStartup - realtimeSinceStartup)); } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("{0} FEHLER in '{1}': {2}", "[FinalAscent]", name, arg)); } } private static void WakeWholeMap() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) MapHandler instance = Singleton.Instance; if ((Object)(object)instance == (Object)null || instance.segments == null) { Plugin.Log.LogWarning((object)"[FinalAscent] Kein MapHandler - die Welt bleibt, wie sie ist."); return; } int num = 0; int num2 = 0; MapSegment[] segments = instance.segments; foreach (MapSegment val in segments) { if (val != null) { if (!Offsets.ContainsKey(val.biome)) { num2++; } else if (WakeChain(val.segmentParent)) { num++; } } } int num3 = 0; if (instance.variantSegments != null) { segments = instance.variantSegments; foreach (MapSegment val2 in segments) { if (val2 != null) { if (!Offsets.ContainsKey(val2.biome)) { num2++; } else if (WakeChain(val2.segmentParent)) { num3++; } } } } int num4 = 0; EnablingSubstep[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (EnablingSubstep val3 in array) { if (!((Object)(object)val3 == (Object)null)) { Biome componentInParent = ((Component)val3).GetComponentInParent(true); if ((Object)(object)componentInParent == (Object)null || !Offsets.ContainsKey(componentInParent.biomeType)) { num2++; } else if (WakeChain(((Component)val3).gameObject)) { num4++; } } } Physics.SyncTransforms(); Plugin.Log.LogInfo((object)(string.Format("{0} Welt geweckt: {1} Segmente, {2} zweite Etappen und ", "[FinalAscent]", num, num3) + $"{num4} zurueckgestellte Teile angeschaltet; {num2} nicht eingeplante " + "uebergangen (Void und dergleichen bleiben aus).")); } private static bool WakeChain(GameObject of) { if ((Object)(object)of == (Object)null || of.activeInHierarchy) { return false; } List list = new List(); Transform val = of.transform; while ((Object)(object)val != (Object)null) { list.Add(((Component)val).gameObject); val = val.parent; } for (int num = list.Count - 1; num >= 0; num--) { if (!list[num].activeSelf) { list[num].SetActive(true); } } return true; } private static void ReportWorldBefore() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) List list = new List(); Biome[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Biome val in array) { if ((Object)(object)val == (Object)null) { continue; } int num = 0; Collider[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Collider val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null && val2.enabled && ((Component)val2).gameObject.activeInHierarchy) { num++; } } list.Add(string.Format("{0}: {1}, ", val.biomeType, ((Component)val).gameObject.activeInHierarchy ? "an " : "AUS") + $"{num} Kollider"); } list.Sort(StringComparer.Ordinal); Plugin.Log.LogInfo((object)string.Format("{0} Ausgangslage vor dem Bau ({1} Landschaften):", "[FinalAscent]", list.Count)); foreach (string item in list) { Plugin.Log.LogInfo((object)("[FinalAscent] " + item)); } } private static void ActivateAndOffsetBiomes(LevelGeneration levelGen) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0116: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) BiomeSelector[] componentsInChildren = ((Component)levelGen).GetComponentsInChildren(true); Plugin.Log.LogInfo((object)string.Format("{0} {1} BiomeSelectors gefunden.", "[FinalAscent]", componentsInChildren.Length)); for (int i = 0; i < componentsInChildren.Length; i++) { foreach (BiomeOption biome in componentsInChildren[i].Biomes) { if (biome == null || (Object)(object)biome.biomeParent == (Object)null) { continue; } GameObject gameObject = ((Component)biome.biomeParent).gameObject; BiomeType biomeType = biome.biomeParent.biomeType; if (!Offsets.TryGetValue(biomeType, out var value)) { gameObject.SetActive(false); Plugin.Log.LogInfo((object)string.Format("{0} {1} bleibt deaktiviert (noch nicht eingeplant).", "[FinalAscent]", biomeType)); continue; } if (value != Vector3.zero) { Transform transform = gameObject.transform; transform.position += value; } gameObject.SetActive(true); Plugin.Log.LogInfo((object)string.Format("{0} {1} '{2}' aktiv, Versatz {3}, Position {4}.", "[FinalAscent]", biomeType, ((Object)gameObject).name, Fmt(value), Fmt(gameObject.transform.position))); CollectStageMarkers(gameObject, biomeType); } } StageMarkers.Sort((KeyValuePair a, KeyValuePair b) => a.Value.z.CompareTo(b.Value.z)); } private static void OpenCitadelInterior(LevelGeneration levelGen) { GameObject val = FindBiomeRoot(levelGen, (BiomeType)8); Transform val2 = (((Object)(object)val != (Object)null) ? DeepFind(val.transform, "Temple_Segment") : null); if ((Object)(object)val2 == (Object)null) { Plugin.Log.LogWarning((object)"[FinalAscent] Kein Temple_Segment gefunden."); return; } int num = 0; List list = new List(); Transform[] componentsInChildren = ((Component)val2).GetComponentsInChildren(true); foreach (Transform val3 in componentsInChildren) { if (!((Component)val3).gameObject.activeSelf && !((Object)(object)((Component)val3).GetComponentInChildren(true) == (Object)null) && !((Object)(object)((Component)val3).GetComponent() != (Object)null) && !((Object)(object)((Component)val3).GetComponent() != (Object)null)) { ((Component)val3).gameObject.SetActive(true); num++; if (list.Count < 12) { list.Add(((Object)val3).name); } } } Plugin.Detail(string.Format("{0} {1} Innenraeume aufgeschlossen", "[FinalAscent]", num) + ((list.Count > 0) ? (": " + string.Join(", ", list)) : ".")); } private static void MuteUnanswerableConstraints() { int num = 0; List list = new List(); PropSpawner[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (PropSpawner val in array) { if (val.constraints == null) { continue; } foreach (PropSpawnerConstraint constraint in val.constraints) { PSC_NearObject val2 = (PSC_NearObject)(object)((constraint is PSC_NearObject) ? constraint : null); if (val2 == null || ((PropSpawnerConstraint)val2).mute || val2.inverted) { continue; } bool flag = false; string text = ""; if (val2.objects != null) { GameObject[] objects = val2.objects; foreach (GameObject val3 in objects) { if (!((Object)(object)val3 == (Object)null)) { text = text + ((text.Length > 0) ? "+" : "") + ((Object)val3).name; if ((Object)(object)GameObject.Find(((Object)val3).name) != (Object)null) { flag = true; } } } } if (!flag) { ((PropSpawnerConstraint)val2).mute = true; num++; if (list.Count < 10) { list.Add(((Object)val).name + " sucht '" + text + "'"); } } } } Plugin.Detail(string.Format("{0} {1} Nachbarschafts-Bedingungen stummgeschaltet, weil das gesuchte ", "[FinalAscent]", num) + "Objekt in der Szene nicht existiert" + ((list.Count > 0) ? (": " + string.Join(", ", list)) : ".")); } internal static Transform DeepFindPublic(Transform root, string name) { return DeepFind(root, name); } private static Transform DeepFind(Transform root, string name) { if (((Object)root).name == name) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = DeepFind(root.GetChild(i), name); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static void FixAbsoluteHeights(LevelGeneration levelGen) { //IL_004c: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) BiomeSelector[] componentsInChildren = ((Component)levelGen).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { foreach (BiomeOption biome in componentsInChildren[i].Biomes) { if (!((Object)(object)biome?.biomeParent == (Object)null) && Offsets.TryGetValue(biome.biomeParent.biomeType, out var value) && !(value == Vector3.zero)) { GameObject gameObject = ((Component)biome.biomeParent).gameObject; int num = ShiftHeightConstraints(gameObject, value.y); int num2 = ShiftSpawnPools(gameObject, value.z, value.y); FinalAscentWorld.Register(gameObject.transform, value); Plugin.Detail(string.Format("{0} {1}: {2} Hoehenschranken um ", "[FinalAscent]", biome.biomeParent.biomeType, num) + $"{value.y:F0}, {num2} Beutetabellen um {value.z:F0}, " + "Weltabfragen um " + Fmt(value) + " zurueckgerechnet."); } } } } private static int ShiftHeightConstraints(GameObject root, float deltaY) { int num = 0; PropSpawner[] componentsInChildren = root.GetComponentsInChildren(true); foreach (PropSpawner val in componentsInChildren) { if (val.constraints == null) { continue; } foreach (PropSpawnerConstraint constraint in val.constraints) { PSC_Height val2 = (PSC_Height)(object)((constraint is PSC_Height) ? constraint : null); if (val2 != null) { if (val2.minHeight > -9000f) { val2.minHeight += deltaY; num++; } if (val2.maxHeight < 9000f) { val2.maxHeight += deltaY; num++; } } } } return num; } private static int ShiftSpawnPools(GameObject root, float deltaZ, float deltaY) { int num = 0; Spawner[] componentsInChildren = root.GetComponentsInChildren(true); foreach (Spawner val in componentsInChildren) { if (val.heightBasedSpawnPools == null) { continue; } for (int j = 0; j < val.heightBasedSpawnPools.Count; j++) { HeightBasedSpawnListEntry val2 = val.heightBasedSpawnPools[j]; if (val2 != null) { val2.minimumZ += deltaZ; val2.minimumHeight += deltaY; val.heightBasedSpawnPools[j] = val2; num++; } } } return num; } private unsafe static void CollectStageMarkers(GameObject root, BiomeType type) { //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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) Campfire[] componentsInChildren = root.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Vector3 position = ((Component)componentsInChildren[i]).transform.position; StageMarkers.Add(new KeyValuePair(((object)(*(BiomeType*)(&type))/*cast due to .constrained prefix*/).ToString(), position)); Plugin.Detail(string.Format("{0} Lagerfeuer {1} '{2}' bei {3}", "[FinalAscent]", type, ((Object)componentsInChildren[i]).name, Fmt(position))); } } internal static void DropMesaBandBottom(string why) { if (!_mesaBandBottomDropped) { _mesaBandBottomDropped = true; if ((Object)(object)_mesaBandBottom != (Object)null) { _mesaBandBottom.SetActive(false); } Plugin.Log.LogInfo((object)("[FinalAscent] Gruft-Trenner: 'FA_StageWallBottom_Alpine' abgeschaltet (" + why + "). Die Rampe reicht bei 20,6 Grad Neigung bis in den Gruftkorridor - ab jetzt liegt dort nichts Unsichtbares mehr im Weg.")); } } private static Transform WallHolder() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown if ((Object)(object)_wallHolder != (Object)null) { return _wallHolder; } MapHandler instance = Singleton.Instance; GameObject val = new GameObject("FA_Walls"); if ((Object)(object)instance != (Object)null) { val.transform.SetParent(((Component)instance).transform, true); } _wallHolder = val.transform; return _wallHolder; } internal static void StageWallsOnSegmentEnter(int segmentIndex) { SwitchStageWalls(segmentIndex, top: true, bottom: false, "Segment betreten"); } internal static void StageWallsOnStageAdvance(int segmentIndex) { SwitchStageWalls(segmentIndex, top: false, bottom: true, "Etappenwechsel"); } internal static void StageWallsOnSegmentLeave(int segmentIndex) { SwitchStageWalls(segmentIndex, top: false, bottom: false, "Segment verlassen"); } private static void SwitchStageWalls(int segmentIndex, bool top, bool bottom, string what) { if (StageWalls.TryGetValue(segmentIndex, out var value) && value != null) { if ((Object)(object)value.Top != (Object)null) { value.Top.SetActive(top); } if ((Object)(object)value.Bottom != (Object)null) { bool active = bottom && (!_mesaBandBottomDropped || !((Object)(object)value.Bottom == (Object)(object)_mesaBandBottom)); value.Bottom.SetActive(active); } Plugin.Detail(string.Format("{0} Trenner Segment {1} ({2}): oben {3}, ", "[FinalAscent]", segmentIndex, what, top ? "an" : "aus") + "unten " + (bottom ? "an" : "aus") + "."); } } private static List CaptureWalls() { //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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) List list = new List(); StageWalls.Clear(); _wallHolder = null; _mesaBandBottom = null; _mesaBandBottomDropped = false; MapHandler instance = Singleton.Instance; if ((Object)(object)instance == (Object)null || instance.segments == null) { return list; } BiomeType[] array = new BiomeType[5]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); BiomeType[] array2 = (BiomeType[])(object)array; BiomeType[] array3 = new BiomeType[5]; RuntimeHelpers.InitializeArray(array3, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); BiomeType[] array4 = (BiomeType[])(object)array3; bool[] array5 = new bool[5] { false, true, true, false, false }; for (int i = 0; i < instance.segments.Length && i < array2.Length; i++) { MapSegment val = instance.segments[i]; if (val != null) { if ((Object)(object)val.wallPrevious != (Object)null) { list.Add(new WallAnchor { wall = val.wallPrevious, originalPosition = val.wallPrevious.transform.position, alignTo = array2[i], label = $"seg{i}.wallPrevious", segmentIndex = i }); } if ((Object)(object)val.wallNext != (Object)null) { list.Add(new WallAnchor { wall = val.wallNext, originalPosition = val.wallNext.transform.position, alignTo = array4[i], label = $"seg{i}.wallNext", cloneFor = (array5[i] ? new BiomeType?(array2[i]) : ((BiomeType?)null)), segmentIndex = i }); } } } return list; } private static void RepositionWalls(List anchors, LevelGeneration levelGen) { //IL_002b: 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_0045: 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_008b: 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) foreach (WallAnchor anchor in anchors) { if (!((Object)(object)anchor.wall == (Object)null) && Offsets.TryGetValue(anchor.alignTo, out var value)) { Vector3 val = anchor.originalPosition + value; anchor.wall.transform.SetParent(WallHolder(), true); anchor.wall.transform.position = val; Plugin.Detail(string.Format("{0} {1} -> {2} (an {3})", "[FinalAscent]", anchor.label, Fmt(val), anchor.alignTo)); } } foreach (WallAnchor anchor2 in anchors) { if (anchor2.cloneFor.HasValue) { CreateStageWallPair(anchor2, anchors); } } FinalAscentTombGate.ApplyFromRoom(); } private unsafe static void CreateStageWallPair(WallAnchor anchor, List anchors) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Invalid comparison between Unknown and I4 //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) BiomeType value = anchor.cloneFor.Value; if (!Offsets.TryGetValue(value, out var value2)) { return; } StageWallPair stageWallPair = new StageWallPair { Top = CloneWall(anchor.wall, anchor.originalPosition + value2, "FA_StageWallTop_" + ((object)(*(BiomeType*)(&value))/*cast due to .constrained prefix*/).ToString()) }; string text = $"seg{anchor.segmentIndex + 1}.wallPrevious"; foreach (WallAnchor anchor2 in anchors) { if (!(anchor2.label != text) && !((Object)(object)anchor2.wall == (Object)null)) { stageWallPair.Bottom = CloneWall(anchor2.wall, anchor2.originalPosition + value2, "FA_StageWallBottom_" + ((object)(*(BiomeType*)(&value))/*cast due to .constrained prefix*/).ToString()); break; } } if ((int)value == 2) { _mesaBandBottom = stageWallPair.Bottom; } StageWalls[anchor.segmentIndex] = stageWallPair; Plugin.Detail(string.Format("{0} Trennerpaar Segment {1} (nach {2}): ", "[FinalAscent]", anchor.segmentIndex, value) + "oben " + (((Object)(object)stageWallPair.Top != (Object)null) ? Fmt(stageWallPair.Top.transform.position) : "-") + ", unten " + (((Object)(object)stageWallPair.Bottom != (Object)null) ? Fmt(stageWallPair.Bottom.transform.position) : "FEHLT") + "."); } internal static float HeightAboveGround(GameObject probe) { //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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)probe == (Object)null) { return 0f; } RaycastHit[] array = Physics.RaycastAll(probe.transform.position + Vector3.up * 10f, Vector3.down, 300f, -1, (QueryTriggerInteraction)1); float num = float.NaN; for (int i = 0; i < array.Length; i++) { Transform val = (((Object)(object)((RaycastHit)(ref array[i])).collider != (Object)null) ? ((Component)((RaycastHit)(ref array[i])).collider).transform : null); if (!((Object)(object)val == (Object)null) && !val.IsChildOf(probe.transform) && !(((RaycastHit)(ref array[i])).point.y > probe.transform.position.y + 0.5f) && (float.IsNaN(num) || ((RaycastHit)(ref array[i])).point.y > num)) { num = ((RaycastHit)(ref array[i])).point.y; } } if (float.IsNaN(num)) { return 0f; } return Mathf.Clamp(probe.transform.position.y - num, 0f, 20f); } internal static void CreateStageWallPairAt(int segmentIndex, GameObject source, Vector3 center, float above, float below, GameObject bottomTemplate = null) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { Plugin.Log.LogWarning((object)string.Format("{0} Segment {1}: keine Wand als Vorlage - kein Trenner.", "[FinalAscent]", segmentIndex)); return; } Vector3 val = center + new Vector3(0f, 0f, above); Vector3 val2 = center + new Vector3(0f, 0f, below); GameObject val3 = (((Object)(object)bottomTemplate != (Object)null) ? bottomTemplate : source); StageWalls[segmentIndex] = new StageWallPair { Top = CloneWall(source, val, "FA_StageWallTop_" + segmentIndex), Bottom = CloneWall(val3, val2, "FA_StageWallBottom_" + segmentIndex) }; Plugin.Detail(string.Format("{0} Trennerpaar {1} um {2}: oben {3} ", "[FinalAscent]", segmentIndex, Fmt(center), Fmt(val)) + "('" + ((Object)source).name + "'), unten " + Fmt(val2) + " ('" + ((Object)val3).name + "')."); } private static GameObject CloneWall(GameObject source, Vector3 position, string name, bool flip = false) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } Quaternion val = (flip ? (source.transform.rotation * Quaternion.Euler(0f, 180f, 0f)) : source.transform.rotation); GameObject val2 = Object.Instantiate(source, position, val); ((Object)val2).name = name; PhotonView[] componentsInChildren = val2.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } val2.transform.SetParent(WallHolder(), true); val2.SetActive(false); return val2; } internal static GameObject FindBiomeRoot(LevelGeneration levelGen, BiomeType type) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)levelGen == (Object)null) { return null; } BiomeSelector[] componentsInChildren = ((Component)levelGen).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { foreach (BiomeOption biome in componentsInChildren[i].Biomes) { if ((Object)(object)biome?.biomeParent != (Object)null && biome.biomeParent.biomeType == type) { return ((Component)biome.biomeParent).gameObject; } } } return null; } private static string Where(Transform of) { string text = ((Object)of).name; Transform parent = of.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private static void ReportConfigSteps(IGenConfigStep[] steps) { Plugin.Log.LogInfo((object)string.Format("{0} {1} GenConfigSteps:", "[FinalAscent]", steps.Length)); foreach (IGenConfigStep val in steps) { Component val2 = (Component)(object)((val is Component) ? val : null); Plugin.Log.LogInfo((object)("[FinalAscent] " + ((object)val).GetType().Name + " auf " + (((Object)(object)val2 != (Object)null) ? Where(val2.transform) : "(kein Objekt)"))); VariationSwapper val3 = (VariationSwapper)(object)((val is VariationSwapper) ? val : null); if (val3 == null || val3.Variations == null) { continue; } Variation[] variations = val3.Variations; foreach (Variation val4 in variations) { if (val4 != null && !((Object)(object)val4.parent == (Object)null)) { Plugin.Log.LogInfo((object)("[FinalAscent] " + (val4.parent.activeSelf ? "AN " : "aus") + " " + $"{((Object)val4.parent).name} (Gewicht {val4.chance:F1})")); } } } } private static void ReportBeachPrefabs(LevelGeneration levelGen) { Transform val = DeepFindPublic(((Component)levelGen).transform, "Beach_Segment"); if ((Object)(object)val == (Object)null) { return; } Dictionary dictionary = new Dictionary(); int num = 0; PropSpawner[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (PropSpawner val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null) { continue; } num++; GameObject[] array = ((val2.overrideProps && (Object)(object)val2.overridePropsList != (Object)null) ? val2.overridePropsList.gameObjects : val2.props); if (array == null) { continue; } GameObject[] array2 = array; foreach (GameObject val3 in array2) { if (!((Object)(object)val3 == (Object)null)) { dictionary.TryGetValue(((Object)val3).name, out var value); dictionary[((Object)val3).name] = value + 1; } } } List> list = new List>(dictionary); list.Sort((KeyValuePair x, KeyValuePair y) => y.Value.CompareTo(x.Value)); Plugin.Log.LogInfo((object)string.Format("{0} Strand: {1} Spawner, {2} verschiedene Vorlagen:", "[FinalAscent]", num, dictionary.Count)); for (int num2 = 0; num2 < list.Count && num2 < 25; num2++) { Plugin.Log.LogInfo((object)string.Format("{0} {1,4}x {2}", "[FinalAscent]", list[num2].Value, list[num2].Key)); } ReportRockPrefabs(val); ReportRockMods(val); } private static void ReportRockPrefabs(Transform beach) { Dictionary dictionary = new Dictionary(); PropSpawner[] componentsInChildren = ((Component)beach).GetComponentsInChildren(true); foreach (PropSpawner val in componentsInChildren) { if ((Object)(object)val == (Object)null || (!((Object)val).name.Contains("Rock") && !((Object)val).name.Contains("Small") && !((Object)val).name.Contains("Medium") && !((Object)val).name.Contains("Foundation"))) { continue; } GameObject[] array = ((val.overrideProps && (Object)(object)val.overridePropsList != (Object)null) ? val.overridePropsList.gameObjects : val.props); if (array == null) { continue; } GameObject[] array2 = array; foreach (GameObject val2 in array2) { if ((Object)(object)val2 == (Object)null || dictionary.ContainsKey(((Object)val2).name)) { continue; } List list = new List(); Renderer[] componentsInChildren2 = val2.GetComponentsInChildren(true); for (int k = 0; k < componentsInChildren2.Length; k++) { Material[] sharedMaterials = componentsInChildren2[k].sharedMaterials; foreach (Material val3 in sharedMaterials) { string item = (((Object)(object)val3 != (Object)null) ? ((Object)val3).name : "(keins)"); if (!list.Contains(item)) { list.Add(item); } } } dictionary[((Object)val2).name] = ((list.Count > 0) ? string.Join(", ", list) : "(keine)"); } } Plugin.Log.LogInfo((object)"[FinalAscent] Was in den Felsvorlagen des Strandes steckt:"); foreach (KeyValuePair item2 in dictionary) { Plugin.Log.LogInfo((object)("[FinalAscent] " + item2.Key + ": " + item2.Value)); } } private static void ReportBeachSurface(LevelGeneration levelGen, string when) { Transform val = DeepFindPublic(((Component)levelGen).transform, "Beach_Segment"); if ((Object)(object)val == (Object)null) { return; } Plugin.Log.LogInfo((object)("[FinalAscent] Untergrund des Strandes, " + when + ":")); string[] array = new string[2] { "Ground", "Wall" }; foreach (string text in array) { Transform val2 = val.Find(text); if ((Object)(object)val2 == (Object)null) { Plugin.Log.LogInfo((object)("[FinalAscent] " + text + ": nicht vorhanden")); continue; } Dictionary dictionary = new Dictionary(); Renderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren.Length; j++) { Material[] sharedMaterials = componentsInChildren[j].sharedMaterials; foreach (Material val3 in sharedMaterials) { string key = (((Object)(object)val3 != (Object)null) ? ((Object)val3).name : "(keins)"); dictionary.TryGetValue(key, out var value); dictionary[key] = value + 1; } } List> list = new List>(dictionary); list.Sort((KeyValuePair x, KeyValuePair y) => y.Value.CompareTo(x.Value)); string text2 = ""; for (int num = 0; num < list.Count && num < 6; num++) { text2 = text2 + ((text2.Length > 0) ? ", " : "") + list[num].Value + "x " + list[num].Key; } Plugin.Log.LogInfo((object)("[FinalAscent] " + text + ": " + text2)); } } private static void ReportRockMods(Transform beach) { Plugin.Log.LogInfo((object)"[FinalAscent] Bearbeitungsschritte an den Strandspawnern:"); PropSpawner[] componentsInChildren = ((Component)beach).GetComponentsInChildren(true); foreach (PropSpawner val in componentsInChildren) { if ((Object)(object)val == (Object)null || val.modifiers == null || val.modifiers.Count == 0) { continue; } List list = new List(); foreach (PropSpawnerMod modifier in val.modifiers) { if (modifier == null) { continue; } string text = ((object)modifier).GetType().Name; List list2 = new List(); FieldInfo[] fields = ((object)modifier).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType == typeof(Material)) { object? value = fieldInfo.GetValue(modifier); Material val2 = (Material)((value is Material) ? value : null); list2.Add(fieldInfo.Name + "=" + (((Object)(object)val2 != (Object)null) ? ((Object)val2).name : "null")); } else { if (!(fieldInfo.FieldType == typeof(Material[]))) { continue; } Material[] array = fieldInfo.GetValue(modifier) as Material[]; List list3 = new List(); if (array != null) { Material[] array2 = array; foreach (Material val3 in array2) { list3.Add(((Object)(object)val3 != (Object)null) ? ((Object)val3).name : "null"); } } list2.Add(fieldInfo.Name + "=[" + string.Join("/", list3) + "]"); } } if (list2.Count > 0) { text = text + "(" + string.Join(", ", list2) + ")"; } list.Add(text); } string text2 = ((Object)val).name; Transform parent = ((Component)val).transform.parent; while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)beach) { text2 = ((Object)parent).name + "/" + text2; parent = parent.parent; } if (list.Count > 0) { Plugin.Log.LogInfo((object)("[FinalAscent] " + text2 + ": " + string.Join(" | ", list))); } } } private static IEnumerator RunGeneration(LevelGeneration levelGen) { FinalAscentSetup.Apply(levelGen); FinalAscentPaint.Snapshot(); IGenConfigStep[] componentsInChildren = ((Component)levelGen).GetComponentsInChildren(); for (int i = 0; i < componentsInChildren.Length; i++) { IGenConfigStep val = componentsInChildren[i]; Component val2 = (Component)(object)((val is Component) ? val : null); string text = ((val2 != null) ? ((Object)val2.gameObject).name : "?"); Component val3 = (Component)(object)((val is Component) ? val : null); if (val3 != null && FinalAscentVoid.Owns(val3.transform)) { Plugin.Detail("[FinalAscent] " + ((object)val).GetType().Name + " auf '" + text + "' uebersprungen - gehoert zum Nichts, das wir nicht bauen."); continue; } try { val.RunStep(); } catch (Exception ex) { Plugin.Log.LogError((object)string.Format("{0} GenConfigStep [{1}] {2} auf '{3}' wirft: {4}", "[FinalAscent]", i, ((object)val).GetType().Name, text, ex)); } } ReportConfigSteps(componentsInChildren); ReportBeachPrefabs(levelGen); ReportBeachSurface(levelGen, "VOR dem Bestuecken"); FinalAscentWallWatch.Start(DeepFindPublic(((Component)levelGen).transform, "Beach_Segment")); MapHandler instance = Singleton.Instance; PropGrouper val4 = (((Object)(object)instance != (Object)null) ? ((Component)instance).GetComponent() : null); if ((Object)(object)val4 == (Object)null) { Plugin.Log.LogError((object)"[FinalAscent] Kein PropGrouper - ohne den bleibt der Berg leer."); yield break; } LightVolume val5 = Object.FindFirstObjectByType(); if ((Object)(object)val5 != (Object)null) { Plugin.Log.LogInfo((object)("[FinalAscent] Lichtgitter unveraendert: Ursprung " + Fmt(val5.gridOffset) + ", " + $"Rasterweite {val5.raySpacing:F2}, " + "Daten " + (((Object)(object)((CompressableLightMap)(ref val5.lightMapData)).Uncompressed != (Object)null) ? "vorhanden" : "FEHLEN") + ", " + $"Vanilla wuerde neu backen: {levelGen.updateLightmap}.")); } FinalAscentSetup.Apply(levelGen); Quiet("Netz-Dinge schlafen legen", FinalAscentGuests.Sleep); Quiet("Nichts schlafen legen", FinalAscentVoid.Sleep); Physics.SyncTransforms(); foreach (object item in FinalAscentFrames.Through(FinalAscentGeneration.Run(val4))) { yield return item; } Quiet("Nichts wieder aufwecken", FinalAscentVoid.Wake); Quiet("Riegel vor dem Nichts melden", FinalAscentVoidGuard.Report); Quiet("Netz-Dinge wieder aufwecken", FinalAscentGuests.Wake); FinishScene(); ReportBeachSurface(levelGen, "NACH dem Bestuecken"); LogChosenVariants(levelGen); FinalAscentSetup.CountWhenDone(levelGen); } internal static void FinishScene() { FinalAscentRockPaintGate.PaintNow(); FinalAscentZones.Realign(); if ((Object)(object)FakeItemManager.Instance != (Object)null) { FakeItemManager.Instance.RefreshList(); } MapHandler instance = Singleton.Instance; if ((Object)(object)instance != (Object)null) { DetectBiomesMethod?.Invoke(instance, null); Plugin.Log.LogInfo((object)("[FinalAscent] Erkannte Biome (in dieser Reihenfolge): " + string.Join(", ", instance.biomes))); } FinalAscentJitterRadar.Begin(); } private static void LogChosenVariants(LevelGeneration levelGen) { //IL_01cb: Unknown result type (might be due to invalid IL or missing references) BiomeSelector[] componentsInChildren = ((Component)levelGen).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { foreach (BiomeOption biome in componentsInChildren[i].Biomes) { if ((Object)(object)biome?.biomeParent == (Object)null || !((Component)biome.biomeParent).gameObject.activeSelf) { continue; } GameObject gameObject = ((Component)biome.biomeParent).gameObject; string text = ""; BiomeVariant[] componentsInChildren2 = gameObject.GetComponentsInChildren(true); foreach (BiomeVariant val in componentsInChildren2) { if (((Component)val).gameObject.activeSelf) { text = text + ((text.Length > 0) ? ", " : "") + ((Object)val).name; } } VariantObject[] componentsInChildren3 = gameObject.GetComponentsInChildren(true); foreach (VariantObject val2 in componentsInChildren3) { if (((Component)val2).gameObject.activeSelf) { text = text + ((text.Length > 0) ? ", " : "") + ((Object)val2).name; } } List list = new List(); componentsInChildren3 = gameObject.GetComponentsInChildren(true); foreach (VariantObject val3 in componentsInChildren3) { list.Add(((Component)val3).gameObject.activeSelf ? ("[" + ((Object)val3).name + "]") : ((Object)val3).name); } if (list.Count > 0) { Plugin.Detail("[FinalAscent] Zur Wahl standen: " + string.Join(", ", list)); } int num = gameObject.GetComponentsInChildren(true).Length; int num2 = gameObject.GetComponentsInChildren(true).Length; Plugin.Log.LogInfo((object)(string.Format("{0} Variante {1}: ", "[FinalAscent]", biome.biomeParent.biomeType) + ((text.Length > 0) ? text : "keine") + " " + $"({num} PropSpawner, {num2} Objekte)")); } } } private static void MoveFogHelpers() { MoveNamedChildren("FogOrigins"); MoveNamedChildren("FogCutouts"); } private static void MoveNamedChildren(string containerName) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_024e: 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_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.Find(containerName); if ((Object)(object)val == (Object)null) { Transform[] array = Resources.FindObjectsOfTypeAll(); foreach (Transform val2 in array) { if (((Object)val2).name == containerName) { Scene scene = ((Component)val2).gameObject.scene; if (((Scene)(ref scene)).IsValid()) { val = ((Component)val2).gameObject; break; } } } } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + containerName + "' nicht gefunden.")); return; } Transform transform = val.transform; string text = ""; for (int j = 0; j < transform.childCount; j++) { text = text + ((text.Length > 0) ? ", " : "") + ((Object)transform.GetChild(j)).name; } Plugin.Detail("[FinalAscent] " + containerName + " enthaelt: " + text); for (int k = 0; k < transform.childCount; k++) { Transform child = transform.GetChild(k); string key = ((Object)child).name.Split(' ')[0]; if (FogChildNames.TryGetValue(key, out var value) && Offsets.TryGetValue(value, out var value2) && !(value2 == Vector3.zero)) { child.position += value2; FogSphereOrigin component = ((Component)child).GetComponent(); if ((Object)(object)component != (Object)null && component.moveOnHeight < 9000f) { float moveOnHeight = component.moveOnHeight; float moveOnForward = component.moveOnForward; component.moveOnHeight += value2.y; component.moveOnForward += value2.z; Plugin.Log.LogInfo((object)(string.Format("{0} Nebelschwelle '{1}' mit {2} versetzt: ", "[FinalAscent]", ((Object)child).name, value) + $"y={moveOnHeight:F0} z={moveOnForward:F0} -> y={component.moveOnHeight:F0} " + $"z={component.moveOnForward:F0}.")); } Plugin.Detail(string.Format("{0} {1}/{2} -> {3} (an {4})", "[FinalAscent]", containerName, ((Object)child).name, Fmt(child.position), value)); } } } private static void MovePeakToCitadel(LevelGeneration levelGen) { GameObject val = FindBiomeRoot(levelGen, (BiomeType)3); GameObject val2 = FindBiomeRoot(levelGen, (BiomeType)8); PeakHandler[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); PeakHandler[] array2 = array; foreach (PeakHandler val3 in array2) { bool num = (Object)(object)val != (Object)null && ((Component)val3).transform.IsChildOf(val.transform); bool flag = (Object)(object)val2 != (Object)null && ((Component)val3).transform.IsChildOf(val2.transform); if (num) { int num2 = ((Component)val3).GetComponentsInChildren(true).Length; Plugin.Detail(string.Format("{0} Kiln-Gipfel '{1}' wird geloescht ({2} Objekte).", "[FinalAscent]", ((Object)val3).name, num2)); Object.DestroyImmediate((Object)(object)((Component)val3).gameObject); } else if (flag) { Plugin.Detail("[FinalAscent] Zitadellen-Gipfel '" + ((Object)val3).name + "' wird der aktive."); } else { Plugin.Detail("[FinalAscent] Gipfel '" + ((Object)val3).name + "' gehoert zu keinem der beiden Bloecke."); } } if (array.Length == 0) { Plugin.Log.LogWarning((object)"[FinalAscent] Kein PeakHandler gefunden - der Gipfel bleibt, wo er ist."); } ReleaseSingleton(); } private static void ReleaseSingleton() where T : Singleton { FieldInfo fieldInfo = AccessTools.Field(typeof(Singleton), "_instance"); if (fieldInfo == null) { Plugin.Log.LogWarning((object)("[FinalAscent] Singleton-Feld fuer " + typeof(T).Name + " nicht gefunden.")); return; } object value = fieldInfo.GetValue(null); fieldInfo.SetValue(null, null); string[] obj = new string[5] { "[FinalAscent] Singleton ", typeof(T).Name, " freigegeben (vorher: ", null, null }; Object val = (Object)((value is Object) ? value : null); obj[3] = ((val != null && val != (Object)null) ? val.name : "keiner"); obj[4] = ")."; Plugin.Detail(string.Concat(obj)); } private static void ProbeSeams(LevelGeneration levelGen) { ProbeSeam(levelGen, (BiomeType)1, (BiomeType)7); ProbeSeam(levelGen, (BiomeType)2, (BiomeType)6); } internal static Vector3 KilnSummit() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (!_measuredSummit.HasValue) { return KilnSummitPoint(); } return _measuredSummit.Value; } internal static void MeasureSummitAndFollow(LevelGeneration levelGen) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_015c: 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_005e: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) _measuredSummit = null; GameObject val = FindBiomeRoot(levelGen, (BiomeType)3); if ((Object)(object)val == (Object)null) { return; } Vector3 val2 = KilnSummitPoint(); List list = new List(); float[] array = new float[3] { -4f, 0f, 4f }; float[] array2 = array; foreach (float num in array2) { float[] array3 = array; foreach (float num2 in array3) { Vector3 probe = val2 + new Vector3(num, 0f, num2); float num3 = GroundHeight(val, probe); if (!float.IsNaN(num3)) { list.Add(num3); } } } if (list.Count < 3) { Plugin.Log.LogWarning((object)(string.Format("{0} Kuppe des Kiln nicht messbar ({1} Treffer) - Nennhoehe ", "[FinalAscent]", list.Count) + $"{val2.y:F1} bleibt.")); return; } list.Sort(); float num4 = list[list.Count / 2]; _measuredSummit = new Vector3(val2.x, num4, val2.z); float num5 = num4 - val2.y; Plugin.Log.LogInfo((object)(string.Format("{0} Kuppe des Kiln bei {1:F1} gemessen ({2} Treffer), ", "[FinalAscent]", num4, list.Count) + $"Nennwert {val2.y:F1}, Abweichung {num5:F1}.")); if (!(Mathf.Abs(num5) < 0.5f)) { if (Mathf.Abs(num5) > 200f) { Plugin.Log.LogWarning((object)string.Format("{0} Abweichung {1:F1} ist unplausibel gross - Gloom bleibt, wo er ist.", "[FinalAscent]", num5)); _measuredSummit = null; } else { ShiftFrom((BiomeType)8, new Vector3(0f, num5, 0f)); } } } internal static string SummitNote() { //IL_0017: 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) if (!_measuredSummit.HasValue) { return "x"; } return _measuredSummit.Value.y.ToString("R", CultureInfo.InvariantCulture); } internal static void AdoptSummit(string note) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) _measuredSummit = null; if (string.IsNullOrEmpty(note) || note == "x") { Plugin.Log.LogInfo((object)"[FinalAscent] Im Manifest steht keine Kuppen-Messung - Nennhoehe bleibt."); return; } if (!float.TryParse(note, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { Plugin.Log.LogWarning((object)("[FinalAscent] Kuppen-Wert '" + note + "' unlesbar - Nennhoehe bleibt.")); return; } Vector3 val = KilnSummitPoint(); _measuredSummit = new Vector3(val.x, result, val.z); float num = result - val.y; Plugin.Log.LogInfo((object)(string.Format("{0} Kuppe des Kiln aus dem Image: {1:F1} (Host-Messung), ", "[FinalAscent]", result) + $"Nennwert {val.y:F1}, Abweichung {num:F1}.")); if (!(Mathf.Abs(num) < 0.5f) && !(Mathf.Abs(num) > 200f)) { ShiftFrom((BiomeType)8, new Vector3(0f, num, 0f)); } } private static Vector3 KilnSummitPoint() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) return new Vector3(0f, 1187.7f, 2134.5f) + CalderaOffset + KilnCampfireShift; } internal static Vector3 FindFlatSpot(GameObject terrain, Vector3 center, Vector3 preferred, List taken, float minGap) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) GameObject terrain2 = terrain; Biome val = (((Object)(object)terrain != (Object)null) ? terrain.GetComponentInParent(true) : null); if ((Object)(object)val != (Object)null) { terrain2 = ((Component)val).gameObject; } List list = new List { center + preferred }; float[] array = new float[6] { 2f, 3f, 4f, 5f, 6.5f, 8f }; foreach (float num in array) { for (int j = 0; j < 12; j++) { float num2 = (float)j * 30f * (MathF.PI / 180f); list.Add(center + new Vector3(Mathf.Cos(num2), 0f, Mathf.Sin(num2)) * num); } } Vector3 val2 = center + preferred; Vector3 val3 = val2; float num3 = float.MaxValue; float num4 = 0f; bool flag = false; foreach (Vector3 item in list) { bool flag2 = false; foreach (Vector3 item2 in taken) { Vector3 val4 = item2 - item; if (((Vector3)(ref val4)).sqrMagnitude < minGap * minGap) { flag2 = true; break; } } if (flag2) { continue; } Vector3 val5 = SnapToGround(terrain2, item); if (!Mathf.Approximately(val5.y, item.y)) { float num5 = Mathf.Abs(val5.y - center.y); float num6 = Vector2.Distance(new Vector2(val5.x, val5.z), new Vector2(val2.x, val2.z)); float num7 = num5 + num6 * 0.25f; if (num7 < num3) { num3 = num7; val3 = val5; num4 = val5.y - center.y; flag = true; } } } if (!flag) { Plugin.Log.LogWarning((object)("[FinalAscent] Nirgends Boden neben " + Fmt(center) + " - Hoehe des Feuers gilt.")); } else { Plugin.Detail(string.Format("{0} Platz {1}, {2:F1} unter dem Feuer, ", "[FinalAscent]", Fmt(val3), num4) + $"{Vector2.Distance(new Vector2(val3.x, val3.z), new Vector2(center.x, center.z)):F1} daneben."); } taken.Add(val3); return val3; } internal static Vector3 SnapToGround(GameObject terrain, Vector3 point, float tolerance = 0f) { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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) if ((Object)(object)terrain == (Object)null) { return point; } bool activeSelf = terrain.activeSelf; terrain.SetActive(true); Physics.SyncTransforms(); RaycastHit[] array = Physics.RaycastAll(point + Vector3.up * 300f, Vector3.down, 900f, -1, (QueryTriggerInteraction)1); float num = float.NaN; for (int i = 0; i < array.Length; i++) { Transform val = (((Object)(object)((RaycastHit)(ref array[i])).collider != (Object)null) ? ((Component)((RaycastHit)(ref array[i])).collider).transform : null); if (!((Object)(object)val == (Object)null) && val.IsChildOf(terrain.transform) && (float.IsNaN(num) || ((RaycastHit)(ref array[i])).point.y > num)) { num = ((RaycastHit)(ref array[i])).point.y; } } terrain.SetActive(activeSelf); Physics.SyncTransforms(); if (float.IsNaN(num)) { Plugin.Log.LogWarning((object)("[FinalAscent] Kein Boden unter " + Fmt(point) + " in '" + ((Object)terrain).name + "' - Punkt bleibt, wo er ist.")); return point; } if (tolerance > 0f && Mathf.Abs(num - point.y) > tolerance) { Plugin.Detail(string.Format("{0} Boden bei {1:F1} liegt {2:F0} von ", "[FinalAscent]", num, Mathf.Abs(num - point.y)) + $"{point.y:F1} entfernt - eingemessene Hoehe bleibt."); return point; } return new Vector3(point.x, num, point.z); } private static void ResetOffsets() { //IL_0039: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0070: Unknown result type (might be due to invalid IL or missing references) if (_pristineOffsets == null) { _pristineOffsets = new Dictionary(Offsets); return; } List list = new List(); foreach (KeyValuePair pristineOffset in _pristineOffsets) { if (Offsets.TryGetValue(pristineOffset.Key, out var value) && value != pristineOffset.Value) { list.Add($"{pristineOffset.Key} {Fmt(value)} -> {Fmt(pristineOffset.Value)}"); } Offsets[pristineOffset.Key] = pristineOffset.Value; } if (list.Count > 0) { Plugin.Log.LogInfo((object)("[FinalAscent] Versaetze auf den Urzustand zurueckgesetzt - der vorige Aufbau " + string.Format("hatte {0} nachgemessen: {1}.", list.Count, string.Join(", ", list)))); } } internal unsafe static void ShiftFrom(BiomeType from, Vector3 shift) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Invalid comparison between Unknown and I4 //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Invalid comparison between Unknown and I4 //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) LevelGeneration val = Object.FindFirstObjectByType(); if ((Object)(object)val == (Object)null) { return; } BiomeType[] array = new BiomeType[7]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); BiomeType[] array2 = (BiomeType[])(object)array; int num = Array.IndexOf(array2, from); if ((int)from == 3) { Plugin.Log.LogWarning((object)"[FinalAscent] Der Caldera-Block bleibt, wo er ist - er haengt am eingemessenen Gipfel-Lagerfeuer. Justiere stattdessen Gloom."); return; } if (num < 0) { Plugin.Log.LogWarning((object)string.Format("{0} {1} laesst sich nicht verschieben (Shore und Tropics liegen fest).", "[FinalAscent]", from)); return; } List list = new List(); List list2 = new List(); Bounds item = default(Bounds); for (int i = num; i < array2.Length; i++) { BiomeType val2 = array2[i]; if (Offsets.ContainsKey(val2)) { Dictionary offsets = Offsets; BiomeType key = val2; offsets[key] += shift; } if ((int)val2 == 5 || (int)val2 == 9) { continue; } GameObject val3 = FindBiomeRoot(val, val2); if ((Object)(object)val3 != (Object)null) { ((Bounds)(ref item))..ctor(val3.transform.position, Vector3.zero); Transform[] componentsInChildren = val3.GetComponentsInChildren(true); foreach (Transform val4 in componentsInChildren) { ((Bounds)(ref item)).Encapsulate(val4.position); } ((Bounds)(ref item)).Expand(10f); list.Add(item); list2.Add(val3.transform); Transform transform = val3.transform; transform.position += shift; } } if (list.Count > 0 && (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient)) { int num2 = 0; int num3 = 0; Item[] array3 = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Item val5 in array3) { if ((Object)(object)val5 == (Object)null || (int)val5.itemState != 0) { continue; } Transform transform2 = ((Component)val5).transform; bool flag = false; foreach (Transform item2 in list2) { if (transform2.IsChildOf(item2)) { flag = true; break; } } if (flag) { continue; } foreach (Bounds item3 in list) { Bounds current2 = item3; if (!((Bounds)(ref current2)).Contains(transform2.position)) { continue; } transform2.position += shift; Rigidbody component = ((Component)val5).GetComponent(); if ((Object)(object)component != (Object)null && !component.isKinematic) { component.position = transform2.position; } if (PhotonNetwork.InRoom && (Object)(object)((MonoBehaviourPun)val5).photonView != (Object)null) { try { ((MonoBehaviourPun)val5).photonView.RPC("SetKinematicRPC", (RpcTarget)3, new object[3] { (Object)(object)component == (Object)null || component.isKinematic, transform2.position, transform2.rotation }); num3++; } catch (Exception ex) { Plugin.Detail("[FinalAscent] '" + ((Object)val5).name + "' liess sich nicht melden: " + ex.Message); } } num2++; break; } } if (num2 > 0) { Plugin.Log.LogInfo((object)(string.Format("{0} {1} frei liegende Gegenstaende sind mit dem ", "[FinalAscent]", num2) + $"Block um {Fmt(shift)} mitgewandert, {num3} davon den anderen " + "Rechnern gemeldet. Ohne die Meldung lagen sie nur beim Host richtig - beim Gast blieben sie 0,6 tiefer im Boden.")); } } Physics.SyncTransforms(); RefreshWeatherBounds(); string text = ""; BiomeType[] array4 = array2; for (int j = 0; j < array4.Length; j++) { BiomeType key2 = array4[j]; text = text + ((text.Length > 0) ? " " : "") + ((object)(*(BiomeType*)(&key2))/*cast due to .constrained prefix*/).ToString() + "=" + Fmt(Offsets[key2]); } Plugin.Log.LogInfo((object)string.Format("{0} Versatz ab {1} um {2} geaendert. Stand: {3}", "[FinalAscent]", from, Fmt(shift), text)); } internal static void RefreshWeatherBounds() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) WindChillZone[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); WindChillZone[] array2 = array; foreach (WindChillZone val in array2) { Vector3 center = ((Bounds)(ref val.windZoneBounds)).center; ((Bounds)(ref val.windZoneBounds)).center = ((Component)val).transform.position; Plugin.Detail("[FinalAscent] Wetterzone '" + ((Object)val).name + "': Mitte " + Fmt(center) + " -> " + Fmt(((Bounds)(ref val.windZoneBounds)).center) + ", Groesse " + Fmt(((Bounds)(ref val.windZoneBounds)).size)); } if (array.Length == 0) { Plugin.Log.LogWarning((object)"[FinalAscent] Keine WindChillZone gefunden - Wetter bleibt wie es ist."); } RefreshWindHeights(); } private static void RefreshWindHeights() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) WindHeightEffect[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (WindHeightEffect val in array) { if (!WindHeightOriginals.TryGetValue(val, out var value)) { ((Vector2)(ref value))..ctor(val.fromHeight, val.toHeight); WindHeightOriginals[val] = value; } Biome componentInParent = ((Component)val).GetComponentInParent(true); Vector3 value2; float num = (((Object)(object)componentInParent != (Object)null && Offsets.TryGetValue(componentInParent.biomeType, out value2)) ? value2.y : 0f); val.fromHeight = value.x + num; val.toHeight = value.y + num; Plugin.Detail(string.Format("{0} Sturmhoehe '{1}': {2:F0}-{3:F0} -> ", "[FinalAscent]", ((Object)val).name, value.x, value.y) + $"{val.fromHeight:F0}-{val.toHeight:F0}"); } } private static float ProbeSeam(LevelGeneration levelGen, BiomeType lower, BiomeType upper) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) GameObject val = FindBiomeRoot(levelGen, lower); GameObject val2 = FindBiomeRoot(levelGen, upper); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return float.NaN; } Campfire componentInChildren = val.GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { Plugin.Log.LogWarning((object)string.Format("{0} Kein Lagerfeuer in {1} - Nahtstelle nicht messbar.", "[FinalAscent]", lower)); return float.NaN; } Vector3 position = ((Component)componentInChildren).transform.position; Plugin.Log.LogInfo((object)string.Format("{0} Nahtstelle {1} -> {2}, Anker {3}:", "[FinalAscent]", lower, upper, Fmt(position))); float[] array = new float[5] { -35f, -15f, 0f, 15f, 35f }; List list = new List(); float[] array2 = array; foreach (float num in array2) { float[] array3 = array; foreach (float num2 in array3) { list.Add(position + new Vector3(num, 0f, num2)); } } bool activeSelf = val.activeSelf; bool activeSelf2 = val2.activeSelf; float[] array4 = MeasureAll(val, val2, list); float[] array5 = MeasureAll(val2, val, list); val.SetActive(activeSelf); val2.SetActive(activeSelf2); Physics.SyncTransforms(); List list2 = new List(); for (int k = 0; k < list.Count; k++) { if (!float.IsNaN(array4[k]) && !float.IsNaN(array5[k])) { list2.Add(array5[k] - array4[k]); } } if (list2.Count < 3) { Plugin.Log.LogWarning((object)string.Format("{0} Nur {1} brauchbare Messpunkte von {2}.", "[FinalAscent]", list2.Count, list.Count)); return float.NaN; } list2.Sort(); float num3 = list2[list2.Count / 2]; Plugin.Detail(string.Format("{0} {1} von {2} Messpunkten brauchbar, Median {3:F1} ", "[FinalAscent]", list2.Count, list.Count, num3) + $"({upper} liegt um so viel hoeher als {lower}; negativ heisst zu tief)."); return num3; } private static float[] MeasureAll(GameObject wanted, GameObject other, List probes) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) wanted.SetActive(true); other.SetActive(false); Physics.SyncTransforms(); float[] array = new float[probes.Count]; for (int i = 0; i < probes.Count; i++) { array[i] = GroundHeight(wanted, probes[i]); } return array; } private static float GroundHeight(GameObject wanted, Vector3 probe) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) RaycastHit[] array = Physics.RaycastAll(probe + Vector3.up * 600f, Vector3.down, 1800f, -1, (QueryTriggerInteraction)1); float num = float.NaN; for (int i = 0; i < array.Length; i++) { Transform val = (((Object)(object)((RaycastHit)(ref array[i])).collider != (Object)null) ? ((Component)((RaycastHit)(ref array[i])).collider).transform : null); if (!((Object)(object)val == (Object)null) && val.IsChildOf(wanted.transform) && (float.IsNaN(num) || ((RaycastHit)(ref array[i])).point.y > num)) { num = ((RaycastHit)(ref array[i])).point.y; } } return num; } internal static string Fmt(Vector3 v) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) return $"({v.x:F1} / {v.y:F1} / {v.z:F1})"; } } [HarmonyPatch(typeof(PointAtObject), "OnLevelGenFinished")] internal static class FinalAscentPointAtObjectPatch { private static Exception Finalizer(Exception __exception, PointAtObject __instance) { if (__exception == null || !FinalAscent.Active) { return __exception; } Plugin.Log.LogWarning((object)("[FinalAscent] '" + (((Object)(object)__instance != (Object)null) ? ((Object)__instance).name : "?") + "' konnte sich nicht ausrichten (" + __exception.GetType().Name + ") - uebersprungen, die Generierung laeuft weiter.")); return null; } } [HarmonyPatch(typeof(MapHandler), "InitializeMap")] internal static class FinalAscentInitializeMapPatch { private static bool _letThrough; internal static bool Suppressed { get; private set; } [HarmonyPriority(800)] private static bool Prefix() { if (_letThrough) { _letThrough = false; Suppressed = false; return true; } FinalAscentRoom.Adopt(); if (!FinalAscent.Active) { if (PhotonNetwork.IsConnected && !PhotonNetwork.InRoom && (Object)(object)Plugin.Instance != (Object)null) { Plugin.Log.LogInfo((object)"[FinalAscent] Karte wird eingerichtet, aber der Raum steht noch nicht - es wird gewartet, bevor entschieden wird."); FinalAscentBuilder.Expect(); Suppressed = true; ((MonoBehaviour)Plugin.Instance).StartCoroutine(DecideWhenRoomIsKnown()); return false; } return true; } if (FinalAscentBuilder.Building) { Plugin.Log.LogWarning((object)"[FinalAscent] InitializeMap kam ein zweites Mal, waehrend der Berg noch gebaut wird - der zweite Ruf wird verworfen."); Suppressed = true; return false; } if ((Object)(object)Plugin.Instance == (Object)null) { Plugin.Log.LogWarning((object)"[FinalAscent] Kein Traeger fuer die Coroutine - der Berg wird am Stueck gebaut. Das Fenster reagiert waehrenddessen nicht."); FinalAscentBuilder.Expect(); DrainDeep(FinalAscentBuilder.BuildRoutine()); FinalAscentBuilder.MarkReady(); return true; } FinalAscentBuilder.Expect(); Suppressed = true; ((MonoBehaviour)Plugin.Instance).StartCoroutine(BuildThenInitialize()); return false; } private static void DrainDeep(IEnumerator routine) { Stack stack = new Stack(); stack.Push(routine); while (stack.Count > 0) { IEnumerator enumerator = stack.Peek(); if (!enumerator.MoveNext()) { stack.Pop(); } else if (enumerator.Current is IEnumerator item) { stack.Push(item); } } } private static IEnumerator DecideWhenRoomIsKnown() { float waited = 0f; while (waited < 30f) { if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null) { FinalAscentRoom.Adopt(); if (FinalAscent.Active) { Plugin.Log.LogInfo((object)($"[FinalAscent] Raum steht nach {waited:F1}s - es IST ein " + "Finaler Aufstieg, der Berg wird gebaut.")); foreach (object item in FinalAscentFrames.Through(BuildThenInitialize())) { yield return item; } yield break; } Plugin.Log.LogInfo((object)($"[FinalAscent] Raum steht nach {waited:F1}s - kein Aufstieg, " + "die Karte wird normal eingerichtet.")); break; } waited += Time.unscaledDeltaTime; yield return null; } if (waited >= 30f) { Plugin.Log.LogWarning((object)"[FinalAscent] Nach dreissig Sekunden immer noch kein Raum - die Karte wird normal eingerichtet."); } FinalAscentBuilder.Cancel(); FinalAscentLoadHud.Hide(); Suppressed = false; _letThrough = true; try { MapHandler.InitializeMap(); } catch (Exception arg) { Plugin.Log.LogError((object)$"[FinalAscent] InitializeMap wirft: {arg}"); } finally { _letThrough = false; } } private static IEnumerator BuildThenInitialize() { foreach (object item in FinalAscentFrames.Through(FinalAscentBuilder.BuildRoutine())) { yield return item; } try { Suppressed = false; _letThrough = true; MapHandler.InitializeMap(); FinalAscentSoftLanding.Begin(); } catch (Exception arg) { Plugin.Log.LogError((object)$"[FinalAscent] Nach dem Aufbau ist etwas schiefgegangen: {arg}"); } finally { _letThrough = false; FinalAscentBuilder.MarkBuilt(); } try { MountainProgressHandler instance = Singleton.Instance; if ((Object)(object)instance != (Object)null) { FinalAscentProgressOrderPatch.Rebuild(instance); FinalAscentStuckWatch.Begin(); FinalAscentItems.ReportLater(); FinalAscentJumpGate.ReplayIfStashed(); int stage = FinalAscentRoom.Stage; if (stage >= 0 && !FinalAscentSegments.RestoreToStage(stage)) { Plugin.Log.LogError((object)($"[FinalAscent] Der Etappenstand {stage} liess sich nach dem Aufbau " + "NICHT herstellen. Der Berg steht jetzt vollstaendig sichtbar da und weicht damit von der Gruppe ab.")); } FinalAscentSegments.MarkFogRevealed(); } else { Plugin.Log.LogWarning((object)"[FinalAscent] Fortschrittspunkte konnten nicht nachgeholt werden - die Biom-Titel bleiben unvollstaendig."); } } catch (Exception arg2) { Plugin.Log.LogError((object)$"[FinalAscent] Fortschrittspunkte wirft: {arg2}"); } finally { FinalAscentBuilder.MarkReady(); } } } internal static class FinalAscentCamps { private const string Tag = "[FinalAscent]"; private static readonly List Lit = new List(); internal static Campfire Last { get { for (int num = Lit.Count - 1; num >= 0; num--) { if ((Object)(object)Lit[num] != (Object)null) { return Lit[num]; } } return null; } } internal static Campfire Previous { get { bool flag = false; for (int num = Lit.Count - 1; num >= 0; num--) { if (!((Object)(object)Lit[num] == (Object)null)) { if (flag) { return Lit[num]; } flag = true; } } return null; } } internal static Campfire BaseCamp { get { Campfire last = Last; if ((Object)(object)last == (Object)null) { return null; } Campfire previous = Previous; if (!((Object)(object)previous != (Object)null) || last.EveryoneInRange()) { return last; } return previous; } } internal static void Reset() { Lit.Clear(); } internal static void NoteLit(Campfire fire) { if (!((Object)(object)fire == (Object)null)) { Lit.Remove(fire); Lit.Add(fire); } } internal static bool BaseCampIsSafe(out string why) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_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_005c: Unknown result type (might be due to invalid IL or missing references) Campfire baseCamp = BaseCamp; if ((Object)(object)baseCamp == (Object)null) { why = "kein angezuendetes Lagerfeuer"; return true; } Segment currentSegmentNumber = MapHandler.CurrentSegmentNumber; foreach (LavaRising item in LavaRising.ALL_LAVA) { if ((Object)(object)item != (Object)null && item.started && !item.ended && item.requiredSegment == currentSegmentNumber) { why = $"{item.risingFieldType} '{((Object)item).name}' steigt bereits"; return false; } } if (OrbFogHandler.IsFoggingCurrentSegment && !baseCamp.EveryoneInRange()) { why = "Nebel zieht und nicht alle sind am Feuer"; return false; } why = "frei"; return true; } internal static RespawnChest StatueAtBaseCamp() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) Campfire baseCamp = BaseCamp; if ((Object)(object)baseCamp == (Object)null) { return null; } RespawnChest result = null; float num = float.MaxValue; RespawnChest[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (RespawnChest val in array) { if (!((Object)(object)val == (Object)null)) { float num2 = Vector3.Distance(((Component)val).transform.position, ((Component)baseCamp).transform.position); if (num2 < num) { num = num2; result = val; } } } if (!(num < 60f)) { return null; } return result; } } [HarmonyPatch(typeof(MapHandler), "get_CurrentBaseCampSpawnPoint")] internal static class FinalAscentBaseCampPatch { private static bool Prefix(ref Transform __result) { if (!FinalAscent.Active || VoidBiome.VoidBiomeActive) { return true; } Campfire baseCamp = FinalAscentCamps.BaseCamp; if ((Object)(object)baseCamp == (Object)null) { return true; } __result = ((Component)baseCamp).transform; return false; } } [HarmonyPatch(typeof(MapHandler), "get_LastSeenCampfireIsSafe")] internal static class FinalAscentCampfireSafePatch { private static bool Prefix(ref bool __result) { if (!FinalAscent.Active || VoidBiome.VoidBiomeActive) { return true; } __result = FinalAscentCamps.BaseCampIsSafe(out var why); Plugin.Log.LogInfo((object)("[FinalAscent] Lager am Feuer '" + (((Object)(object)FinalAscentCamps.BaseCamp != (Object)null) ? ((Object)FinalAscentCamps.BaseCamp).name : "-") + "': " + (__result ? "sicher" : "TOEDLICH") + " (" + why + ").")); return false; } } [HarmonyPatch(typeof(MapHandler), "get_BaseCampScoutStatue")] internal static class FinalAscentBaseCampStatuePatch { private static void Postfix(ref RespawnChest __result) { if (FinalAscent.Active && !((Object)(object)__result != (Object)null) && !VoidBiome.VoidBiomeActive) { __result = FinalAscentCamps.StatueAtBaseCamp(); Plugin.Log.LogInfo((object)("[FinalAscent] Vanilla kannte keine Truhe am Lager; genommen: '" + (((Object)(object)__result != (Object)null) ? ((Object)__result).name : "immer noch keine") + "'.")); } } } internal sealed class FinalAscentCaret : MonoBehaviour { private const float Width = 5f; private TMP_InputField _field; private TMP_Text _text; private RectTransform _bar; internal static void Attach(TMP_InputField field, Color color) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) FinalAscentCaret finalAscentCaret = ((Component)field).gameObject.AddComponent(); finalAscentCaret._field = field; finalAscentCaret._text = field.textComponent; GameObject obj = FinalAscentUiKit.Node("Caret", field.textComponent.transform); RectTransform val = FinalAscentUiKit.Rect(obj); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); val.anchorMax = val2; val.anchorMin = val2; val.pivot = new Vector2(0f, 0.5f); val.sizeDelta = new Vector2(5f, 0f); Image obj2 = obj.AddComponent(); ((Graphic)obj2).color = color; ((Graphic)obj2).raycastTarget = false; finalAscentCaret._bar = val; obj.SetActive(false); } private void Update() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_field == (Object)null || (Object)(object)_bar == (Object)null || (Object)(object)_text == (Object)null) { return; } if (!_field.isFocused || !((Selectable)_field).interactable) { if (((Component)_bar).gameObject.activeSelf) { ((Component)_bar).gameObject.SetActive(false); } return; } ((Transform)_bar).localPosition = new Vector3(CaretX(), 0f, 0f); float num = _text.fontSize * 1.15f; if (!Mathf.Approximately(_bar.sizeDelta.y, num)) { _bar.sizeDelta = new Vector2(5f, num); } bool flag = Mathf.Repeat(Time.unscaledTime, 1f) < 0.6f; if (((Component)_bar).gameObject.activeSelf != flag) { ((Component)_bar).gameObject.SetActive(flag); } } private float CaretX() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) TMP_TextInfo textInfo = _text.textInfo; int num = textInfo?.characterCount ?? 0; if (num <= 0) { Rect rect = _text.rectTransform.rect; return ((Rect)(ref rect)).xMin + _text.margin.x; } int num2 = Mathf.Clamp(_field.caretPosition, 0, num); if (num2 < num) { return textInfo.characterInfo[num2].origin; } return textInfo.characterInfo[num - 1].xAdvance; } } internal static class FinalAscentColdNight { private const string Tag = "[FinalAscent]"; private static int _told = int.MinValue; internal static int Reached(MountainProgressHandler handler) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected I4, but got Unknown int num = (((Object)(object)handler != (Object)null) ? handler.maxProgressPointReached : 0); if (!FinalAscent.Active) { return num; } try { if ((Object)(object)Singleton.Instance == (Object)null) { return num; } int num2 = (int)MapHandler.CurrentSegmentNumber; if (num2 != _told) { _told = num2; Plugin.Detail(string.Format("{0} Kalte Nacht rechnet jetzt in Segmenten: {1} ", "[FinalAscent]", num2) + "(Vanillas Schwelle 3 = ab der Caldera, also ab dem " + $"Mesa-Lagerfeuer). Punktindex waere {num} gewesen."); } return num2; } catch { return num; } } } [HarmonyPatch(typeof(CharacterAfflictions), "UpdateNormalStatuses")] internal static class FinalAscentColdNightPatch { private const string Tag = "[FinalAscent]"; private static IEnumerable Transpiler(IEnumerable code) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown List list = new List(code); MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(MountainProgressHandler), "maxProgressPointReached"); MethodInfo methodInfo2 = AccessTools.Method(typeof(FinalAscentColdNight), "Reached", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { Plugin.Log.LogWarning((object)"[FinalAscent] Kalte Nacht: Abfrage nicht gefunden - es bleibt bei Vanillas Schwelle."); return list; } List list2 = new List(list.Count); int num = 0; foreach (CodeInstruction item in list) { if (CodeInstructionExtensions.Calls(item, methodInfo)) { num++; list2.Add(new CodeInstruction(OpCodes.Call, (object)methodInfo2)); } else { list2.Add(item); } } if (num != 1) { Plugin.Log.LogWarning((object)(string.Format("{0} Kalte Nacht: 'maxProgressPointReached' kommt {1}x vor, ", "[FinalAscent]", num) + "erwartet war genau einmal - nichts geaendert, es bleibt bei Vanillas Schwelle.")); return list; } Plugin.Log.LogInfo((object)"[FinalAscent] Kalte Nacht endet am Mesa-Lagerfeuer: die Schwelle rechnet jetzt in Segmenten statt in Fortschrittspunkten. Vanillas '< 3' meint damit wieder 'vor der Caldera' - bei zehn Punkten statt fuenf hiess dieselbe 3 vorher 'vor Alpine'."); return list2; } } internal static class FinalAscentColliderCensus { private const string Tag = "[FinalAscent]"; private static string FilePath => FinalAscentStore.Note("TrueFinalAscent.Kollider.txt"); private static void TakeRenderers() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) try { List list = new List(45000); Renderer[] array = Object.FindObjectsByType((FindObjectsSortMode)0); foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null) && val.enabled && ((Component)val).gameObject.activeInHierarchy) { Bounds bounds = val.bounds; Vector3 center = ((Bounds)(ref bounds)).center; list.Add(PathOf(((Component)val).transform) + ";" + ((object)val).GetType().Name + ";" + center.x.ToString("F2", CultureInfo.InvariantCulture) + "," + center.y.ToString("F2", CultureInfo.InvariantCulture) + "," + center.z.ToString("F2", CultureInfo.InvariantCulture)); } } list.Sort(StringComparer.Ordinal); if (!Plugin.Diagnosing) { Plugin.Log.LogInfo((object)string.Format("{0} {1} sichtbare Renderer gezaehlt.", "[FinalAscent]", list.Count)); return; } File.WriteAllLines(FinalAscentStore.Note("TrueFinalAscent.Renderer.txt"), list); Plugin.Log.LogInfo((object)(string.Format("{0} {1} sichtbare Renderer aufgeschrieben ", "[FinalAscent]", list.Count) + "(TrueFinalAscent.Renderer.txt).")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Renderer-Liste nicht abgelegt: " + ex.Message)); } } internal static void TakeAndCompare() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //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) TakeRenderers(); List list = new List(45000); Collider[] array = Object.FindObjectsByType((FindObjectsSortMode)0); foreach (Collider val in array) { if (!((Object)(object)val == (Object)null) && val.enabled) { Bounds bounds = val.bounds; Vector3 center = ((Bounds)(ref bounds)).center; list.Add(PathOf(((Component)val).transform) + ";" + ((object)val).GetType().Name + ";" + center.x.ToString("F2", CultureInfo.InvariantCulture) + "," + center.y.ToString("F2", CultureInfo.InvariantCulture) + "," + center.z.ToString("F2", CultureInfo.InvariantCulture)); } } list.Sort(StringComparer.Ordinal); List list2 = null; try { if (!Plugin.Diagnosing) { return; } if (File.Exists(FilePath)) { list2 = new List(File.ReadAllLines(FilePath)); File.Copy(FilePath, Path.ChangeExtension(FilePath, null) + ".vorher.txt", overwrite: true); } File.WriteAllLines(FilePath, list); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Kollider-Inventur nicht speicherbar: " + ex.Message)); } if (list2 == null) { Plugin.Log.LogInfo((object)(string.Format("{0} Kollider-Inventur: {1} aktive Kollider aufgeschrieben. ", "[FinalAscent]", list.Count) + "Der naechste Lauf nennt die Unterschiede namentlich.")); return; } Dictionary dictionary = new Dictionary(StringComparer.Ordinal); foreach (string item in list2) { dictionary.TryGetValue(item, out var value); dictionary[item] = value + 1; } foreach (string item2 in list) { dictionary.TryGetValue(item2, out var value2); dictionary[item2] = value2 - 1; } List list3 = new List(); List list4 = new List(); foreach (KeyValuePair item3 in dictionary) { if (item3.Value > 0) { list3.Add($"{item3.Value,6}x {item3.Key}"); } else if (item3.Value < 0) { list4.Add($"{-item3.Value,6}x {item3.Key}"); } } if (list3.Count == 0 && list4.Count == 0) { Plugin.Log.LogInfo((object)("[FinalAscent] Kollider-Inventur: Ausgangslage identisch mit dem vorigen Lauf " + $"({list.Count} aktive Kollider).")); return; } Plugin.Log.LogWarning((object)("[FinalAscent] KOLLIDER-INVENTUR: Ausgangslage weicht vom vorigen Lauf ab - " + $"{list3.Count} Pfade nur damals, {list4.Count} nur jetzt " + $"({list2.Count} -> {list.Count} gesamt). Das ist der Unterschied, der den " + "ersten Streifschuss kippt:")); Name("nur im VORIGEN Lauf", list3); Name("nur JETZT", list4); } private static void Name(string what, List lines) { if (lines.Count != 0) { lines.Sort(StringComparer.Ordinal); lines.Reverse(); Plugin.Log.LogWarning((object)string.Format("{0} {1} ({2} Pfade):", "[FinalAscent]", what, lines.Count)); for (int i = 0; i < lines.Count && i < 40; i++) { Plugin.Log.LogWarning((object)("[FinalAscent] " + lines[i])); } if (lines.Count > 40) { Plugin.Log.LogWarning((object)string.Format("{0} ... und {1} weitere.", "[FinalAscent]", lines.Count - 40)); } } } private static string PathOf(Transform leaf) { StringBuilder stringBuilder = new StringBuilder(((Object)leaf).name); Transform parent = leaf.parent; while ((Object)(object)parent != (Object)null) { stringBuilder.Insert(0, '/').Insert(0, ((Object)parent).name); parent = parent.parent; } return stringBuilder.ToString(); } } internal sealed class FinalAscentDarkLamps : MonoBehaviour { private sealed class Lamp { internal float Power; internal float Reach; internal LightBakingOutput Baked; internal bool Ours; internal float Wrote; internal float WroteReach; } private const string Tag = "[FinalAscent]"; private const float Boost = 14f; private const float Spread = 4f; private const float Least = 26f; private const float Lit = 6f; private const float LitLeast = 22f; private const float LitMost = 80f; private static readonly Color Warm = new Color(1f, 0.8f, 0.52f, 1f); private readonly Dictionary _known = new Dictionary(); private readonly Dictionary _made = new Dictionary(); private readonly HashSet _now = new HashSet(); private readonly List _off = new List(); private readonly HashSet _seen = new HashSet(); private static FinalAscentDarkLamps _instance; internal static void Install() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("FA_DarkLamps"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } } private void LateUpdate() { if (!FinalAscentDarkSky.Full) { Douse(); return; } _now.Clear(); List aLL_GLOOM_SAFE_ZONES = GloomSafeZone.ALL_GLOOM_SAFE_ZONES; for (int i = 0; i < aLL_GLOOM_SAFE_ZONES.Count; i++) { GloomSafeZone val = aLL_GLOOM_SAFE_ZONES[i]; if (!((Object)(object)val == (Object)null) && val.isLit) { Feed(val); } } _off.Clear(); foreach (KeyValuePair item in _known) { if ((Object)(object)item.Key == (Object)null || !_now.Contains(item.Key)) { _off.Add(item.Key); } } for (int j = 0; j < _off.Count; j++) { Put(_off[j]); } } private void Feed(GloomSafeZone zone) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 int num = 0; Transform val = ((Component)zone).transform; for (int i = 0; i < 3; i++) { if (!((Object)(object)val != (Object)null)) { break; } Light[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Light val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && (int)val2.type != 1 && !IsOurs(val2)) { Take(val2, zone, num == 0 && i == 0); _now.Add(val2); num++; } } if (num > 0) { break; } val = val.parent; } Light val3 = Make(zone, num); if ((Object)(object)val3 != (Object)null) { _now.Add(val3); } Tell(zone, num); } private bool IsOurs(Light one) { if (_known.TryGetValue(one, out var value)) { return value.Ours; } return false; } private void Take(Light one, GloomSafeZone zone, bool first) { //IL_002f: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Invalid comparison between Unknown and I4 //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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) if (!_known.TryGetValue(one, out var value)) { value = new Lamp { Power = one.intensity, Reach = one.range, Baked = one.bakingOutput, Ours = false, Wrote = one.intensity, WroteReach = one.range }; _known[one] = value; } ((Behaviour)one).enabled = true; if (Mathf.Abs(one.intensity - value.Wrote) > 0.0001f) { value.Power = one.intensity; } if (Mathf.Abs(one.range - value.WroteReach) > 0.0001f) { value.Reach = one.range; } one.intensity = value.Power * 14f; one.range = Mathf.Max(value.Reach * 4f, 26f); value.Wrote = one.intensity; value.WroteReach = one.range; if ((int)one.bakingOutput.lightmapBakeType != 4) { LightBakingOutput bakingOutput = one.bakingOutput; bakingOutput.lightmapBakeType = (LightmapBakeType)4; bakingOutput.isBaked = false; one.bakingOutput = bakingOutput; } } private Light Make(GloomSafeZone zone, int found) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) Light value; bool flag = _made.TryGetValue(zone, out value) && (Object)(object)value != (Object)null; if (found > 0) { if (flag) { Put(value); _made.Remove(zone); } return null; } if (!flag) { GameObject val = new GameObject("FA_Glow"); val.transform.SetParent(((Component)zone).transform, false); val.transform.localPosition = Vector3.up * 0.4f; value = val.AddComponent(); value.type = (LightType)2; value.color = Warm; value.shadows = (LightShadows)0; _made[zone] = value; _known[value] = new Lamp { Power = 0f, Reach = 0f, Ours = true }; } float num = ((zone.statusProtectionRadius > 0.5f) ? zone.statusProtectionRadius : 6f); value.range = Mathf.Clamp(num * 3f, 22f, 80f); value.intensity = Mathf.Clamp(num * 6f, 14f, 80f); ((Behaviour)value).enabled = true; return value; } private void Put(Light one) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)one != (Object)null && _known.TryGetValue(one, out var value)) { if (value.Ours) { Object.Destroy((Object)(object)((Component)one).gameObject); } else { one.intensity = value.Power; one.range = value.Reach; one.bakingOutput = value.Baked; } } _known.Remove(one); } private void Tell(GloomSafeZone zone, int found) { if (_seen.Add(zone)) { Plugin.Log.LogInfo((object)("[FinalAscent] Finsternis: Quelle '" + ((Object)((Component)zone).gameObject).name + "' " + $"(Schutzradius {zone.statusProtectionRadius:0.#}m) - " + ((found > 0) ? $"{found} eigene(s) Licht(er), aufgedreht x{14f:0.#}" : "KEIN Licht, eines gestellt") + ".")); } } private void Douse() { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (_known.Count == 0) { _seen.Clear(); return; } foreach (KeyValuePair item in _known) { if (!((Object)(object)item.Key == (Object)null)) { if (item.Value.Ours) { Object.Destroy((Object)(object)((Component)item.Key).gameObject); continue; } item.Key.intensity = item.Value.Power; item.Key.range = item.Value.Reach; item.Key.bakingOutput = item.Value.Baked; } } _known.Clear(); _made.Clear(); _seen.Clear(); } } internal sealed class FinalAscentDarkMeter : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const Key ShowKey = (Key)103; private bool _shown; internal static void Install(GameObject host) { if ((Object)(object)host.GetComponent() == (Object)null) { host.AddComponent(); } } private void Update() { if (Keyboard.current != null && FinalAscentApocalypse.Active && FinalAscentDarkSky.Wanted && ((ButtonControl)Keyboard.current[(Key)103]).wasPressedThisFrame) { _shown = !_shown; Plugin.Log.LogInfo((object)("[FinalAscent] Finsternismesser " + (_shown ? "an" : "aus") + ".")); } } private void OnGUI() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Expected O, but got Unknown //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Expected O, but got Unknown //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) if (!_shown || !FinalAscentDarkSky.Wanted) { return; } Scoutmaster val = default(Scoutmaster); bool flag = Scoutmaster.GetPrimaryScoutmaster(ref val) && (Object)(object)val != (Object)null; Character localCharacter = Character.localCharacter; float num = -1f; if (flag && (Object)(object)localCharacter != (Object)null) { Character component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { num = Vector3.Distance(component.Center, localCharacter.Center); } } string text = "FINSTERNIS F10 aus\n" + $"Blende : {FinalAscentDarkSky.Lift:0.00}\n" + "Lampe : " + (FinalAscentFlashlight.Lit ? "AN" : "aus") + $" Batterie {FinalAscentFlashlight.Charge * 100f:0} %\n" + "Licht gilt : " + (FinalAscentScoutHunt.Sighted ? "ja" : "nein") + " " + FinalAscentScoutHunt.Lantern + "\n\n" + $"im Dunkeln : {FinalAscentScoutHunt.Dark:0.0} / " + $"{20f:0} s\n" + $"Licht am Stueck: {FinalAscentScoutHunt.Held:0.0} / " + $"{2f:0} s\n" + "Stufe : " + FinalAscentScoutHunt.Where + "\n" + $"Rauschen seit : {FinalAscentScoutHunt.Staring:0.0} / " + $"{3f:0} s\n" + $"Wuerfe : {FinalAscentScoutHunt.Rolls} a {5f:0} %\n" + $"im Strahl : {FinalAscentScoutHunt.Beamed:0.0} / " + $"{4f:0} s\n" + "\nScoutmaster : " + (flag ? "da" : "KEINER") + ((num >= 0f) ? $" {num:0} m" : "") + "\njagt mich : " + (FinalAscentScoutHunt.Chased ? "JA" : "nein") + "\n" + FinalAscentScoutHunt.Sheet + "\n" + $"Rauschen : {FinalAscentScoutHunt.Hissing:0.00}\n" + "in diesem Lauf : " + (FinalAscentScoutHunt.Allowed ? "erlaubt" : "abgestellt"); GUIStyle val2 = new GUIStyle(GUI.skin.box); val2.alignment = (TextAnchor)0; val2.fontSize = 14; val2.normal.textColor = Color.white; val2.padding = new RectOffset(10, 10, 8, 8); Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = new Color(0f, 0f, 0f, 0.85f); GUI.Box(new Rect(14f, 120f, 470f, 330f), text, val2); GUI.backgroundColor = backgroundColor; } } internal sealed class FinalAscentDarkness : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const string MusicKnob = "MusicVolume"; private const float Silence = -80f; private static readonly Color Rest = new Color(0.0009f, 0.0009f, 0.0018f, 1f); private const float Blackout = -2.5f; private Volume _blind; private const float MusicFade = 1.5f; private float _quiet; private AudioMixer _desk; private bool _asked; private float _wasMusic; private bool _tookMusic; private float _wasAmbient; private bool _tookAmbient; private bool _saidMode; private static FinalAscentDarkness _instance; private AmbientMode _wasMode; private float _wasMirror; private Color _wasFlat; private bool _dimmed; private LightmapData[] _wasBaked; private Texture2D _soot; 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_Darkness"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); FinalAscentTorches.Install(); FinalAscentDarkLamps.Install(); } FinalAscentFlashlight.Run(on); FinalAscentScoutHunt.Run(on); } private void LateUpdate() { float lift = FinalAscentDarkSky.Lift; if (lift <= 0f) { Daylight(); return; } Music(lift); Blind(lift); Ambient(lift); } private void Blind(float lift) { if ((Object)(object)_blind == (Object)null) { Shutter(); } if ((Object)(object)_blind != (Object)null) { _blind.weight = lift; } } private void Shutter() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown GameObject val = new GameObject("FA_Blackout"); val.transform.SetParent(((Component)this).transform, false); VolumeProfile val2 = ScriptableObject.CreateInstance(); ((Object)val2).name = "FA_Blackout"; ColorAdjustments obj = val2.Add(false); ((VolumeParameter)obj.postExposure).overrideState = true; ((VolumeParameter)(object)obj.postExposure).value = -2.5f; PostHandler val3 = Object.FindObjectOfType(); if ((Object)(object)val3 != (Object)null && (Object)(object)val3.volume != (Object)null) { val.layer = ((Component)val3.volume).gameObject.layer; } Volume val4 = val.AddComponent(); val4.isGlobal = true; val4.priority = 1000f; val4.weight = 0f; val4.sharedProfile = val2; _blind = val4; Plugin.Log.LogInfo((object)(string.Format("{0} Finsternis: eigene Blende gestellt ({1:0.#} Stufen) ", "[FinalAscent]", -2.5f) + $"in Ebene {val.layer}" + (((Object)(object)val3 != (Object)null && (Object)(object)val3.volume != (Object)null) ? " (von PEAKs Blende uebernommen)" : " (Vorgabe - PEAKs Blende nicht gefunden)") + ".")); } private void Music(float lift) { AudioMixer val = Desk(); if ((Object)(object)val == (Object)null) { return; } if (!_tookMusic) { if (!val.GetFloat("MusicVolume", ref _wasMusic)) { return; } _tookMusic = true; Plugin.Log.LogInfo((object)(string.Format("{0} Finsternis: Musik stand bei {1:0.#} dB - ", "[FinalAscent]", _wasMusic) + "wird gemerkt und am Ende zurueckgegeben.")); } float num = (FinalAscentScoutHunt.Chased ? 0f : lift); _quiet = Mathf.MoveTowards(_quiet, num, Time.deltaTime / 1.5f); val.SetFloat("MusicVolume", Mathf.Lerp(_wasMusic, -80f, _quiet)); } private void Ambient(float lift) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Survey(); if (!_tookAmbient) { _tookAmbient = true; _wasAmbient = RenderSettings.ambientIntensity; _wasMode = RenderSettings.ambientMode; _wasFlat = RenderSettings.ambientLight; _wasMirror = RenderSettings.reflectionIntensity; } RenderSettings.ambientMode = (AmbientMode)3; RenderSettings.ambientIntensity = Mathf.Lerp(_wasAmbient, 0f, lift); RenderSettings.ambientLight = Color.Lerp(_wasFlat, Rest, lift); RenderSettings.reflectionIntensity = Mathf.Lerp(_wasMirror, 0f, lift); Baked(lift); } private void Baked(float lift) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0056: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown bool flag = lift >= 0.5f; if (flag == _dimmed) { return; } LightmapData[] lightmaps = LightmapSettings.lightmaps; if (lightmaps == null || lightmaps.Length == 0) { return; } if (flag) { _wasBaked = lightmaps; if ((Object)(object)_soot == (Object)null) { _soot = new Texture2D(1, 1, (TextureFormat)4, false); _soot.SetPixel(0, 0, Color.black); _soot.Apply(); ((Object)_soot).hideFlags = (HideFlags)61; } LightmapData[] array = (LightmapData[])(object)new LightmapData[lightmaps.Length]; for (int i = 0; i < lightmaps.Length; i++) { array[i] = new LightmapData { lightmapColor = _soot, lightmapDir = lightmaps[i].lightmapDir, shadowMask = lightmaps[i].shadowMask }; } LightmapSettings.lightmaps = array; _dimmed = true; Plugin.Log.LogInfo((object)string.Format("{0} Finsternis: {1} Lichtkarte(n) geschwaerzt.", "[FinalAscent]", lightmaps.Length)); } else { if (_wasBaked != null) { LightmapSettings.lightmaps = _wasBaked; _wasBaked = null; } _dimmed = false; Plugin.Log.LogInfo((object)"[FinalAscent] Finsternis: Lichtkarten zurueckgelegt."); } } private void Survey() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (_saidMode) { return; } _saidMode = true; int num = ((LightmapSettings.lightmaps != null) ? LightmapSettings.lightmaps.Length : 0); string arg = "keine Kamera"; Camera main = Camera.main; if ((Object)(object)main != (Object)null) { UniversalAdditionalCameraData component = ((Component)main).GetComponent(); object obj; if (!((Object)(object)component != (Object)null)) { obj = "keine URP-Daten"; } else { string obj2 = (component.renderPostProcessing ? "ja" : "nein"); LayerMask volumeLayerMask = component.volumeLayerMask; obj = "nachbearbeitet " + obj2 + ", " + $"Blendenmaske {((LayerMask)(ref volumeLayerMask)).value}"; } arg = (string)obj; } Plugin.Log.LogInfo((object)(string.Format("{0} Finsternis misst: Umgebung '{1}' ", "[FinalAscent]", RenderSettings.ambientMode) + $"(Licht {RenderSettings.ambientLight}, Staerke " + $"{RenderSettings.ambientIntensity:0.###}), Spiegelung " + $"{RenderSettings.reflectionIntensity:0.##}, Lichtkarten {num} " + $"({LightmapSettings.lightmapsMode}), Kamera: {arg}, unsere Blende in " + $"Ebene {(((Object)(object)_blind != (Object)null) ? ((Component)_blind).gameObject.layer : (-1))}.")); } private void Daylight() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (_tookMusic) { AudioMixer val = Desk(); if ((Object)(object)val != (Object)null) { val.SetFloat("MusicVolume", _wasMusic); } _tookMusic = false; _quiet = 0f; } if (_tookAmbient) { RenderSettings.ambientMode = _wasMode; RenderSettings.ambientIntensity = _wasAmbient; RenderSettings.ambientLight = _wasFlat; RenderSettings.reflectionIntensity = _wasMirror; _tookAmbient = false; } Baked(0f); } private AudioMixer Desk() { if ((Object)(object)_desk != (Object)null || _asked) { return _desk; } _asked = true; AudioMixerGroup val = FinalAscentLarder.Bus(); float num = default(float); if ((Object)(object)val != (Object)null && (Object)(object)val.audioMixer != (Object)null && val.audioMixer.GetFloat("MusicVolume", ref num)) { _desk = val.audioMixer; Plugin.Log.LogInfo((object)("[FinalAscent] Finsternis: Mischpult '" + ((Object)_desk).name + "' ueber die Tonschiene.")); return _desk; } AudioMixerGroup[] array = Resources.FindObjectsOfTypeAll(); foreach (AudioMixerGroup val2 in array) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2.audioMixer != (Object)null && val2.audioMixer.GetFloat("MusicVolume", ref num)) { _desk = val2.audioMixer; Plugin.Log.LogInfo((object)("[FinalAscent] Finsternis: Mischpult '" + ((Object)_desk).name + "' ueber '" + ((Object)val2).name + "' gefunden.")); return _desk; } } Plugin.Log.LogWarning((object)"[FinalAscent] Finsternis: kein Mischpult mit 'MusicVolume' gefunden - die Musik spielt weiter."); return null; } } [HarmonyPatch(typeof(DayNightManager), "UpdateCycle")] internal static class FinalAscentDarkSky { private const float FadeSeconds = 5f; private const float Dim = 0.0001f; internal static bool Wanted; internal static float Lift; private static readonly Color SkyHigh = new Color(0.0003f, 0.0003f, 0.0007f, 1f); private static readonly Color SkyMid = new Color(0.0006f, 0.0006f, 0.0013f, 1f); private static readonly Color SkyLow = new Color(0.001f, 0.001f, 0.002f, 1f); private static readonly int TopKey = Shader.PropertyToID("SkyTopColor"); private static readonly int MidKey = Shader.PropertyToID("SkyMidColor"); private static readonly int LowKey = Shader.PropertyToID("SkyBottomColor"); private static bool _discs; internal static bool Full => Lift >= 1f; private static void Prefix() { Lift = Mathf.MoveTowards(Lift, Wanted ? 1f : 0f, Time.deltaTime / 5f); } private static void Postfix(DayNightManager __instance) { //IL_00e7: 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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_012d: 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_013c: Unknown result type (might be due to invalid IL or missing references) if (Lift > 0f) { _discs = true; FinalAscentSkyBodies.Fade(__instance, Lift); } else if (_discs) { _discs = false; FinalAscentSkyBodies.Fade(__instance, 0f); } if (!(Lift <= 0f)) { if ((Object)(object)__instance.sun != (Object)null) { __instance.sun.intensity = Mathf.Lerp(__instance.sun.intensity, 0.0001f, Lift); } if ((Object)(object)__instance.moon != (Object)null) { __instance.moon.intensity = Mathf.Lerp(__instance.moon.intensity, 0.0001f, Lift); } if ((Object)(object)__instance.lensFlare != (Object)null) { __instance.lensFlare.intensity = Mathf.Lerp(__instance.lensFlare.intensity, 0f, Lift); } Shader.SetGlobalColor(TopKey, Color.Lerp(Shader.GetGlobalColor(TopKey), SkyHigh, Lift)); Shader.SetGlobalColor(MidKey, Color.Lerp(Shader.GetGlobalColor(MidKey), SkyMid, Lift)); Shader.SetGlobalColor(LowKey, Color.Lerp(Shader.GetGlobalColor(LowKey), SkyLow, Lift)); } } } internal static class FinalAscentDelivery { private sealed class Listener : IOnEventCallback { public void OnEvent(EventData photonEvent) { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) if (photonEvent.Code == 181) { Serve(photonEvent); return; } if (photonEvent.Code == 182) { try { object[] array = (object[])photonEvent.CustomData; _acked[photonEvent.Sender] = (int)array[1]; return; } catch (Exception ex) { Plugin.Detail("[FinalAscent] Quittung unlesbar: " + ex.Message); return; } } if (photonEvent.Code != 180) { return; } try { object[] obj = (object[])photonEvent.CustomData; int num = (int)obj[0]; int num2 = (int)obj[1]; int num3 = (int)obj[2]; byte[] array2 = (byte[])obj[3]; if (num != _sliceSeed) { _slices.Clear(); _sliceSeed = num; } _slices[num2] = array2; _sliceTotal = num3; if ((num2 + 1) % 2 == 0 || num2 == num3 - 1) { object[] obj2 = new object[2] { num, _slices.Count }; RaiseEventOptions val = new RaiseEventOptions(); val.TargetActors = new int[1] { photonEvent.Sender }; PhotonNetwork.RaiseEvent((byte)182, (object)obj2, val, SendOptions.SendReliable); } Plugin.Detail(string.Format("{0} Paketscheibe {1}/{2} fuer Seed {3} ", "[FinalAscent]", num2 + 1, num3, num) + $"({array2.Length} Bytes)."); } catch (Exception ex2) { Plugin.Log.LogError((object)("[FinalAscent] Paketscheibe unlesbar: " + ex2.Message)); } } } private const string Tag = "[FinalAscent]"; private const char NewLine = '\n'; private const string KeyManifest = "FAmap"; private const string KeyStatus = "FAbau"; private const byte EventSlice = 180; private const byte EventRequest = 181; private const byte EventAck = 182; private const int Slice = 60000; private const int Window = 2; private const float SlicePause = 0.05f; private const float AckPatience = 30f; private static readonly Dictionary _acked = new Dictionary(); private static byte[] _package; private static int _packageSeed = int.MinValue; private static Listener _listener; private static readonly SortedDictionary _slices = new SortedDictionary(); private static int _sliceSeed = int.MinValue; private static int _sliceTotal = -1; private static readonly HashSet _serving = new HashSet(); private static readonly Dictionary _skipped = new Dictionary(); private static readonly Dictionary _prefabs = new Dictionary(); private static readonly Dictionary _materials = new Dictionary(); private static readonly HashSet _deliveredSections = new HashSet(); private static readonly Dictionary> _biomeMats = new Dictionary>(); private static int _matHome; private static int _matAfar; private static readonly List _laterVines = new List(); private static readonly List _laterGround = new List(); private static readonly List> _laterWorld = new List>(); private static readonly List> _laterWake = new List>(); private static readonly Dictionary> _stepMats = new Dictionary>(); private static int _matStep; private static readonly Dictionary> _biomePrefabs = new Dictionary>(); private static int _prefLocal; private static int _prefHome; private static int _prefAfar; private static readonly Dictionary _afarNames = new Dictionary(); private static readonly HashSet _mined = new HashSet(); internal static bool ClientMode { get; set; } internal static void Listen() { if (_listener == null) { _listener = new Listener(); PhotonNetwork.AddCallbackTarget((object)_listener); } } private static void Serve(EventData e) { try { if (PhotonNetwork.IsMasterClient && !((Object)(object)Plugin.Instance == (Object)null)) { int seed = (int)((object[])e.CustomData)[0]; byte[] array = Package(seed); if (array == null) { Plugin.Detail(string.Format("{0} Platz {1} bittet um die Karte - noch nichts da.", "[FinalAscent]", e.Sender)); } else if (!_serving.Contains(e.Sender)) { _serving.Add(e.Sender); ((MonoBehaviour)Plugin.Instance).StartCoroutine(SendPaced(e.Sender, seed, array)); } } } catch (Exception ex) { Plugin.Log.LogError((object)("[FinalAscent] Kartenbitte nicht beantwortbar: " + ex.Message)); } } private static IEnumerator SendPaced(int actor, int seed, byte[] packed) { int total = (packed.Length + 60000 - 1) / 60000; _acked[actor] = 0; float begun = Time.realtimeSinceStartup; Plugin.Log.LogInfo((object)(string.Format("{0} Karte geht an Platz {1}: {2} KB in ", "[FinalAscent]", actor, packed.Length / 1024) + $"{total} Scheiben, Fenster {2} - das Tempo bestimmt der Empfaenger.")); for (int i = 0; i < total; i++) { if (!PhotonNetwork.InRoom) { break; } int num = Math.Min(60000, packed.Length - i * 60000); byte[] array = new byte[num]; Buffer.BlockCopy(packed, i * 60000, array, 0, num); object[] obj = new object[4] { seed, i, total, array }; RaiseEventOptions val = new RaiseEventOptions(); val.TargetActors = new int[1] { actor }; PhotonNetwork.RaiseEvent((byte)180, (object)obj, val, SendOptions.SendReliable); if ((i + 1) % 2 != 0) { yield return (object)new WaitForSecondsRealtime(0.05f); continue; } float waitedAck = 0f; while (Ack(actor) < i + 1 && waitedAck < 30f && PhotonNetwork.InRoom) { waitedAck += Time.unscaledDeltaTime; yield return null; } if (waitedAck >= 30f) { Plugin.Log.LogWarning((object)(string.Format("{0} Platz {1} quittiert seit {2:F0}s nicht ", "[FinalAscent]", actor, 30f) + $"(bei Scheibe {i + 1}/{total}) - die Auslieferung bricht ab. " + "Der Empfaenger fragt von selbst neu an.")); break; } } _serving.Remove(actor); _acked.Remove(actor); Plugin.Log.LogInfo((object)(string.Format("{0} Karte an Platz {1} abgeschickt in ", "[FinalAscent]", actor) + $"{Time.realtimeSinceStartup - begun:F1}s " + $"({(float)packed.Length / 1024f / Mathf.Max(0.1f, Time.realtimeSinceStartup - begun):F0} KB/s).")); } private static int Ack(int actor) { if (!_acked.TryGetValue(actor, out var value)) { return 0; } return value; } private static byte[] Package(int seed) { if (_package != null && _packageSeed == seed) { return _package; } if (!FinalAscentBuilder.Done) { return null; } try { _package = Zip(Serialize(out var objects)); _packageSeed = seed; Plugin.Log.LogInfo((object)("[FinalAscent] Karte aus der eigenen Szene nachserialisiert " + $"({objects} Objekte, {_package.Length / 1024} KB) - dieser Rechner " + "kann jetzt selbst ausliefern.")); return _package; } catch (Exception ex) { Plugin.Log.LogError((object)("[FinalAscent] Nachserialisieren misslungen: " + ex.Message)); return null; } } private static byte[] Assembled(int seed) { if (_sliceSeed != seed || _sliceTotal < 0 || _slices.Count < _sliceTotal) { return null; } using MemoryStream memoryStream = new MemoryStream(); foreach (KeyValuePair slice in _slices) { memoryStream.Write(slice.Value, 0, slice.Value.Length); } return memoryStream.ToArray(); } internal static void ForgetRoomPackage(int newSeed) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_0088: Expected O, but got Unknown if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null || !PhotonNetwork.IsMasterClient) { return; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties != null && ((Dictionary)(object)customProperties).TryGetValue((object)"FAmap", out object value) && value is string text) { string value2 = newSeed.ToString(CultureInfo.InvariantCulture) + ";"; if (!text.StartsWith(value2)) { Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"FAmap", (object)null); ((Dictionary)val).Add((object)"FAbau", (object)null); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); _package = null; _packageSeed = 0; _slices.Clear(); Plugin.Log.LogInfo((object)(string.Format("{0} Neuer Lauf (Seed {1}): das Inselpaket des vorigen wird ", "[FinalAscent]", newSeed) + "aus dem Raum genommen. Sonst wuerde es als Wahrheit weitergereicht.")); } } } internal static void PackAndShip() { //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown Listen(); if (!FinalAscent.Active || !PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient) { return; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties != null && ((Dictionary)(object)customProperties).TryGetValue((object)"FAmap", out object value) && value is string text && text.StartsWith(FinalAscent.Seed.ToString(CultureInfo.InvariantCulture) + ";")) { Plugin.Log.LogInfo((object)(string.Format("{0} Im Raum liegt schon ein Inselpaket fuer Seed {1} - ", "[FinalAscent]", FinalAscent.Seed) + "das bleibt die Wahrheit.")); return; } string text2; int objects; try { BuildResolver(); text2 = Serialize(out objects); } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("{0} Inselpaket liess sich nicht packen: {1}", "[FinalAscent]", arg)); return; } _package = Zip(text2); _packageSeed = FinalAscent.Seed; FinalAscentBaked.Save(_package, objects); FinalAscentItemResync.Listen(); int num = (_package.Length + 60000 - 1) / 60000; Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary)(object)val).Add((object)"FAmap", (object)(FinalAscent.Seed.ToString(CultureInfo.InvariantCulture) + ";" + num + ";" + _package.Length + ";" + FinalAscentSetup.SerializeChosen() + ";" + FinalAscentBuilder.SummitNote())); ((Dictionary)(object)val).Add((object)"FAbau", (object)null); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)(string.Format("{0} INSELPAKET BEREIT: {1} Objekte, ", "[FinalAscent]", objects) + $"{_package.Length / 1024} KB gepackt in {num} Scheiben. Es wird " + "auf Zuruf ausgeliefert, gedrosselt - nicht mehr im Schwall.")); } private static string Serialize(out int objects) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_0502: Unknown result type (might be due to invalid IL or missing references) //IL_051f: Unknown result type (might be due to invalid IL or missing references) //IL_053c: Unknown result type (might be due to invalid IL or missing references) //IL_0559: Unknown result type (might be due to invalid IL or missing references) //IL_0576: Unknown result type (might be due to invalid IL or missing references) //IL_0593: Unknown result type (might be due to invalid IL or missing references) //IL_05c8: Unknown result type (might be due to invalid IL or missing references) //IL_05e5: Unknown result type (might be due to invalid IL or missing references) //IL_0602: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) objects = 0; _skipped.Clear(); StringBuilder stringBuilder = new StringBuilder(4194304); TowerStacker[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (TowerStacker val in array) { if ((Object)(object)val == (Object)null || val.stack == null || val.stack.Count == 0) { continue; } stringBuilder.Append('!').Append(ScenePathOf(((Component)val).transform)).Append('|'); foreach (GameObject item in val.stack) { float num = (((Object)(object)item != (Object)null) ? item.transform.localEulerAngles.y : 0f); stringBuilder.Append((Mathf.Abs(Mathf.DeltaAngle(num, 180f)) < 90f) ? '1' : '0'); } stringBuilder.Append('\n'); } List list = OrderedSteps(); HashSet hashSet = new HashSet(); List list2 = new List(); int num2 = 0; foreach (Transform item2 in list) { if ((Object)(object)item2 == (Object)null || !hashSet.Add(item2)) { continue; } string text = ScenePathOf(item2); bool flag = HostCleared(item2, text); bool flag2 = false; for (int j = 0; j < item2.childCount; j++) { string name = ((Object)item2.GetChild(j)).name; if (CloneNamed(name) && !name.StartsWith("MushroomZombieSpawner")) { flag2 = true; break; } } Transform val2 = (((Object)(object)((Component)item2).GetComponent() != (Object)null) ? item2.Find("Enterences") : null); if (!flag2 && (Object)(object)val2 != (Object)null) { for (int k = 0; k < val2.childCount; k++) { if (flag2) { break; } Transform child = val2.GetChild(k); for (int l = 0; l < child.childCount; l++) { if (CloneNamed(((Object)child.GetChild(l)).name)) { flag2 = true; break; } } } } if (!flag && !flag2) { continue; } stringBuilder.Append('@').Append(text).Append('\n'); if (!flag2) { num2++; continue; } list2.Add(item2); Dictionary local = LocalPrefabs(item2); for (int m = 0; m < item2.childCount; m++) { Transform child2 = item2.GetChild(m); if (!CloneNamed(((Object)child2).name) || ((Object)child2).name.StartsWith("MushroomZombieSpawner")) { if (!((Object)child2).name.StartsWith("MushroomZombieSpawner")) { _skipped.TryGetValue(((Object)child2).name, out var value); _skipped[((Object)child2).name] = value + 1; } } else { Dictionary local2 = WithDecorLists(local, child2); WriteLine(stringBuilder, child2, null, local2, item2); objects++; objects += WriteDecor(stringBuilder, child2, child2, "", local2); } } if (!((Object)(object)val2 != (Object)null)) { continue; } Transform val3 = item2.Find("Inside"); string text2 = (((Object)(object)val3 != (Object)null) ? ("|i=" + F(val3.localPosition.x) + ":" + F(val3.localPosition.y) + ":" + F(val3.localPosition.z)) : ""); for (int n = 0; n < val2.childCount; n++) { Transform child3 = val2.GetChild(n); for (int num3 = 0; num3 < child3.childCount; num3++) { Transform child4 = child3.GetChild(num3); if (CloneNamed(((Object)child4).name)) { WriteLine(stringBuilder, child4, null, local, item2, "|c=Enterences/" + ((Object)child3).name + text2); text2 = ""; objects++; } } } } foreach (Transform item3 in list2) { stringBuilder.Append('=').Append(ScenePathOf(item3)).Append('|') .Append(PrintOf(item3)) .Append('\n'); } int num4 = 0; JungleVine[] array2 = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (JungleVine val4 in array2) { if (!((Object)(object)val4 == (Object)null) && FinalAscentVineLog.TryGet(val4, out var build)) { stringBuilder.Append('~').Append(ScenePathOf(((Component)val4).transform)).Append('|') .Append(F(build.From.x)) .Append(':') .Append(F(build.From.y)) .Append(':') .Append(F(build.From.z)) .Append(':') .Append(F(build.To.x)) .Append(':') .Append(F(build.To.y)) .Append(':') .Append(F(build.To.z)) .Append(':') .Append(F(build.Hang)) .Append(':') .Append(F(build.Mid.x)) .Append(':') .Append(F(build.Mid.y)) .Append(':') .Append(F(build.Mid.z)) .Append('\n'); num4++; } } Plugin.Log.LogInfo((object)(string.Format("{0} {1} Ranken-Baudaten im Image ", "[FinalAscent]", num4) + $"(mitgeschrieben: {FinalAscentVineLog.Count}).")); int num5 = 0; HeightmapMesh[] array3 = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (HeightmapMesh val5 in array3) { if ((Object)(object)val5 == (Object)null || !FinalAscentHeightmap.TryGet(val5, out var heights) || heights == null) { continue; } int length = heights.GetLength(0); int length2 = heights.GetLength(1); stringBuilder.Append('^').Append(ScenePathOf(((Component)val5).transform)).Append('|') .Append(F(val5.cellSize)) .Append('|') .Append(val5.center ? '1' : '0') .Append('|') .Append(length) .Append('|') .Append(length2) .Append('|'); for (int num6 = 0; num6 < length; num6++) { for (int num7 = 0; num7 < length2; num7++) { if (num6 > 0 || num7 > 0) { stringBuilder.Append(','); } stringBuilder.Append(C(heights[num6, num7])); } } stringBuilder.Append('\n'); num5++; } if (num5 > 0) { Plugin.Log.LogInfo((object)(string.Format("{0} {1} Hoehenkarte(n) im Image - der Sumpfboden reist ", "[FinalAscent]", num5) + "jetzt mit, statt auf jedem Rechner neu erstrahlt zu werden.")); } if (num2 > 0) { Plugin.Log.LogInfo((object)(string.Format("{0} {1} leere Sektionen im Image - vom Host ", "[FinalAscent]", num2) + "geleerte Schritte ohne neue Ladung; der Gast leert sie ebenso.")); } stringBuilder.Append('&').Append(StatueSpawnRandomizationStep.statueSpawnOffset.ToString(CultureInfo.InvariantCulture)).Append('\n'); Plugin.Log.LogInfo((object)(string.Format("{0} Statuen-Versatz {1} ", "[FinalAscent]", StatueSpawnRandomizationStep.statueSpawnOffset) + "im Image - damit haengt an jeder Statue bei allen dasselbe Amulett.")); int num8 = FinalAscentPaint.Pack(stringBuilder); if (num8 > 0) { Plugin.Log.LogInfo((object)(string.Format("{0} {1} umgefaerbte Renderer im Image - RedBeach, Ivy und die ", "[FinalAscent]", num8) + "uebrigen Fassungen kommen damit auch beim Gast in ihrer Farbe an.")); } ReportSkipped(); return stringBuilder.ToString(); } private static bool CloneNamed(string name) { if (!name.EndsWith("(Clone)")) { return name.EndsWith(" (spawner)"); } return true; } private static bool HostCleared(Transform root, string where) { LevelGenStep[] components = ((Component)root).GetComponents(); foreach (LevelGenStep val in components) { if ((Object)(object)val != (Object)null && FinalAscentGeneration.WasCleared(val)) { return true; } } return _deliveredSections.Contains(where); } private static string PrintOf(Transform stepRoot) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) Biome componentInParent = ((Component)stepRoot).GetComponentInParent(true); Transform val = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).transform : stepRoot); long num = 0L; int num2 = 0; for (int i = 0; i < stepRoot.childCount; i++) { Transform child = stepRoot.GetChild(i); if (CloneNamed(((Object)child).name) && !((Object)child).name.StartsWith("MushroomZombieSpawner")) { Vector3 val2 = val.InverseTransformPoint(child.position); long num3 = 1469598103934665603L; num3 = (num3 ^ Mathf.RoundToInt(val2.x * 100f)) * 1099511628211L; num3 = (num3 ^ Mathf.RoundToInt(val2.y * 100f)) * 1099511628211L; num3 = (num3 ^ Mathf.RoundToInt(val2.z * 100f)) * 1099511628211L; num += num3; num2++; } } return num2 + "/" + (num & 0xFFFFFF).ToString("X6"); } private static void ReportSkipped() { int num = 0; foreach (KeyValuePair item in _skipped) { num += item.Value; } if (num != 0) { List> list = new List>(_skipped); list.Sort((KeyValuePair a, KeyValuePair b) => b.Value.CompareTo(a.Value)); Plugin.Log.LogInfo((object)(string.Format("{0} Nicht ins Paket gelegt (kein '(Clone)' im Namen): {1} ", "[FinalAscent]", num) + $"Kinder in {_skipped.Count} Sorten.")); for (int num2 = 0; num2 < list.Count && num2 < 12; num2++) { Plugin.Log.LogInfo((object)string.Format("{0} {1,5}x '{2}'", "[FinalAscent]", list[num2].Value, list[num2].Key)); } } } private static int WriteDecor(StringBuilder text, Transform prop, Transform at, string relParent, Dictionary local) { if ((Object)(object)((Component)at).GetComponent() != (Object)null) { return 0; } if ((Object)(object)((Component)at).GetComponent() != (Object)null) { return 0; } int num = 0; for (int i = 0; i < at.childCount; i++) { Transform child = at.GetChild(i); if (!((Object)(object)((Component)child).GetComponent() != (Object)null)) { string relParent2 = ((relParent.Length == 0) ? RelName(at, child) : (relParent + "/" + RelName(at, child))); if (((Object)child).name.EndsWith("(Clone)") && !((Object)child).name.StartsWith("MushroomZombieSpawner")) { WriteLine(text, child, relParent, local); num++; } num += WriteDecor(text, prop, child, relParent2, local); } } return num; } private static string RelName(Transform parent, Transform kid) { int num = 0; for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if ((Object)(object)child == (Object)(object)kid) { break; } if (((Object)child).name == ((Object)kid).name) { num++; } } if (num != 0) { return ((Object)kid).name + "#" + num; } return ((Object)kid).name; } private static void WriteLine(StringBuilder text, Transform kid, string relParent, Dictionary local, Transform sectionStep = null, string extraTail = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Expected I4, but got Unknown //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Expected O, but got Unknown //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) Vector3 localPosition = kid.localPosition; Quaternion localRotation = kid.localRotation; Vector3 localScale = kid.localScale; if (relParent != null) { text.Append('>').Append(relParent).Append('|'); } text.Append(((Object)kid).name).Append('|').Append(F(localPosition.x)) .Append('|') .Append(F(localPosition.y)) .Append('|') .Append(F(localPosition.z)) .Append('|') .Append(F(localRotation.x)) .Append('|') .Append(F(localRotation.y)) .Append('|') .Append(F(localRotation.z)) .Append('|') .Append(F(localRotation.w)) .Append('|') .Append(F(localScale.x)) .Append('|') .Append(F(localScale.y)) .Append('|') .Append(F(localScale.z)); GameObject val = ResolveWith(local, ((Object)kid).name); if ((Object)(object)val == (Object)null && ((Object)kid).name.EndsWith(" (spawner)") && (Object)(object)sectionStep != (Object)null) { PropSpawner[] components = ((Component)sectionStep).GetComponents(); foreach (PropSpawner val2 in components) { if (val2.props != null && val2.props.Length == 1 && (Object)(object)val2.props[0] != (Object)null) { val = val2.props[0]; text.Append("|p=").Append(((Object)val2.props[0]).name).Append("(Clone)"); break; } } } if ((Object)(object)val != (Object)null) { WriteStateDiff(text, kid, val.transform, ""); } Campfire componentInChildren = ((Component)kid).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { text.Append("|f=").Append((int)componentInChildren.advanceToSegment); } LavaRiver componentInChildren2 = ((Component)kid).GetComponentInChildren(true); if ((Object)(object)componentInChildren2 != (Object)null && componentInChildren2.frames != null && componentInChildren2.frames.Count > 1) { Quaternion val3 = (((Object)(object)componentInChildren2.endRock != (Object)null) ? componentInChildren2.endRock.transform.rotation : Quaternion.identity); text.Append("|r=").Append(F(val3.x)).Append(':') .Append(F(val3.y)) .Append(':') .Append(F(val3.z)) .Append(':') .Append(F(val3.w)) .Append('#'); for (int j = 0; j < componentInChildren2.frames.Count; j++) { LavaRiverFrame val4 = componentInChildren2.frames[j]; if (j > 0) { text.Append(';'); } text.Append(C(val4.position.x)).Append(',').Append(C(val4.position.y)) .Append(',') .Append(C(val4.position.z)) .Append(',') .Append(C(val4.up.x)) .Append(',') .Append(C(val4.up.y)) .Append(',') .Append(C(val4.up.z)) .Append(',') .Append(C(val4.forward.x)) .Append(',') .Append(C(val4.forward.y)) .Append(',') .Append(C(val4.forward.z)); } } WaterFallConfig componentInChildren3 = ((Component)kid).GetComponentInChildren(true); if ((Object)(object)componentInChildren3 != (Object)null && (Object)(object)componentInChildren3.endRock != (Object)null) { float value = 0f; try { if ((Object)(object)componentInChildren3.mesh != (Object)null) { MaterialPropertyBlock val5 = new MaterialPropertyBlock(); ((Renderer)componentInChildren3.mesh).GetPropertyBlock(val5); value = val5.GetFloat("_WorldPositionY"); } } catch { } Vector3 position = componentInChildren3.endRock.position; text.Append("|w=").Append(F(position.x)).Append(':') .Append(F(position.y)) .Append(':') .Append(F(position.z)) .Append(':') .Append(F(value)); } if (extraTail != null) { text.Append(extraTail); } text.Append('\n'); } private static void WriteStateDiff(StringBuilder text, Transform inst, Transform proto, string idxPath) { Renderer component = ((Component)inst).GetComponent(); Renderer component2 = ((Component)proto).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null) { Material[] sharedMaterials = component.sharedMaterials; Material[] sharedMaterials2 = component2.sharedMaterials; int num = Math.Min(sharedMaterials.Length, sharedMaterials2.Length); for (int i = 0; i < num; i++) { string text2 = (((Object)(object)sharedMaterials[i] != (Object)null) ? ((Object)sharedMaterials[i]).name.Replace(" (Instance)", "") : ""); string text3 = (((Object)(object)sharedMaterials2[i] != (Object)null) ? ((Object)sharedMaterials2[i]).name.Replace(" (Instance)", "") : ""); if (text2 != text3 && text2.Length > 0) { text.Append("|M").Append(idxPath).Append(':') .Append(i) .Append(':') .Append(text2); } } } if (((Component)inst).gameObject.activeSelf != ((Component)proto).gameObject.activeSelf) { text.Append("|A").Append(idxPath).Append(':') .Append(((Component)inst).gameObject.activeSelf ? '1' : '0'); } int num2 = 0; for (int j = 0; j < inst.childCount; j++) { if (num2 >= proto.childCount) { break; } Transform child = inst.GetChild(j); if (!((Object)child).name.EndsWith("(Clone)")) { WriteStateDiff(text, child, proto.GetChild(num2), (idxPath.Length == 0) ? num2.ToString() : (idxPath + "," + num2)); num2++; } } } internal static IEnumerator WaitAndApply(Func fallback, LevelGeneration levelGen) { Listen(); int seed = FinalAscent.Seed; float waited = 0f; byte[] packed = null; Plugin.Log.LogInfo((object)("[FinalAscent] Dieser Rechner generiert nicht - er wartet auf das Inselpaket " + $"des Hosts (Seed {seed}).")); float sinceAsk = 99f; int _lastSeen = 0; while (waited < 600f) { packed = Assembled(seed); if (packed != null) { break; } if (PhotonNetwork.IsMasterClient && Package(seed) == null) { Plugin.Log.LogWarning((object)"[FinalAscent] Dieser Rechner ist selbst Master geworden, ohne Karte - er generiert nun doch selbst."); break; } if (_slices.Count > _lastSeen) { _lastSeen = _slices.Count; sinceAsk = 0f; } sinceAsk += Time.deltaTime; if (sinceAsk >= 12f && PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient) { sinceAsk = 0f; PhotonNetwork.RaiseEvent((byte)181, (object)new object[1] { seed }, new RaiseEventOptions { Receivers = (ReceiverGroup)2 }, SendOptions.SendReliable); Plugin.Detail(string.Format("{0} Karte beim Master angefragt (Seed {1}).", "[FinalAscent]", seed)); } if (_sliceTotal > 0 && _sliceSeed == seed && _slices.Count > 0) { FinalAscentLoadHud.Phase("load.download", "Downloading the island"); int num = _slices.Count * 60000 / 1024; FinalAscentLoadHud.Detail($"slice {_slices.Count} of {_sliceTotal} ({num} KB)"); } else { FinalAscentLoadHud.Phase("load.wait", "Waiting for the island"); FinalAscentLoadHud.Detail(string.Empty); } waited += Time.deltaTime; yield return null; } if (packed == null) { Plugin.Log.LogError((object)(string.Format("{0} Nach {1:F0}s KEIN Inselpaket - Rueckfall auf eigene ", "[FinalAscent]", waited) + "Generierung (Host mit alter Fassung?). Der Berg kann abweichen.")); if (fallback != null) { IEnumerator own = fallback(); while (own.MoveNext()) { yield return own.Current; } FinalAscentBuilder.MeasureSummitAndFollow(levelGen); } yield break; } _package = packed; _packageSeed = seed; if (waited > 5f) { Plugin.Log.LogInfo((object)(string.Format("{0} Inselpaket nach {1:F0}s Wartezeit vollstaendig ", "[FinalAscent]", waited) + $"({packed.Length / 1024} KB) - dieser Rechner kann es jetzt " + "selbst weiterreichen.")); } string text = null; string summit = null; if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties != null && ((Dictionary)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"FAmap", out object value) && value is string text2) { string[] array = text2.Split(';'); if (array.Length >= 4 && array[0] == seed.ToString(CultureInfo.InvariantCulture)) { text = array[3]; if (array.Length >= 5) { summit = array[4]; } } } if (!string.IsNullOrEmpty(text)) { Plugin.Log.LogInfo((object)("[FinalAscent] Fassungen des Hosts werden gestellt: " + text)); try { FinalAscentSetup.ApplyDelivered(text, levelGen); } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("{0} Fassungen liessen sich nicht stellen: {1}", "[FinalAscent]", arg)); } } else { Plugin.Log.LogWarning((object)"[FinalAscent] Keine Fassungswahl im Manifest - die Aeste bleiben, wie die Szene sie gebacken hat. Das Bild KANN vom Host abweichen."); } PropGrouper val = (((Object)(object)levelGen != (Object)null) ? ((Component)levelGen).GetComponent() : null); if ((Object)(object)val != (Object)null) { FinalAscentGeneration.ClearEverything(val); } FinalAscentLoadHud.Phase("load.unpack", "Unpacking the map"); IEnumerator apply = Apply(Unzip(packed)); while (apply.MoveNext()) { yield return apply.Current; } yield return null; yield return null; FinalAscentBuilder.FinishScene(); FinalAscentBuilder.AdoptSummit(summit); FinalAscentTowerStackerPatch.WakeSink = null; int woken = 0; int dueWake = 0; foreach (KeyValuePair item in _laterWake) { if (!((Object)(object)item.Key == (Object)null) && item.Value) { item.Key.SetActive(true); woken++; int num2 = dueWake + 1; dueWake = num2; if ((num2 & 0x1FF) == 0) { yield return null; } } } Plugin.Log.LogInfo((object)(string.Format("{0} {1} Paket-Klone geweckt (von {2} ", "[FinalAscent]", woken, _laterWake.Count) + "geborenen) - nach der Kuppen-Korrektur, an ihren Endplaetzen.")); _laterWake.Clear(); LayGround(); SpanVines(); BuildWorldPieces(); FinalAscentWorldCensus.Take("bauende"); FinalAscentDiceWatch.Report(); FinalAscentGeneration.PostUnpackCleanup(); FinalAscentGeneration.FingerprintNow(); } private static IEnumerator Apply(string text) { BuildResolver(); string[] array = text.Split('\n'); Transform stepRoot = null; Transform lastProp = null; Dictionary stepLocal = null; Dictionary propLocal = null; int made = 0; int decor = 0; int paintLines = 0; int shelfLines = 0; FinalAscentPaint.BeginApply(); FinalAscentFakeItems.BeginApply(); int orphans = 0; int mats = 0; int fires = 0; int toggles = 0; int sinceYield = 0; int noStep = 0; int noParent = 0; int sweptSteps = 0; int sweptKids = 0; int printsOk = 0; int towers = 0; Dictionary missing = new Dictionary(); HashSet sweptNow = new HashSet(); Dictionary sections = new Dictionary(); List misprints = new List(); _deliveredSections.Clear(); _biomeMats.Clear(); _matHome = 0; _matAfar = 0; _biomePrefabs.Clear(); _afarNames.Clear(); _prefLocal = 0; _prefHome = 0; _prefAfar = 0; _stepMats.Clear(); _matStep = 0; _laterVines.Clear(); _laterWorld.Clear(); _laterWake.Clear(); _laterGround.Clear(); FinalAscentTowerStackerPatch.WakeSink = _laterWake; string[] array2 = array; foreach (string text2 in array2) { if (text2.Length == 0) { continue; } if (text2[0] == '^') { _laterGround.Add(text2); continue; } if (text2[0] == '~') { _laterVines.Add(text2); continue; } if (text2[0] == '!') { int num = text2.LastIndexOf('|'); if (num <= 1) { continue; } string text3 = text2.Substring(1, num - 1); Transform val = FindByPath(text3); TowerStacker val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if ((Object)(object)val2 != (Object)null) { try { towers += ((FinalAscentTowerStackerPatch.StackWith(val2, text2.Substring(num + 1)) > 0) ? 1 : 0); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Stapler '" + text3 + "' baut nicht: " + ex.Message)); } } else { Plugin.Log.LogWarning((object)("[FinalAscent] Stapler '" + text3 + "' fehlt in dieser Szene - " + Whereabouts(text3))); } continue; } if (text2[0] == '=') { int num2 = text2.LastIndexOf('|'); if (num2 <= 1) { continue; } string text4 = text2.Substring(1, num2 - 1); string text5 = text2.Substring(num2 + 1); if (sections.TryGetValue(text4, out var value) && (Object)(object)value != (Object)null) { string text6 = PrintOf(value); if (text6 == text5) { printsOk++; continue; } misprints.Add(text4 + ": Host " + text5 + ", hier " + text6); } continue; } if (text2[0] == '&') { if (int.TryParse(text2.Substring(1), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { int statueSpawnOffset = StatueSpawnRandomizationStep.statueSpawnOffset; StatueSpawnRandomizationStep.statueSpawnOffset = result; Plugin.Log.LogInfo((object)(string.Format("{0} Statuen-Versatz aus dem Image: {1} ", "[FinalAscent]", result) + $"(hier stand {statueSpawnOffset}). Ohne ihn zieht man aus derselben " + "Statue ein anderes Amulett als der Host.")); } continue; } if (text2[0] == '$') { FinalAscentFakeItems.ApplyLine(text2.Substring(1)); shelfLines++; continue; } if (text2[0] == '%') { FinalAscentPaint.ApplyLine(text2.Substring(1)); paintLines++; continue; } if (text2[0] == '@') { string text7 = text2.Substring(1); stepRoot = FindByPath(text7); _deliveredSections.Add(text7); if ((Object)(object)stepRoot == (Object)null) { Plugin.Log.LogWarning((object)("[FinalAscent] Schritt '" + text7 + "' fehlt in dieser Szene - " + Whereabouts(text7))); } else { sections[text7] = stepRoot; if (sweptNow.Add(stepRoot)) { sweptKids += stepRoot.childCount; LevelGenStep[] components = ((Component)stepRoot).GetComponents(); foreach (LevelGenStep val3 in components) { if (!(val3 is TowerStacker)) { try { val3.Clear(); } catch (Exception ex2) { Plugin.Detail("[FinalAscent] '" + ((Object)val3).name + "' liess sich nicht leeren: " + ex2.Message); } } } sweptSteps++; } } stepLocal = (((Object)(object)stepRoot != (Object)null) ? LocalPrefabs(stepRoot) : null); propLocal = stepLocal; continue; } bool flag = text2[0] == '>'; string[] array3 = (flag ? text2.Substring(1) : text2).Split('|'); if ((Object)(object)stepRoot == (Object)null) { orphans++; noStep++; continue; } Transform val4; int num3; if (flag) { val4 = (((Object)(object)lastProp != (Object)null) ? FindRelative(lastProp, array3[0]) : null); num3 = 1; } else { val4 = stepRoot; num3 = 0; } if ((Object)(object)val4 == (Object)null || array3.Length < num3 + 11) { orphans++; noParent++; continue; } string text8 = array3[num3]; string text9 = null; string text10 = null; for (int k = num3 + 11; k < array3.Length; k++) { if (text9 == null && array3[k].StartsWith("p=")) { text9 = array3[k].Substring(2); } else if (text10 == null && array3[k].StartsWith("c=")) { text10 = array3[k].Substring(2); } } if (text10 != null && !flag) { Transform val5 = stepRoot; string[] array4 = text10.Split('/'); foreach (string text11 in array4) { val5 = (((Object)(object)val5 != (Object)null) ? val5.Find(text11) : null); } if ((Object)(object)val5 == (Object)null) { orphans++; noParent++; continue; } val4 = val5; } GameObject val6 = ResolveNear(flag ? propLocal : stepLocal, text9 ?? text8, stepRoot); if ((Object)(object)val6 == (Object)null) { orphans++; missing.TryGetValue(text8, out var value2); missing[text8] = value2 + 1; continue; } bool activeSelf = val6.activeSelf; GameObject val7; try { val6.SetActive(false); val7 = Object.Instantiate(val6, val4); } finally { val6.SetActive(activeSelf); } _laterWake.Add(new KeyValuePair(val7, activeSelf)); ((Object)val7).name = text8; Transform transform = val7.transform; transform.localPosition = new Vector3(P(array3[num3 + 1]), P(array3[num3 + 2]), P(array3[num3 + 3])); transform.localRotation = new Quaternion(P(array3[num3 + 4]), P(array3[num3 + 5]), P(array3[num3 + 6]), P(array3[num3 + 7])); transform.localScale = new Vector3(P(array3[num3 + 8]), P(array3[num3 + 9]), P(array3[num3 + 10])); for (int l = num3 + 11; l < array3.Length; l++) { string text12 = array3[l]; int result2; if (text12.StartsWith("m=") && ApplyMaterial(val7, text12.Substring(2))) { mats++; } else if (text12.StartsWith("f=") && int.TryParse(text12.Substring(2), out result2)) { Campfire componentInChildren = val7.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.advanceToSegment = (Segment)(byte)result2; fires++; } } else if (text12.StartsWith("i=")) { string[] array5 = text12.Substring(2).Split(':'); Transform val8 = (((Object)(object)stepRoot != (Object)null) ? stepRoot.Find("Inside") : null); if (array5.Length == 3 && (Object)(object)val8 != (Object)null) { val8.localPosition = new Vector3(P(array5[0]), P(array5[1]), P(array5[2])); } } else if (text12.StartsWith("r=") || text12.StartsWith("w=")) { _laterWorld.Add(new KeyValuePair(val7, text12)); } else if (text12.Length > 1 && text12[0] == 'M') { string[] array6 = text12.Substring(1).Split(new char[1] { ':' }, 3); if (array6.Length != 3 || !int.TryParse(array6[1], out var result3)) { continue; } Transform val9 = NavigateIdx(transform, array6[0]); Renderer val10 = (((Object)(object)val9 != (Object)null) ? ((Component)val9).GetComponent() : null); Material val11 = (((Object)(object)val10 != (Object)null) ? MaterialNear(stepRoot, flag ? propLocal : stepLocal, array6[2]) : null); if ((Object)(object)val11 != (Object)null) { Material[] sharedMaterials = val10.sharedMaterials; if (result3 >= 0 && result3 < sharedMaterials.Length) { sharedMaterials[result3] = val11; val10.sharedMaterials = sharedMaterials; mats++; } } } else { if (text12.Length <= 1 || text12[0] != 'A') { continue; } string[] array7 = text12.Substring(1).Split(':'); if (array7.Length == 2) { Transform val12 = NavigateIdx(transform, array7[0]); if ((Object)(object)val12 != (Object)null) { ((Component)val12).gameObject.SetActive(array7[1] == "1"); toggles++; } } } } if (!flag) { if (text8.EndsWith(" (spawner)") && (Object)(object)stepRoot != (Object)null) { PropSpawner[] components2 = ((Component)stepRoot).GetComponents(); foreach (PropSpawner val13 in components2) { if (val13.modifiers == null) { continue; } foreach (PropSpawnerMod modifier in val13.modifiers) { PSM_SingleItemSpawner val14 = (PSM_SingleItemSpawner)(object)((modifier is PSM_SingleItemSpawner) ? modifier : null); if (val14 != null) { try { ((PropSpawnerMod)val14).ModifyObject(val7, (SpawnData)null); } catch (Exception ex3) { Plugin.Detail("[FinalAscent] Item-Spawner '" + text8 + "': " + ex3.Message); } } } } } lastProp = transform; made++; propLocal = WithDecorLists(stepLocal ?? new Dictionary(), transform); HarvestDecorSpawners(val7); } else { decor++; } int j = sinceYield + 1; sinceYield = j; if (j >= 250) { sinceYield = 0; FinalAscentLoadHud.Detail($"Karte auspacken: {made + decor} Objekte"); yield return null; } } Physics.SyncTransforms(); Plugin.Log.LogInfo((object)(string.Format("{0} {1} Sektions-Schritte nach Abraeumliste des Hosts ", "[FinalAscent]", sweptSteps) + $"geleert ({sweptKids} gebackene Kinder), {towers} Stapler gestellt. " + $"Materialien: {_matStep} sektions-lokal, {_matHome} biom-lokal, " + $"{_matAfar} global. Vorlagen: " + $"{_prefLocal} sektions-lokal, {_prefHome} biom-lokal, {_prefAfar} global.")); if (_afarNames.Count > 0) { List> list = new List>(_afarNames); list.Sort((KeyValuePair a, KeyValuePair b) => b.Value.CompareTo(a.Value)); Plugin.Log.LogWarning((object)"[FinalAscent] GLOBAL aufgeloeste Vorlagen (Identitaet ungesichert - Kandidaten fuer falsche Felsen):"); for (int num4 = 0; num4 < list.Count && num4 < 8; num4++) { Plugin.Log.LogWarning((object)string.Format("{0} {1,5}x '{2}'", "[FinalAscent]", list[num4].Value, list[num4].Key)); } } if (misprints.Count > 0) { Plugin.Log.LogWarning((object)(string.Format("{0} SCHRITT-ABGLEICH: {1} von ", "[FinalAscent]", misprints.Count) + $"{printsOk + misprints.Count} Sektionen weichen vom Host ab:")); for (int num5 = 0; num5 < misprints.Count && num5 < 12; num5++) { Plugin.Log.LogWarning((object)("[FinalAscent] " + misprints[num5])); } } else if (printsOk > 0) { Plugin.Log.LogInfo((object)(string.Format("{0} SCHRITT-ABGLEICH: alle {1} Sektionen decken sich ", "[FinalAscent]", printsOk) + "mit dem Host - Position fuer Position.")); } FinalAscentTowerStackerPatch.WakeSink = null; FinalAscentPaint.EndApply(paintLines); FinalAscentFakeItems.EndApply(shelfLines); Plugin.Log.LogInfo((object)(string.Format("{0} KARTE AUSGEPACKT: {1} Props, {2} Dekor, {3} ", "[FinalAscent]", made, decor, mats) + $"Material-Slots, {toggles} Schalter, {fires} Lagerfeuer-Ziele, " + $"{_laterWorld.Count} Weltteile vorgemerkt" + ((orphans > 0) ? $", {orphans} Eintraege ausgefallen" : "") + ". Die Insel ist die des Hosts - per Konstruktion.")); if (orphans > 0) { Plugin.Log.LogWarning((object)(string.Format("{0} Ausfaelle: {1} ohne Schritt in der Szene, ", "[FinalAscent]", noStep) + $"{noParent} ohne Elternteil, {orphans - noStep - noParent} ohne Vorlage.")); List> list2 = new List>(missing); list2.Sort((KeyValuePair a, KeyValuePair b) => b.Value.CompareTo(a.Value)); for (int num6 = 0; num6 < list2.Count && num6 < 12; num6++) { Plugin.Log.LogWarning((object)string.Format("{0} {1,5}x Vorlage fehlt: '{2}'", "[FinalAscent]", list2[num6].Value, list2[num6].Key)); } } } private static void LayGround() { int num = 0; foreach (string item in _laterGround) { try { string[] array = item.Substring(1).Split('|'); if (array.Length < 6) { continue; } Transform val = FindByPath(array[0]); HeightmapMesh val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if ((Object)(object)val2 == (Object)null) { Plugin.Log.LogWarning((object)("[FinalAscent] Hoehenkarte fuer '" + array[0] + "' laesst sich nicht legen - kein HeightmapMesh an dieser Stelle.")); continue; } int num2 = int.Parse(array[3], CultureInfo.InvariantCulture); int num3 = int.Parse(array[4], CultureInfo.InvariantCulture); string[] array2 = array[5].Split(','); if (array2.Length != num2 * num3) { Plugin.Log.LogWarning((object)("[FinalAscent] Hoehenkarte fuer '" + array[0] + "' ist unvollstaendig " + $"({array2.Length} statt {num2 * num3} Werte) - uebersprungen.")); continue; } float[,] array3 = new float[num2, num3]; int num4 = 0; for (int i = 0; i < num2; i++) { for (int j = 0; j < num3; j++) { array3[i, j] = P(array2[num4++]); } } val2.cellSize = P(array[1]); val2.center = array[2] == "1"; val2.Generate(array3); MeshFilter component = ((Component)val).GetComponent(); MeshCollider component2 = ((Component)val).GetComponent(); if ((Object)(object)component2 != (Object)null && (Object)(object)component != (Object)null) { component2.sharedMesh = null; component2.sharedMesh = component.sharedMesh; Plugin.Detail("[FinalAscent] Kollider von '" + array[0] + "' neu gekocht - sonst traegt er die Form, die dieser Rechner selbst erstrahlt hatte."); } FinalAscentHeightmap.MarkDelivered(val2); num++; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Hoehenkarte liess sich nicht legen: " + ex.Message)); } } if (_laterGround.Count > 0) { Plugin.Log.LogInfo((object)(string.Format("{0} {1} von {2} Hoehenkarte(n) gelegt - ", "[FinalAscent]", num, _laterGround.Count) + "der Sumpfboden hat jetzt die Form des Hosts.")); } _laterGround.Clear(); } private static void BuildWorldPieces() { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown int num = 0; int num2 = 0; foreach (KeyValuePair item in _laterWorld) { GameObject key = item.Key; string value = item.Value; if ((Object)(object)key == (Object)null) { continue; } try { if (value.StartsWith("r=")) { LavaRiver componentInChildren = key.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { num += BuildRiver(componentInChildren, value.Substring(2)); } continue; } string[] array = value.Substring(2).Split(':'); WaterFallConfig val = ((array.Length == 4) ? key.GetComponentInChildren(true) : null); if (!((Object)(object)val == (Object)null)) { if ((Object)(object)val.endRock != (Object)null) { val.endRock.position = new Vector3(P(array[0]), P(array[1]), P(array[2])); } float num3 = P(array[3]); if ((Object)(object)val.mesh != (Object)null && num3 != 0f) { MaterialPropertyBlock val2 = new MaterialPropertyBlock(); ((Renderer)val.mesh).GetPropertyBlock(val2); val2.SetFloat("_WorldPositionY", num3); ((Renderer)val.mesh).SetPropertyBlock(val2); } num2++; } } catch (Exception ex) { Plugin.Detail("[FinalAscent] '" + ((Object)key).name + "' baut nicht: " + ex.Message); } } Plugin.Log.LogInfo((object)string.Format("{0} Nach dem Versatz gestellt: {1} Splines, {2} Wasserlinien.", "[FinalAscent]", num, num2)); _laterWorld.Clear(); Physics.SyncTransforms(); } private static void SpanVines() { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) int num = 0; int num2 = 0; foreach (string laterVine in _laterVines) { int num3 = laterVine.LastIndexOf('|'); if (num3 <= 1) { continue; } string text = laterVine.Substring(1, num3 - 1); string[] array = laterVine.Substring(num3 + 1).Split(':'); Transform val = ((array.Length == 10) ? FindByPath(text) : null); JungleVine val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if ((Object)(object)val2 == (Object)null) { num2++; Plugin.Detail("[FinalAscent] Ranke '" + text + "' fehlt in dieser Szene."); continue; } try { Transform transform = ((Component)val2).transform; FinalAscentVineLog.Replaying = true; val2.ForceBuildVine(transform.TransformPoint(new Vector3(P(array[0]), P(array[1]), P(array[2]))), transform.TransformPoint(new Vector3(P(array[3]), P(array[4]), P(array[5]))), P(array[6]), transform.TransformPoint(new Vector3(P(array[7]), P(array[8]), P(array[9])))); num++; } catch (Exception ex) { num2++; Plugin.Detail("[FinalAscent] Ranke '" + text + "' spannt sich nicht: " + ex.Message); } finally { FinalAscentVineLog.Replaying = false; } } Plugin.Log.LogInfo((object)(string.Format("{0} {1} Ranken mit den Baudaten des Hosts gespannt", "[FinalAscent]", num) + ((num2 > 0) ? $", {num2} nicht auffindbar." : "."))); _laterVines.Clear(); } private static void OfferMats(Dictionary map, object one) { if (one == null) { return; } FieldInfo[] fields = one.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { object value; try { value = fieldInfo.GetValue(one); } catch { continue; } Material val = (Material)((value is Material) ? value : null); if (val != null) { if ((Object)(object)val != (Object)null && !map.ContainsKey(((Object)val).name)) { map[((Object)val).name] = val; } } else { if (!(value is IEnumerable enumerable) || value is string) { continue; } try { foreach (object item in enumerable) { Material val2 = (Material)((item is Material) ? item : null); if (val2 != null && (Object)(object)val2 != (Object)null && !map.ContainsKey(((Object)val2).name)) { map[((Object)val2).name] = val2; } } } catch { } } } } private static Dictionary SectionMats(Transform stepRoot, Dictionary local) { if ((Object)(object)stepRoot == (Object)null) { return null; } if (_stepMats.TryGetValue(stepRoot, out var value)) { return value; } value = new Dictionary(); LevelGenStep[] components = ((Component)stepRoot).GetComponents(); foreach (LevelGenStep val in components) { if ((Object)(object)val == (Object)null) { continue; } OfferMats(value, val); PropSpawner val2 = (PropSpawner)(object)((val is PropSpawner) ? val : null); if (val2 == null) { continue; } if (val2.modifiers != null) { foreach (PropSpawnerMod modifier in val2.modifiers) { OfferMats(value, modifier); } } IEnumerable postSpawnBehaviors = val2.postSpawnBehaviors; if (postSpawnBehaviors == null) { continue; } foreach (object item in postSpawnBehaviors) { OfferMats(value, item); } } if (local != null) { foreach (GameObject value2 in local.Values) { if ((Object)(object)value2 == (Object)null) { continue; } Renderer[] componentsInChildren = value2.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Material[] sharedMaterials = componentsInChildren[i].sharedMaterials; foreach (Material val3 in sharedMaterials) { if ((Object)(object)val3 != (Object)null && !value.ContainsKey(((Object)val3).name)) { value[((Object)val3).name] = val3; } } } } } _stepMats[stepRoot] = value; return value; } private static Material MaterialNear(Transform stepRoot, Dictionary local, string matName) { Dictionary dictionary = SectionMats(stepRoot, local); if (dictionary != null && dictionary.TryGetValue(matName, out var value)) { _matStep++; return value; } Biome val = (((Object)(object)stepRoot != (Object)null) ? ((Component)stepRoot).GetComponentInParent(true) : null); if ((Object)(object)val != (Object)null) { if (!_biomeMats.TryGetValue(((Component)val).transform, out var value2)) { value2 = new Dictionary(); Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null) { continue; } Material[] sharedMaterials = val2.sharedMaterials; foreach (Material val3 in sharedMaterials) { if ((Object)(object)val3 != (Object)null && !value2.ContainsKey(((Object)val3).name)) { value2[((Object)val3).name] = val3; } } } _biomeMats[((Component)val).transform] = value2; } if (value2.TryGetValue(matName, out var value3)) { _matHome++; return value3; } } if (_materials.TryGetValue(matName, out var value4)) { _matAfar++; return value4; } return null; } private static void BuildResolver() { _prefabs.Clear(); _materials.Clear(); _mined.Clear(); PropSpawner[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (PropSpawner val in array) { if (!((Object)(object)val == (Object)null)) { Offer(val.props); if ((Object)(object)val.overridePropsList != (Object)null) { Offer(val.overridePropsList.gameObjects); } } } SpawnList[] array2 = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); for (int i = 0; i < array2.Length; i++) { OfferList(array2[i]); } DecorSpawner[] array3 = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (DecorSpawner val2 in array3) { if ((Object)(object)val2 != (Object)null) { Offer(val2.props); } } Renderer[] array4 = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Renderer val3 in array4) { if ((Object)(object)val3 == (Object)null) { continue; } Material[] sharedMaterials = val3.sharedMaterials; foreach (Material val4 in sharedMaterials) { if ((Object)(object)val4 != (Object)null && !_materials.ContainsKey(((Object)val4).name)) { _materials[((Object)val4).name] = val4; } } } Plugin.Log.LogInfo((object)(string.Format("{0} Aufloeser bereit: {1} Prefabs, ", "[FinalAscent]", _prefabs.Count) + $"{_materials.Count} Materialien.")); } private static void HarvestDecorSpawners(GameObject prop) { DecorSpawner[] componentsInChildren = prop.GetComponentsInChildren(true); foreach (DecorSpawner val in componentsInChildren) { if ((Object)(object)val != (Object)null) { Offer(val.props); } } } private static void Offer(GameObject[] list) { if (list == null) { return; } foreach (GameObject val in list) { if ((Object)(object)val != (Object)null && !_prefabs.ContainsKey(((Object)val).name + "(Clone)")) { _prefabs[((Object)val).name + "(Clone)"] = val; } } } private static void OfferList(SpawnList list) { if ((Object)(object)list == (Object)null || list.items == null) { return; } foreach (SpawnEntry item in list.items) { if (item != null && (Object)(object)item.prefab != (Object)null && !_prefabs.ContainsKey(((Object)item.prefab).name + "(Clone)")) { _prefabs[((Object)item.prefab).name + "(Clone)"] = item.prefab; } } } private static Dictionary LocalPrefabs(Transform stepRoot) { Dictionary dictionary = new Dictionary(); LevelGenStep[] components = ((Component)stepRoot).GetComponents(); foreach (LevelGenStep obj in components) { PropSpawner val = (PropSpawner)(object)((obj is PropSpawner) ? obj : null); if (val != null) { AddTo(dictionary, val.props); if ((Object)(object)val.overridePropsList != (Object)null) { AddTo(dictionary, val.overridePropsList.gameObjects); } ReflectInto(dictionary, val.modifiers); ReflectInto(dictionary, val.postSpawnBehaviors); } DecorSpawner val2 = (DecorSpawner)(object)((obj is DecorSpawner) ? obj : null); if (val2 != null) { AddTo(dictionary, val2.props); } DesertRockSpawner val3 = (DesertRockSpawner)(object)((obj is DesertRockSpawner) ? obj : null); if (val3 != null) { AddTo(dictionary, val3.blockerObjects); AddTo(dictionary, val3.enterenceObjects); } } return dictionary; } private static void ReflectInto(Dictionary map, IEnumerable bag) { if (bag == null) { return; } foreach (object item in bag) { if (item == null) { continue; } FieldInfo[] fields = item.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { object value; try { value = fieldInfo.GetValue(item); } catch { continue; } GameObject val = (GameObject)((value is GameObject) ? value : null); if (val != null) { OfferOne(val); if (!map.ContainsKey(((Object)val).name + "(Clone)")) { map[((Object)val).name + "(Clone)"] = val; } } else if (value is GameObject[] list) { AddTo(map, list); Offer(list); } } } } private static Dictionary WithDecorLists(Dictionary local, Transform prop) { Dictionary dictionary = new Dictionary(local); DecorSpawner[] componentsInChildren = ((Component)prop).GetComponentsInChildren(true); foreach (DecorSpawner val in componentsInChildren) { if ((Object)(object)val != (Object)null) { AddTo(dictionary, val.props); } } return dictionary; } private static void AddTo(Dictionary map, GameObject[] list) { if (list == null) { return; } foreach (GameObject val in list) { if ((Object)(object)val != (Object)null && !map.ContainsKey(((Object)val).name + "(Clone)")) { map[((Object)val).name + "(Clone)"] = val; } } } private static GameObject ResolveWith(Dictionary local, string name) { if (local != null && local.TryGetValue(name, out var value)) { MinePrefab(value); return value; } return Resolve(name); } private static GameObject ResolveNear(Dictionary local, string name, Transform stepRoot) { if (local != null && local.TryGetValue(name, out var value)) { _prefLocal++; MinePrefab(value); return value; } Biome val = (((Object)(object)stepRoot != (Object)null) ? ((Component)stepRoot).GetComponentInParent(true) : null); if ((Object)(object)val != (Object)null) { if (!_biomePrefabs.TryGetValue(((Component)val).transform, out var value2)) { value2 = new Dictionary(); PropSpawner[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (PropSpawner val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null)) { AddTo(value2, val2.props); if ((Object)(object)val2.overridePropsList != (Object)null) { AddTo(value2, val2.overridePropsList.gameObjects); } } } DecorSpawner[] componentsInChildren2 = ((Component)val).GetComponentsInChildren(true); foreach (DecorSpawner val3 in componentsInChildren2) { if ((Object)(object)val3 != (Object)null) { AddTo(value2, val3.props); } } _biomePrefabs[((Component)val).transform] = value2; } if (value2.TryGetValue(name, out var value3)) { _prefHome++; MinePrefab(value3); return value3; } } GameObject obj = Resolve(name); if ((Object)(object)obj != (Object)null) { _prefAfar++; _afarNames.TryGetValue(name, out var value4); _afarNames[name] = value4 + 1; } return obj; } internal static string ScenePathOf(Transform leaf) { List list = new List(); Transform val = leaf; while ((Object)(object)val != (Object)null) { list.Insert(0, ((Object)(object)val.parent != (Object)null) ? RelName(val.parent, val) : ((Object)val).name); val = val.parent; } return string.Join("/", list); } private static Transform NavigateIdx(Transform root, string idxPath) { if (string.IsNullOrEmpty(idxPath)) { return root; } Transform val = root; string[] array = idxPath.Split(','); for (int i = 0; i < array.Length; i++) { if (!int.TryParse(array[i], out var result) || result < 0 || result >= val.childCount) { return null; } val = val.GetChild(result); } return val; } private static GameObject Resolve(string cloneName) { if (_prefabs.TryGetValue(cloneName, out var value)) { MinePrefab(value); return value; } return null; } private static void MinePrefab(GameObject prefab) { if ((Object)(object)prefab == (Object)null || !_mined.Add(((Object)prefab).name)) { return; } try { MonoBehaviour[] componentsInChildren = prefab.GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } FieldInfo[] fields = ((object)val).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { object value; try { value = fieldInfo.GetValue(val); } catch { continue; } GameObject val2 = (GameObject)((value is GameObject) ? value : null); if (val2 != null) { OfferOne(val2); } else if (value is GameObject[] list) { Offer(list); } else { if (!(value is List list2)) { continue; } foreach (GameObject item in list2) { OfferOne(item); } } } } } catch (Exception ex) { Plugin.Detail("[FinalAscent] Erzen von '" + ((Object)prefab).name + "' gestolpert: " + ex.Message); } } private static void OfferOne(GameObject one) { if ((Object)(object)one != (Object)null && !_prefabs.ContainsKey(((Object)one).name + "(Clone)")) { _prefabs[((Object)one).name + "(Clone)"] = one; } } private static bool ApplyMaterial(GameObject born, string matName) { if (!_materials.TryGetValue(matName, out var value)) { return false; } Renderer componentInChildren = born.GetComponentInChildren(); if ((Object)(object)componentInChildren == (Object)null) { return false; } componentInChildren.sharedMaterial = value; return true; } private static List OrderedSteps() { List list = new List(); List list2 = new List(); LevelGenStep[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (LevelGenStep val in array) { if ((Object)(object)val == (Object)null) { continue; } bool flag = false; Transform parent = ((Component)val).transform.parent; while ((Object)(object)parent != (Object)null) { if (((Object)parent).name.EndsWith("(Clone)")) { flag = true; break; } parent = parent.parent; } (flag ? list2 : list).Add(((Component)val).transform); } list.Sort((Transform a, Transform b) => string.CompareOrdinal(PathOf(a), PathOf(b))); list2.Sort((Transform a, Transform b) => string.CompareOrdinal(PathOf(a), PathOf(b))); list.AddRange(list2); return list; } private static int BuildRiver(LavaRiver river, string data) { //IL_0057: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_01b4: Unknown result type (might be due to invalid IL or missing references) int num = data.IndexOf('#'); if (num < 0) { return 0; } string[] array = data.Substring(0, num).Split(':'); List list = new List(); string[] array2 = data.Substring(num + 1).Split(';'); for (int i = 0; i < array2.Length; i++) { string[] array3 = array2[i].Split(','); if (array3.Length >= 9) { list.Add(new LavaRiverFrame { position = new Vector3(P(array3[0]), P(array3[1]), P(array3[2])), up = new Vector3(P(array3[3]), P(array3[4]), P(array3[5])), forward = new Vector3(P(array3[6]), P(array3[7]), P(array3[8])) }); } } if (list.Count < 2) { return 0; } river.frames = list; river.Apply(); AccessTools.Method(typeof(LavaRiver), "AddLights", (Type[])null, (Type[])null)?.Invoke(river, null); AccessTools.Method(typeof(LavaRiver), "addAlongSpline", (Type[])null, (Type[])null)?.Invoke(river, null); if ((Object)(object)river.spawnAlongSpline != (Object)null) { AccessTools.Method(typeof(LavaRiver), "SpawnItemsAlongSpline", (Type[])null, (Type[])null)?.Invoke(river, null); } if ((Object)(object)river.endRock != (Object)null && array.Length == 4) { river.endRock.transform.rotation = new Quaternion(P(array[0]), P(array[1]), P(array[2]), P(array[3])); } return 1; } private static string Whereabouts(string path) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) string[] array = path.Split('/'); GameObject val = null; Scene activeScene = SceneManager.GetActiveScene(); GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects(); foreach (GameObject val2 in rootGameObjects) { if (((Object)val2).name == array[0]) { val = val2; break; } } if ((Object)(object)val == (Object)null) { return "schon die Wurzel '" + array[0] + "' gibt es nicht."; } Transform val3 = val.transform; for (int j = 1; j < array.Length; j++) { Transform val4 = FindRelative(val3, array[j], single: true); if ((Object)(object)val4 == (Object)null) { StringBuilder stringBuilder = new StringBuilder(); int num = 0; for (int k = 0; k < val3.childCount; k++) { if (num >= 8) { break; } if (stringBuilder.Length > 0) { stringBuilder.Append(", "); } stringBuilder.Append(((Object)val3.GetChild(k)).name); num++; } return "riss bei '" + array[j] + "'; unter '" + ((Object)val3).name + "' stehen " + $"{val3.childCount} Kinder: {stringBuilder}" + ((val3.childCount > num) ? ", ..." : "") + "."; } val3 = val4; } return "der Pfad stimmt inzwischen wieder - ein Wettlauf?"; } internal static Transform FindByPathPublic(string path) { return FindByPath(path); } private static Transform FindByPath(string path) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) string[] array = path.Split('/'); GameObject val = null; Scene activeScene = SceneManager.GetActiveScene(); GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects(); foreach (GameObject val2 in rootGameObjects) { if (((Object)val2).name == array[0]) { val = val2; break; } } if ((Object)(object)val == (Object)null) { return null; } Transform val3 = val.transform; for (int j = 1; j < array.Length; j++) { val3 = FindRelative(val3, array[j], single: true); if ((Object)(object)val3 == (Object)null) { return null; } } return val3; } private static Transform FindRelative(Transform at, string relPath, bool single = false) { if (string.IsNullOrEmpty(relPath)) { return at; } string[] array = ((!single) ? relPath.Split('/') : new string[1] { relPath }); foreach (string text in array) { string text2 = text; int num = 0; int num2 = text.LastIndexOf('#'); if (num2 > 0 && int.TryParse(text.Substring(num2 + 1), out var result)) { text2 = text.Substring(0, num2); num = result; } Transform val = null; int num3 = 0; for (int j = 0; j < at.childCount; j++) { Transform child = at.GetChild(j); if (((Object)child).name == text2) { if (num3 == num) { val = child; break; } num3++; } } if ((Object)(object)val == (Object)null) { return null; } at = val; } return at; } private static string PathOf(Transform leaf) { StringBuilder stringBuilder = new StringBuilder(((Object)leaf).name); Transform parent = leaf.parent; while ((Object)(object)parent != (Object)null) { stringBuilder.Insert(0, '/').Insert(0, ((Object)parent).name); parent = parent.parent; } return stringBuilder.ToString(); } private static string F(float value) { return value.ToString("R", CultureInfo.InvariantCulture); } private static string C(float value) { return value.ToString("F3", CultureInfo.InvariantCulture); } private static float P(string value) { return float.Parse(value, CultureInfo.InvariantCulture); } private static byte[] Zip(string text) { using MemoryStream memoryStream = new MemoryStream(); using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionLevel.Optimal)) { byte[] bytes = Encoding.UTF8.GetBytes(text); gZipStream.Write(bytes, 0, bytes.Length); } return memoryStream.ToArray(); } private static string Unzip(byte[] packed) { using MemoryStream stream = new MemoryStream(packed); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); gZipStream.CopyTo(memoryStream); return Encoding.UTF8.GetString(memoryStream.ToArray()); } } [HarmonyPatch(typeof(DestroyBasedOnPlayerCount), "Start")] internal static class FinalAscentDespawn { private const string Tag = "[FinalAscent]"; private static int _removed; private static float _lastReport; private static bool Prefix(DestroyBasedOnPlayerCount __instance, ref IEnumerator __result) { if (!FinalAscent.Active || PhotonNetwork.IsMasterClient) { return true; } __result = Decide(__instance); return false; } private static IEnumerator Decide(DestroyBasedOnPlayerCount one) { while (!PhotonNetwork.InRoom) { yield return null; } if (!((Object)(object)one == (Object)null) && PhotonNetwork.PlayerList.Length < one.destroyIfPlayerCountIsLessThan) { Plugin.Detail(string.Format("{0} Ausgeduennt (unter {1} Spielern): ", "[FinalAscent]", one.destroyIfPlayerCountIsLessThan) + PathOf(((Component)one).transform)); Object.Destroy((Object)(object)((Component)one).gameObject); _removed++; if (Time.realtimeSinceStartup - _lastReport > 3f) { _lastReport = Time.realtimeSinceStartup; Plugin.Log.LogInfo((object)(string.Format("{0} Spielerzahl-Ausduennung: {1} Objekte entfernt ", "[FinalAscent]", _removed) + $"(unter {PhotonNetwork.PlayerList.Length + 1} Spielern) - " + "dieselbe Regel wie beim Host, ohne Uebertragung.")); } } } private static string PathOf(Transform leaf) { StringBuilder stringBuilder = new StringBuilder(((Object)leaf).name); Transform parent = leaf.parent; while ((Object)(object)parent != (Object)null) { stringBuilder.Insert(0, '/').Insert(0, ((Object)parent).name); parent = parent.parent; } return stringBuilder.ToString(); } } [HarmonyPatch(typeof(DesertRockSpawner), "ExecuteImmediately")] internal static class FinalAscentMesaDiceSpy { private const string Tag = "[FinalAscent]"; private static void Prefix(DesertRockSpawner __instance) { Note(__instance, "ExecuteImmediately"); } internal static void Note(DesertRockSpawner one, string how) { if (!FinalAscent.Active || (Object)(object)one == (Object)null) { return; } string text = ""; try { StackTrace stackTrace = new StackTrace(2, fNeedFileInfo: false); for (int i = 0; i < stackTrace.FrameCount && i < 4; i++) { MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod(); if (methodBase != null) { text = text + ((text.Length > 0) ? " <- " : "") + methodBase.DeclaringType?.Name + "." + methodBase.Name; } } } catch { text = "unlesbar"; } Plugin.Log.LogWarning((object)("[FinalAscent] MESA-WUERFEL: DesertRockSpawner '" + ((Object)one).name + "' laeuft (" + how + "), gerufen von: " + text)); } } [HarmonyPatch(typeof(DesertRockSpawner), "Run")] internal static class FinalAscentMesaDiceSpyRun { private static void Prefix(DesertRockSpawner __instance) { FinalAscentMesaDiceSpy.Note(__instance, "Run"); } } [HarmonyPatch(typeof(DesertRockSpawner), "Execute")] internal static class FinalAscentMesaDiceSpyExecute { private static void Prefix(DesertRockSpawner __instance) { FinalAscentMesaDiceSpy.Note(__instance, "Execute"); } } [HarmonyPatch(typeof(MovingSawBlade), "Start")] internal static class FinalAscentSawSpy { private static void Postfix(MovingSawBlade __instance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (FinalAscent.Active && !((Object)(object)__instance == (Object)null)) { Vector3 position = ((Component)__instance).transform.position; Plugin.Log.LogInfo((object)("[FinalAscent] SAEGE-START: '" + ((Object)__instance).name + "' bei " + $"({position.x:F2} / {position.y:F2} / {position.z:F2}), Phasen-Anker {position.x + position.y + position.z:F2}")); } } } [HarmonyPatch(typeof(DestroyBasedOnPlayerCount), "Start")] internal static class FinalAscentDespawnCount { private const string Tag = "[FinalAscent]"; private static int _removed; private static float _lastReport; private static void Postfix(DestroyBasedOnPlayerCount __instance) { if (FinalAscent.Active && PhotonNetwork.IsMasterClient && !((Object)(object)__instance == (Object)null) && PhotonNetwork.InRoom && PhotonNetwork.PlayerList.Length < __instance.destroyIfPlayerCountIsLessThan) { _removed++; if (Time.realtimeSinceStartup - _lastReport > 3f) { _lastReport = Time.realtimeSinceStartup; Plugin.Log.LogInfo((object)(string.Format("{0} Spielerzahl-Ausduennung: {1} Objekte abgerissen ", "[FinalAscent]", _removed) + "(Vanillas Weg, als Master).")); } } } } internal static class FinalAscentDiceWatch { private const string Tag = "[FinalAscent]"; private const int Ceiling = 60000; internal static bool Armed; private static readonly Dictionary Dice = new Dictionary(); private static readonly Dictionary Rays = new Dictionary(); private static int _looked; private static int _diceTotal; private static int _rayTotal; internal static bool Watching { get { if (FinalAscent.Active) { return FinalAscentBuilder.Building; } return false; } } internal static void Reset() { Dice.Clear(); Rays.Clear(); _looked = 0; _diceTotal = 0; _rayTotal = 0; } internal static void NoteDice() { _diceTotal++; Add(Dice); } internal static void NoteRay() { _rayTotal++; Add(Rays); } private static void Add(Dictionary book) { if (_looked < 60000) { _looked++; string key = Caller(); book.TryGetValue(key, out var value); book[key] = value + 1; } } private static string Caller() { try { StackTrace stackTrace = new StackTrace(2, fNeedFileInfo: false); for (int i = 0; i < stackTrace.FrameCount && i < 12; i++) { MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod(); Type type = methodBase?.DeclaringType; if (type == null) { continue; } string text = type.Namespace ?? ""; if (!text.StartsWith("UnityEngine", StringComparison.Ordinal) && !text.StartsWith("HarmonyLib", StringComparison.Ordinal) && !text.StartsWith("MonoMod", StringComparison.Ordinal) && !type.Name.StartsWith("FinalAscentDiceWatch", StringComparison.Ordinal) && !(type.Name == "HelperFunctions")) { string text2 = type.Name; if (text2.Length > 0 && text2[0] == '<' && type.DeclaringType != null) { text2 = type.DeclaringType.Name + "." + text2; } return text2 + "." + methodBase.Name; } } } catch { } return "unlesbar"; } internal static void Report() { if (!Armed) { Plugin.Detail("[FinalAscent] Wuerfel-Melder war aus - keine Messdatei."); return; } try { StringBuilder stringBuilder = new StringBuilder(65536); stringBuilder.Append("# Wer hat waehrend des Bauens gewuerfelt oder gestrahlt?\n"); stringBuilder.Append("# Der Host DARF beides - er erzeugt die Wahrheit.\n"); stringBuilder.Append("# Beim Gast ist jede Zeile ein Verdacht: dort entscheidet\n"); stringBuilder.Append("# trotz ausgeliefertem Inselimage noch jemand selbst.\n"); stringBuilder.Append("# Rolle: ").Append(PhotonNetwork.IsMasterClient ? "HOST" : "GAST").Append('\n'); Section(stringBuilder, "WUERFEL", Dice, _diceTotal); Section(stringBuilder, "STRAHLEN", Rays, _rayTotal); File.WriteAllText(FinalAscentStore.Note("TrueFinalAscent.Wuerfel.txt"), stringBuilder.ToString()); Plugin.Log.LogInfo((object)(string.Format("{0} WUERFEL-MELDER: {1} Wuerfe aus {2} Quellen, ", "[FinalAscent]", _diceTotal, Dice.Count) + $"{_rayTotal} Strahlen aus {Rays.Count} Quellen " + "(TrueFinalAscent.Wuerfel.txt).")); Loudest("Wuerfel", Dice); Loudest("Strahlen", Rays); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Wuerfel-Melder konnte nicht schreiben: " + ex.Message)); } } private static void Section(StringBuilder text, string title, Dictionary book, int total) { text.Append('\n').Append("## ").Append(title) .Append(" (") .Append(total) .Append(" Aufrufe, ") .Append(book.Count) .Append(" Quellen)\n"); text.Append("# Zuordnung aus den ersten ").Append(60000).Append(" Aufrufen beider Buecher - Rangfolge gilt, ") .Append("absolute Zahlen sind anteilig.\n"); List> list = new List>(book); list.Sort((KeyValuePair a, KeyValuePair b) => (b.Value == a.Value) ? string.CompareOrdinal(a.Key, b.Key) : b.Value.CompareTo(a.Value)); foreach (KeyValuePair item in list) { text.Append(item.Value).Append('\t').Append(item.Key) .Append('\n'); } } private static void Loudest(string title, Dictionary book) { List> list = new List>(book); list.Sort((KeyValuePair a, KeyValuePair b) => b.Value.CompareTo(a.Value)); for (int num = 0; num < list.Count && num < 8; num++) { Plugin.Log.LogInfo((object)string.Format("{0} {1}: {2,8}x {3}", "[FinalAscent]", title, list[num].Value, list[num].Key)); } } } internal static class FinalAscentDiceWatchSetup { private const string Tag = "[FinalAscent]"; private const bool Wanted = false; private static readonly HashSet RayNames = new HashSet { "Raycast", "RaycastAll", "RaycastNonAlloc", "Linecast", "SphereCast", "SphereCastAll", "SphereCastNonAlloc", "BoxCast", "BoxCastAll", "BoxCastNonAlloc", "CapsuleCast", "CapsuleCastAll", "CapsuleCastNonAlloc", "OverlapSphere", "OverlapSphereNonAlloc", "OverlapBox", "OverlapBoxNonAlloc", "OverlapCapsule", "OverlapCapsuleNonAlloc", "CheckSphere", "CheckBox", "CheckCapsule" }; internal static void Install(Harmony harmony) { FinalAscentDiceWatch.Armed = false; Plugin.Detail("[FinalAscent] Wuerfel-Melder ist aus - er haengt sich an keinen einzigen Eingang."); } private static int Hook(Harmony harmony, Type home, Func wanted, string prefixName) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(FinalAscentDiceWatchSetup), prefixName, (Type[])null, (Type[])null); int num = 0; MethodInfo[] methods = home.GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo2 in methods) { if (!(methodInfo2 == null) && !methodInfo2.IsAbstract && !methodInfo2.ContainsGenericParameters && wanted(methodInfo2.Name)) { try { harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); num++; } catch (Exception ex) { Plugin.Detail("[FinalAscent] '" + home.Name + "." + methodInfo2.Name + "' liess sich nicht ueberwachen: " + ex.Message); } } } return num; } private static void DicePrefix() { if (FinalAscentDiceWatch.Watching) { FinalAscentDiceWatch.NoteDice(); } } private static void RayPrefix() { if (FinalAscentDiceWatch.Watching) { FinalAscentDiceWatch.NoteRay(); } } } internal static class FinalAscentDifficulty { private const string Tag = "[FinalAscent]"; internal const string RoomKey = "FAasc"; internal const int Lowest = -1; private static int _told = int.MinValue; internal static int Highest { get { try { Type type = AccessTools.TypeByName("AscentData"); PropertyInfo propertyInfo = ((type != null) ? AccessTools.Property(type.BaseType, "Instance") : null); object obj = ((propertyInfo != null) ? propertyInfo.GetValue(null) : null); IList list = ((obj != null) ? (AccessTools.Field(type, "ascents")?.GetValue(obj) as IList) : null); if (list != null && list.Count >= 3) { int num = list.Count - 3; if (num != _told) { _told = num; Plugin.Log.LogInfo((object)(string.Format("{0} Schwierigkeitsleiter: {1} Eintraege, ", "[FinalAscent]", list.Count) + $"hoechster Grad {num}. (Vanilla: 11 Eintraege, Grad 8 - " + "mehr heisst, eine Erweiterung hat verlaengert.)")); } return num; } } catch { } return 8; } } internal static int Chosen { get; set; } internal static string TitleOf(int ascent) { if (ascent <= -1) { return FinalAscentText.Get("ascent.tenderfoot"); } if (ascent == 0) { return FinalAscentText.Get("ascent.peak"); } return FinalAscentText.Get("ascent.n") + " " + ascent; } internal static void Publish(int ascent) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0038: Expected O, but got Unknown if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && PhotonNetwork.IsMasterClient) { Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"FAasc", (object)ascent); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)string.Format("{0} Schwierigkeit im Raum hinterlegt: {1} (Ascent {2}).", "[FinalAscent]", TitleOf(ascent), ascent)); } } internal static int FromRoom() { if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties != null && ((Dictionary)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"FAasc", out object value) && value is int) { return (int)value; } return int.MinValue; } internal static void Apply() { if (!FinalAscent.Active) { return; } int num = FromRoom(); if (num == int.MinValue) { Plugin.Log.LogInfo((object)("[FinalAscent] Kein Grad im Raum hinterlegt - es bleibt bei " + $"{TitleOf(Ascents.currentAscent)} (Ascent {Ascents.currentAscent}), " + "so wie der Ladebefehl ihn gebracht hat.")); Report(); return; } if (num < -1) { num = -1; } int highest = Highest; if (num > highest) { num = highest; } int currentAscent = Ascents.currentAscent; if (currentAscent == num) { Plugin.Log.LogInfo((object)string.Format("{0} Schwierigkeit steht schon auf {1} (Ascent {2}).", "[FinalAscent]", TitleOf(num), num)); Report(); } else { Ascents.currentAscent = num; Plugin.Log.LogInfo((object)(string.Format("{0} Schwierigkeit gesetzt: {1} (Ascent {2}, ", "[FinalAscent]", TitleOf(num), num) + $"vorher {currentAscent}). Fallschaden, Hunger, Gewicht, Fackeln, Kaelte, " + "Ausdauer und Fluch richten sich ab jetzt danach - alles Abfragen zur Laufzeit, deshalb gilt es auf unserem Berg genauso.")); Report(); } } internal static void Report() { try { bool isCustomRun = RunSettings.IsCustomRun; Plugin.Log.LogInfo((object)(string.Format("{0} SCHWIERIGKEIT WIRKT SO: Ascent {1} ", "[FinalAscent]", Ascents.currentAscent) + "(" + TitleOf(Ascents.currentAscent) + "), eigener Lauf: " + (isCustomRun ? "JA - dann zaehlen die Lauf-Einstellungen und NICHT der Ascent, das waere die Ursache" : "nein") + ".")); Plugin.Log.LogInfo((object)(string.Format("{0} Hunger x{1:F2} (ab Ascent 2 = 1,60) | ", "[FinalAscent]", Ascents.hungerRateMultiplier) + $"Traglast {Ascents.itemWeightModifier:+0;-0;0} (ab Ascent 3 = +1) | " + $"Fallschaden x{Ascents.fallDamageMultiplier:F1} (ab Ascent 1 = 2,0)")); Plugin.Log.LogInfo((object)("[FinalAscent] Kalte Nacht: " + (Ascents.isNightCold ? "an" : "aus") + " (ab Ascent 5; wirkt bis zum Mesa-Lagerfeuer und nur nachts) | Fackeln am Gipfel: " + (Ascents.shouldSpawnFlare ? "ja" : "nein") + " (ab Ascent 4 weg) | Nebel: " + (Ascents.fogEnabled ? "an" : "aus"))); Plugin.Log.LogInfo((object)(string.Format("{0} Startfluch {1:F2} (ab Ascent 7 = 0,10) | ", "[FinalAscent]", Ascents.startingCurse) + "Zombies: " + (Ascents.shouldSpawnZombie ? "ja" : "nein") + " | Sieg nur ueber Nadir: " + (Ascents.shouldRequireNadir ? "ja" : "nein") + " (ab Ascent 8)")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Schwierigkeitsbericht misslang: " + ex.Message)); } } } [HarmonyPatch(typeof(Ascents), "set_currentAscent")] internal static class FinalAscentAscentWatch { private const string Tag = "[FinalAscent]"; private static bool _busy; private static void Postfix(int value) { if (_busy) { return; } string text = Caller(); if (!FinalAscent.Active) { Plugin.Detail(string.Format("{0} Ascent auf {1} gesetzt von {2}.", "[FinalAscent]", value, text)); return; } int num = FinalAscentDifficulty.FromRoom(); if (num == int.MinValue || num == value) { Plugin.Log.LogInfo((object)(string.Format("{0} Ascent auf {1} gesetzt von {2}", "[FinalAscent]", value, text) + ((num == int.MinValue) ? " (im Raum steht noch nichts)." : "."))); return; } Plugin.Log.LogWarning((object)(string.Format("{0} {1} hat den Ascent auf {2} gedreht, im Raum steht aber ", "[FinalAscent]", text, value) + $"{num}. Der Raum gilt - zurueckgestellt. Wer hier auftaucht, ist der " + "Grund, warum Hunger, Gewicht und kalte Nacht nicht griffen.")); _busy = true; try { Ascents.currentAscent = num; } finally { _busy = false; } } private static string Caller() { try { StackTrace stackTrace = new StackTrace(2, fNeedFileInfo: false); for (int i = 0; i < stackTrace.FrameCount && i < 10; i++) { MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod(); Type type = methodBase?.DeclaringType; if (!(type == null)) { string text = type.Namespace ?? ""; if (!text.StartsWith("HarmonyLib", StringComparison.Ordinal) && !text.StartsWith("MonoMod", StringComparison.Ordinal) && !type.Name.StartsWith("FinalAscentAscentWatch", StringComparison.Ordinal) && !(type == typeof(Ascents))) { return type.Name + "." + methodBase.Name; } } } } catch { } return "unbekannt"; } } internal static class FinalAscentDoubleLoad { private const string Tag = "[FinalAscent]"; private const int Gap = 20000; private const int Show = 25; internal static void Report() { if (!Plugin.Diagnosing) { return; } try { PropSpawner[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); int num = 0; int num2 = 0; int num3 = 0; List list = new List(); PropSpawner[] array2 = array; foreach (PropSpawner val in array2) { if ((Object)(object)val == (Object)null || ((Component)val).transform.childCount == 0) { continue; } num++; list.Clear(); for (int j = 0; j < ((Component)val).transform.childCount; j++) { Transform child = ((Component)val).transform.GetChild(j); if ((Object)(object)child != (Object)null) { list.Add(((Object)((Component)child).gameObject).GetInstanceID()); } } if (list.Count < 2) { continue; } list.Sort(); int num4 = 1; int num5 = 1; int num6 = 0; for (int k = 1; k < list.Count; k++) { int num7 = list[k] - list[k - 1]; if (num7 > 20000) { num4++; if (num4 == 2) { num5 = k; num6 = num7; } } } if (num4 >= 2) { num2++; if (num3 < 25) { num3++; Plugin.Log.LogWarning((object)(string.Format("{0} {1} Kinder in {2} Ladungen ", "[FinalAscent]", list.Count, num4) + $"({num5} + {list.Count - num5}, Luecke {num6}) " + "an '" + PathOf(((Component)val).transform) + "'")); } } } if (num2 == 0) { Plugin.Log.LogInfo((object)(string.Format("{0} Doppelladungs-Probe: {1} bestueckte Spawner, ", "[FinalAscent]", num) + "keiner traegt zwei Ladungen.")); } else { Plugin.Log.LogWarning((object)(string.Format("{0} DOPPELLADUNG: {1} von {2} bestueckten Spawnern ", "[FinalAscent]", num2, num) + "tragen Props aus MEHR ALS EINER Erzeugungsphase. Das ist die Ursache der toedlichen Bruecken - man steht zwischen zwei Ladungen, und jede Planke schlaegt fuer sich zu.")); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Doppelladungs-Probe misslang: " + ex.Message)); } } private static string PathOf(Transform leaf) { if ((Object)(object)leaf == (Object)null) { return "?"; } string text = ((Object)leaf).name; Transform parent = leaf.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } } internal static class FinalAscentExact { private sealed class Listener : IOnEventCallback { public void OnEvent(EventData photonEvent) { try { if (photonEvent.Code == 177) { AnswerWish(photonEvent); } else if (photonEvent.Code == 178) { ReceiveFix(photonEvent); } } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("{0} Exakt-Abgleich wirft: {1}", "[FinalAscent]", arg)); } } } private const string Tag = "[FinalAscent]"; private const string KeySteps = "FAx"; private const byte EventWish = 177; private const byte EventFix = 178; private const int Slice = 60000; private static Listener _listener; private static readonly SortedDictionary _parts = new SortedDictionary(); private static void Listen() { if (_listener == null) { _listener = new Listener(); PhotonNetwork.AddCallbackTarget((object)_listener); } } internal static void PublishSteps() { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_00dd: Expected O, but got Unknown Listen(); if (!FinalAscent.Active || !PhotonNetwork.IsMasterClient || !PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return; } SortedDictionary fingerprints = FinalAscentStepPrint.Fingerprints; if (fingerprints == null || fingerprints.Count == 0) { return; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties != null && ((Dictionary)(object)customProperties).ContainsKey((object)"FAx")) { Plugin.Detail("[FinalAscent] Im Raum steht schon ein Schritt-Massstab - der bleibt."); return; } StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair item in fingerprints) { stringBuilder.Append(item.Key).Append('=').Append(item.Value) .Append('\n'); } byte[] array = Zip(stringBuilder.ToString()); Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"FAx", (object)array); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)(string.Format("{0} Schritt-Massstab im Raum hinterlegt: {1} Schritte, ", "[FinalAscent]", fingerprints.Count) + $"{array.Length} Bytes gepackt.")); } internal static void CompareAndRepairLater() { Listen(); if (FinalAscent.Active && !PhotonNetwork.IsMasterClient && !((Object)(object)Plugin.Instance == (Object)null)) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(CompareRoutine()); } } private static IEnumerator CompareRoutine() { float patience = 300f; float waited = 0f; byte[] packed = null; while (patience > 0f) { if (PhotonNetwork.IsMasterClient) { Plugin.Log.LogInfo((object)"[FinalAscent] Waehrend des Wartens selbst Master geworden - der eigene Berg wird der Massstab."); PublishSteps(); yield break; } if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties != null && ((Dictionary)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"FAx", out object value) && value is byte[] array) { packed = array; break; } patience -= Time.deltaTime; waited += Time.deltaTime; yield return null; } if (packed == null) { Plugin.Log.LogWarning((object)(string.Format("{0} Auch nach {1:F0}s kein Schritt-Massstab im Raum - der ", "[FinalAscent]", waited) + "Exakt-Abgleich entfaellt (Host noch auf einer aelteren Fassung?).")); yield break; } if (waited > 5f) { Plugin.Log.LogInfo((object)(string.Format("{0} Schritt-Massstab nach {1:F0}s Wartezeit eingetroffen ", "[FinalAscent]", waited) + "(der Host hat laenger gebaut) - jetzt wird verglichen.")); } Dictionary dictionary = new Dictionary(); string[] array2 = Unzip(packed).Split('\n'); foreach (string text in array2) { int num = text.IndexOf('='); if (num > 0) { dictionary[text.Substring(0, num)] = text.Substring(num + 1); } } SortedDictionary fingerprints = FinalAscentStepPrint.Fingerprints; List list = new List(); int num2 = 0; foreach (KeyValuePair item in dictionary) { if (!fingerprints.TryGetValue(item.Key, out var value2)) { num2++; } else if (value2 != item.Value) { list.Add(item.Key); } } if (list.Count == 0 && num2 == 0) { Plugin.Log.LogInfo((object)(string.Format("{0} EXAKT: alle {1} Schritte stimmen mit dem Massstab ", "[FinalAscent]", dictionary.Count) + "ueberein - derselbe Berg, bitgenau.")); yield break; } if (list.Count == 0) { Plugin.Log.LogWarning((object)(string.Format("{0} {1} Schritte des Massstabs fehlen hier strukturell - ", "[FinalAscent]", num2) + "das kann kein Versetzen heilen, das ist ein Bau-Unterschied.")); yield break; } Plugin.Log.LogWarning((object)(string.Format("{0} {1} von {2} Schritten weichen vom Massstab ab", "[FinalAscent]", list.Count, dictionary.Count) + ((num2 > 0) ? $" ({num2} fehlen strukturell)" : "") + " - sie werden beim Master im Wortlaut angefordert.")); byte[] array3 = Zip(string.Join("\n", list)); RaiseEventOptions val = new RaiseEventOptions(); val.TargetActors = new int[1] { PhotonNetwork.MasterClient.ActorNumber }; PhotonNetwork.RaiseEvent((byte)177, (object)array3, val, SendOptions.SendReliable); } private static void AnswerWish(EventData e) { //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Expected O, but got Unknown //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) if (!FinalAscent.Active || !PhotonNetwork.IsMasterClient) { return; } string[] array = Unzip((byte[])e.CustomData).Split('\n'); Dictionary dictionary = MapSteps(); StringBuilder stringBuilder = new StringBuilder(); int num = 0; int num2 = 0; string[] array2 = array; foreach (string text in array2) { if (string.IsNullOrEmpty(text)) { continue; } if (!dictionary.TryGetValue(text, out var value)) { stringBuilder.Append('?').Append(text).Append('\n'); num2++; continue; } stringBuilder.Append('@').Append(text).Append('\n'); for (int j = 0; j < value.childCount; j++) { Transform child = value.GetChild(j); if (!((Object)child).name.StartsWith("MushroomZombieSpawner")) { Vector3 localPosition = child.localPosition; Quaternion localRotation = child.localRotation; Vector3 localScale = child.localScale; stringBuilder.Append(((Object)child).name).Append('|').Append(F(localPosition.x)) .Append('|') .Append(F(localPosition.y)) .Append('|') .Append(F(localPosition.z)) .Append('|') .Append(F(localRotation.x)) .Append('|') .Append(F(localRotation.y)) .Append('|') .Append(F(localRotation.z)) .Append('|') .Append(F(localRotation.w)) .Append('|') .Append(F(localScale.x)) .Append('|') .Append(F(localScale.y)) .Append('|') .Append(F(localScale.z)) .Append('\n'); num++; } } } byte[] array3 = Zip(stringBuilder.ToString()); int num3 = (array3.Length + 60000 - 1) / 60000; for (int k = 0; k < num3; k++) { int num4 = Math.Min(60000, array3.Length - k * 60000); byte[] array4 = new byte[num4]; Buffer.BlockCopy(array3, k * 60000, array4, 0, num4); object[] obj = new object[3] { k, num3, array4 }; RaiseEventOptions val = new RaiseEventOptions(); val.TargetActors = new int[1] { e.Sender }; PhotonNetwork.RaiseEvent((byte)178, (object)obj, val, SendOptions.SendReliable); } Plugin.Log.LogInfo((object)(string.Format("{0} Massstab-Antwort an Platz {1}: {2} Schritte ", "[FinalAscent]", e.Sender, array.Length) + $"({num2} unbekannt), {num} Props, {array3.Length} Bytes in {num3} Teil(en).")); } private static void ReceiveFix(EventData e) { object[] array = (object[])e.CustomData; int key = (int)array[0]; int num = (int)array[1]; _parts[key] = (byte[])array[2]; if (_parts.Count < num) { return; } byte[] packed; using (MemoryStream memoryStream = new MemoryStream()) { foreach (KeyValuePair part in _parts) { memoryStream.Write(part.Value, 0, part.Value.Length); } packed = memoryStream.ToArray(); } _parts.Clear(); Apply(Unzip(packed)); } private static void Apply(string text) { Dictionary steps = MapSteps(); List entries = new List(); string current = null; int stepsDone = 0; int moved = 0; int born = 0; int culled = 0; int orphan = 0; string[] array = text.Split('\n'); foreach (string text2 in array) { if (text2.Length != 0) { if (text2[0] == '@') { Flush(); current = text2.Substring(1); } else if (text2[0] == '?') { Plugin.Log.LogWarning((object)("[FinalAscent] Der Master kennt '" + text2.Substring(1) + "' nicht - strukturell verschieden, bleibt wie es ist.")); } else if (current != null) { entries.Add(text2.Split('|')); } } } Flush(); Physics.SyncTransforms(); Plugin.Log.LogInfo((object)(string.Format("{0} EXAKT ANGEGLICHEN: {1} Schritte - {2} Props versetzt, ", "[FinalAscent]", stepsDone, moved) + $"{born} nachgebaut, {culled} entfernt" + ((orphan > 0) ? $", {orphan} ohne Vorlage uebersprungen" : "") + ". Der Berg entspricht jetzt dem Massstab.")); void Flush() { if (current != null) { ApplyStep(steps, current, entries, ref moved, ref born, ref culled, ref orphan); stepsDone++; } entries.Clear(); } } private static void ApplyStep(Dictionary steps, string path, List entries, ref int moved, ref int born, ref int culled, ref int orphan) { //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) if (!steps.TryGetValue(path, out var value)) { Plugin.Log.LogWarning((object)("[FinalAscent] Schritt '" + path + "' hier nicht auffindbar.")); return; } List list = new List(); for (int i = 0; i < value.childCount; i++) { Transform child = value.GetChild(i); if (!((Object)child).name.StartsWith("MushroomZombieSpawner")) { list.Add(child); } } bool[] array = new bool[list.Count]; foreach (string[] entry in entries) { if (entry.Length < 11) { continue; } string text = entry[0]; int num = -1; for (int j = 0; j < list.Count; j++) { if (!array[j] && (Object)(object)list[j] != (Object)null && ((Object)list[j]).name == text) { num = j; break; } } Transform val; if (num >= 0) { array[num] = true; val = list[num]; moved++; } else { Transform val2 = null; for (int k = 0; k < list.Count; k++) { if ((Object)(object)list[k] != (Object)null && ((Object)list[k]).name == text) { val2 = list[k]; break; } } if ((Object)(object)val2 == (Object)null) { orphan++; continue; } GameObject obj = Object.Instantiate(((Component)val2).gameObject, value); ((Object)obj).name = text; val = obj.transform; born++; } val.localPosition = new Vector3(P(entry[1]), P(entry[2]), P(entry[3])); val.localRotation = new Quaternion(P(entry[4]), P(entry[5]), P(entry[6]), P(entry[7])); val.localScale = new Vector3(P(entry[8]), P(entry[9]), P(entry[10])); } for (int l = 0; l < list.Count; l++) { if (!array[l] && (Object)(object)list[l] != (Object)null) { Object.Destroy((Object)(object)((Component)list[l]).gameObject); culled++; } } } private static Dictionary MapSteps() { Dictionary dictionary = new Dictionary(); LevelGenStep[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (LevelGenStep val in array) { if (!((Object)(object)val == (Object)null)) { string key = PathOf(((Component)val).transform); if (!dictionary.ContainsKey(key)) { dictionary[key] = ((Component)val).transform; } } } return dictionary; } private static string PathOf(Transform leaf) { StringBuilder stringBuilder = new StringBuilder(((Object)leaf).name); Transform parent = leaf.parent; while ((Object)(object)parent != (Object)null) { stringBuilder.Insert(0, '/').Insert(0, ((Object)parent).name); parent = parent.parent; } return stringBuilder.ToString(); } private static string F(float value) { return value.ToString("R", CultureInfo.InvariantCulture); } private static float P(string value) { return float.Parse(value, CultureInfo.InvariantCulture); } private static byte[] Zip(string text) { using MemoryStream memoryStream = new MemoryStream(); using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionLevel.Optimal)) { byte[] bytes = Encoding.UTF8.GetBytes(text); gZipStream.Write(bytes, 0, bytes.Length); } return memoryStream.ToArray(); } private static string Unzip(byte[] packed) { using MemoryStream stream = new MemoryStream(packed); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); gZipStream.CopyTo(memoryStream); return Encoding.UTF8.GetString(memoryStream.ToArray()); } } internal static class FinalAscentFakeItems { private const string Tag = "[FinalAscent]"; private static int _set; private static int _missing; private static readonly HashSet Seen = new HashSet(); private static int _twice; internal static void Renumber() { if (!FinalAscent.Active) { return; } try { if ((Object)(object)FakeItemManager.Instance != (Object)null) { FakeItemManager.Instance.RefreshList(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Schaustueck-Liste liess sich nicht fuellen: " + ex.Message)); } List> list = new List>(); FakeItem[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (FakeItem val in array) { if (!((Object)(object)val == (Object)null)) { string key; try { key = FinalAscentDelivery.ScenePathOf(((Component)val).transform); } catch { key = ((Object)val).name; } list.Add(new KeyValuePair(key, val)); } } list.Sort((KeyValuePair a, KeyValuePair b) => string.CompareOrdinal(a.Key, b.Key)); for (int num = 0; num < list.Count; num++) { list[num].Value.index = num; } string text = ((list.Count > 0) ? ("0 = '" + list[0].Key + "'") : "keine"); Plugin.Log.LogInfo((object)(string.Format("{0} Schaustueck-Nummern nach Pfad vergeben: {1} Stueck ", "[FinalAscent]", list.Count) + "(" + text + "). Dieselbe Reihenfolge auf jedem Rechner - sonst zieht ein Griff beim Master das falsche Fach.")); } internal static int Pack(StringBuilder text) { int num = 0; FakeItem[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (FakeItem val in array) { if (!((Object)(object)val == (Object)null)) { string value; try { value = FinalAscentDelivery.ScenePathOf(((Component)val).transform); } catch { continue; } text.Append('$').Append(value).Append('|') .Append(val.index.ToString(CultureInfo.InvariantCulture)) .Append('\n'); num++; } } return num; } internal static void BeginApply() { _set = 0; _missing = 0; _twice = 0; Seen.Clear(); try { if ((Object)(object)FakeItemManager.Instance != (Object)null) { FakeItemManager.Instance.RefreshList(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Schaustueck-Liste liess sich nicht fuellen: " + ex.Message)); } } internal static void ApplyLine(string line) { int num = line.LastIndexOf('|'); if (num <= 0 || !int.TryParse(line.Substring(num + 1), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return; } Transform val = FinalAscentDelivery.FindByPathPublic(line.Substring(0, num)); FakeItem val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if ((Object)(object)val2 == (Object)null) { _missing++; return; } if (!Seen.Add(result)) { _twice++; } val2.index = result; _set++; } internal static void EndApply(int lines) { if (lines != 0) { Plugin.Log.LogInfo((object)(string.Format("{0} Schaustueck-Nummern aus dem Image: {1} von {2} gesetzt, ", "[FinalAscent]", _set, lines) + $"{_missing} nicht gefunden. Ohne sie zieht ein Griff beim Master das " + "falsche Fach - man bekaeme einen fremden Gegenstand, und das eigene Stueck bliebe haengen.")); if (_twice > 0) { Plugin.Log.LogWarning((object)(string.Format("{0} {1} Nummern doppelt vergeben - dann zeigen zwei ", "[FinalAscent]", _twice) + "Schaustuecke auf dasselbe Fach. Das darf nicht vorkommen.")); } } } } internal static class FinalAscentFireReport { private const string Tag = "[FinalAscent]"; internal static void Report() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 //IL_007a: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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) Campfire[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); if (array.Length == 0) { Plugin.Log.LogInfo((object)"[FinalAscent] Keine Lagerfeuer in der Szene."); return; } List list = new List(); int num = 0; int num2 = 0; Campfire[] array2 = array; foreach (Campfire val in array2) { if (!((Object)(object)val == (Object)null)) { bool activeInHierarchy = ((Component)val).gameObject.activeInHierarchy; if (activeInHierarchy) { num++; } if ((int)val.state == 1) { num2++; } Biome componentInParent = ((Component)val).GetComponentInParent(true); Vector3 position = ((Component)val).transform.position; list.Add($"{((Object)val).name} bei ({position.x:F0} / {position.y:F0} / {position.z:F0}): " + string.Format("{0}, {1}, ", activeInHierarchy ? "da" : "NICHT DA", val.state) + "Biom " + (((Object)(object)componentInParent != (Object)null) ? ((object)Unsafe.As(ref componentInParent.biomeType)/*cast due to .constrained prefix*/).ToString() : "keins") + ", unter '" + Parent(((Component)val).transform) + "'"); } } list.Sort(StringComparer.Ordinal); Plugin.Log.LogInfo((object)(string.Format("{0} Lagerfeuer: {1} insgesamt, {2} in der Welt, ", "[FinalAscent]", array.Length, num) + $"{num2} brennen.")); foreach (string item in list) { Plugin.Log.LogInfo((object)("[FinalAscent] " + item)); } } private static string Parent(Transform of) { Transform parent = of.parent; while ((Object)(object)parent != (Object)null) { if (!((Component)parent).gameObject.activeSelf) { return ((Object)parent).name + " (DIESER ist aus)"; } parent = parent.parent; } if (!((Object)(object)of.parent != (Object)null)) { return "(nichts)"; } return ((Object)of.parent).name; } } internal sealed class FinalAscentFlashlight : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const Key Switch = (Key)20; private const float Again = 3f; private float _repeat; private const float Share = 0.7f; private const float Fallback = 90f; internal static float Duration; private static readonly Dictionary Others = new Dictionary(); private static FinalAscentFlashlight _instance; private GameObject _hud; private TextMeshProUGUI _prompt; private Image _gauge; private RectTransform _fill; private float _wide; private const float ClickVolume = 0.35f; private AudioSource _clack; private static readonly Color Green = new Color(0.36f, 0.82f, 0.32f, 1f); private static readonly Color Yellow = new Color(0.95f, 0.79f, 0.22f, 1f); private static readonly Color Red = new Color(0.87f, 0.22f, 0.18f, 1f); private const float BarWide = 360f; private const float BarHigh = 12f; private const float BarUp = 26f; private const float PromptUp = 54f; private static float Life { get { if (!(Duration > 0f)) { return 90f; } return Duration * 0.7f; } } internal static float Charge { get; private set; } internal static bool Lit { get; private set; } internal static bool Burning(Character who) { if ((Object)(object)who == (Object)null || who.refs == null || (Object)(object)who.refs.view == (Object)null) { return false; } if (who.refs.view.IsMine) { return Lit; } bool value; return Others.TryGetValue(who.refs.view.ViewID, out value) && value; } internal static void Hear(int viewId, bool on) { Others[viewId] = on; } 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_Flashlight"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } if (!on) { Lit = false; Others.Clear(); if ((Object)(object)_instance != (Object)null) { _instance.Hide(); } } else { Charge = 1f; Lit = false; Others.Clear(); Plugin.Log.LogInfo((object)("[FinalAscent] Finsternis: Taschenlampen ausgeteilt - Batterie fuer " + $"{Life:0.#}s, alle aus.")); } } private void Update() { if (!FinalAscentDarkSky.Full) { if (Lit) { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null) { Flip(localCharacter, on: false); } } Hide(); return; } float lift = FinalAscentDarkSky.Lift; Character localCharacter2 = Character.localCharacter; if ((Object)(object)localCharacter2 == (Object)null) { return; } if (Keyboard.current != null && ((ButtonControl)Keyboard.current[(Key)20]).wasPressedThisFrame && (Charge > 0f || Lit)) { Flip(localCharacter2, !Lit); } if (Lit) { Charge -= Time.deltaTime / Life; if (Charge <= 0f) { Charge = 0f; Flip(localCharacter2, on: false); Plugin.Log.LogInfo((object)"[FinalAscent] Finsternis: Batterie leer."); } else { _repeat -= Time.deltaTime; if (_repeat <= 0f) { Tell(localCharacter2, on: true); } } } Show(lift); } private static void Flip(Character me, bool on) { Lit = on; if ((Object)(object)_instance != (Object)null) { _instance.Click(on); } Tell(me, on); } private static void Tell(Character me, bool on) { if ((Object)(object)_instance != (Object)null) { _instance._repeat = 3f; } if ((Object)(object)me != (Object)null && me.refs != null && (Object)(object)me.refs.view != (Object)null && me.refs.view.IsMine) { me.refs.view.RPC("RPC_FinalAscentTorch", (RpcTarget)1, new object[1] { on }); } } private void Click(bool on) { if ((Object)(object)_clack == (Object)null) { AudioClip val = FinalAscentLarder.Sound("Au_UI_Click2"); if ((Object)(object)val == (Object)null) { return; } _clack = ((Component)this).gameObject.AddComponent(); _clack.clip = val; _clack.playOnAwake = false; _clack.spatialBlend = 0f; _clack.volume = 0.35f; _clack.outputAudioMixerGroup = FinalAscentLarder.Bus(); } _clack.pitch = (on ? 1.15f : 0.9f); _clack.Play(); } private void Show(float lift) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_hud == (Object)null) || Build()) { _hud.SetActive(true); ((Graphic)_prompt).color = (Color)(Lit ? FinalAscentUiKit.Chalk : new Color(FinalAscentUiKit.ChalkDim.r, FinalAscentUiKit.ChalkDim.g, FinalAscentUiKit.ChalkDim.b, 0.75f)); _fill.sizeDelta = new Vector2(_wide * Mathf.Clamp01(Charge), 12f); ((Graphic)_gauge).color = ((Charge > 0.5f) ? Green : ((Charge > 0.2f) ? Yellow : Red)); CanvasGroup component = _hud.GetComponent(); if ((Object)(object)component != (Object)null) { component.alpha = Mathf.Clamp01(lift * 2f); } } } private void Hide() { if ((Object)(object)_hud != (Object)null) { _hud.SetActive(false); } } private bool Build() { //IL_0046: 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_005c: 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_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) GUIManager instance = GUIManager.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.hudCanvas == (Object)null) { return false; } _hud = FinalAscentUiKit.Node("FA_Flashlight", ((Component)instance.hudCanvas).transform); RectTransform obj = FinalAscentUiKit.Rect(_hud); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; _hud.AddComponent().blocksRaycasts = false; GameObject val = FinalAscentUiKit.Node("Prompt", _hud.transform); TextMeshProUGUI val2 = val.AddComponent(); TextMeshProUGUI interactPromptText = instance.interactPromptText; if ((Object)(object)interactPromptText != (Object)null) { ((TMP_Text)val2).font = ((TMP_Text)interactPromptText).font; ((TMP_Text)val2).fontSharedMaterial = ((TMP_Text)interactPromptText).fontSharedMaterial; } try { InputSpriteData instance2 = SingletonAsset.Instance; if ((Object)(object)instance2 != (Object)null && (Object)(object)instance2.keyboardSprites != (Object)null) { ((TMP_Text)val2).spriteAsset = instance2.keyboardSprites; } } catch (Exception) { } if ((Object)(object)((TMP_Text)val2).spriteAsset == (Object)null && (Object)(object)interactPromptText != (Object)null) { ((TMP_Text)val2).spriteAsset = ((TMP_Text)interactPromptText).spriteAsset; } else if ((Object)(object)FinalAscentUiKit.Font != (Object)null) { ((TMP_Text)val2).font = FinalAscentUiKit.Font; ((TMP_Text)val2).fontSharedMaterial = FinalAscentUiKit.FontMaterial; } ((TMP_Text)val2).fontSize = 26f; ((TMP_Text)val2).alignment = (TextAlignmentOptions)514; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).text = Icon() + " " + FinalAscentText.Get("dark.torch"); _prompt = val2; RectTransform obj2 = FinalAscentUiKit.Rect(val); obj2.anchorMin = new Vector2(0.5f, 0f); obj2.anchorMax = new Vector2(0.5f, 0f); obj2.pivot = new Vector2(0.5f, 0f); obj2.sizeDelta = new Vector2(520f, 34f); obj2.anchoredPosition = new Vector2(0f, 54f); GameObject val3 = FinalAscentUiKit.Node("Battery", _hud.transform); Image obj3 = val3.AddComponent(); ((Graphic)obj3).color = new Color(0f, 0f, 0f, 0.55f); ((Graphic)obj3).raycastTarget = false; RectTransform obj4 = FinalAscentUiKit.Rect(val3); obj4.anchorMin = new Vector2(0.5f, 0f); obj4.anchorMax = new Vector2(0.5f, 0f); obj4.pivot = new Vector2(0.5f, 0f); obj4.sizeDelta = new Vector2(364f, 16f); obj4.anchoredPosition = new Vector2(0f, 26f); GameObject val4 = FinalAscentUiKit.Node("Fill", val3.transform); _gauge = val4.AddComponent(); ((Graphic)_gauge).raycastTarget = false; _fill = FinalAscentUiKit.Rect(val4); _fill.anchorMin = new Vector2(0f, 0.5f); _fill.anchorMax = new Vector2(0f, 0.5f); _fill.pivot = new Vector2(0f, 0.5f); _fill.anchoredPosition = new Vector2(2f, 0f); _wide = 360f; _fill.sizeDelta = new Vector2(_wide, 12f); Plugin.Log.LogInfo((object)"[FinalAscent] Finsternis: Anzeige an PEAKs HUD gehaengt."); return true; } private static string Icon() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) try { InputSpriteData instance = SingletonAsset.Instance; if ((Object)(object)instance != (Object)null) { string spriteTagFromInputPathKeyboard = instance.GetSpriteTagFromInputPathKeyboard("/" + ((object)(Key)20/*cast due to .constrained prefix*/).ToString().ToLowerInvariant()); if (!string.IsNullOrEmpty(spriteTagFromInputPathKeyboard)) { return spriteTagFromInputPathKeyboard; } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Finsternis: Tastenbild nicht zu holen (" + ex.Message + ").")); } return $"[{(object)(Key)20}]"; } } public class FinalAscentTorchSync : MonoBehaviour { [PunRPC] public void RPC_FinalAscentTorch(bool on) { PhotonView component = ((Component)this).GetComponent(); if ((Object)(object)component != (Object)null) { FinalAscentFlashlight.Hear(component.ViewID, on); } } [PunRPC] public void RPC_FinalAscentScoutOff(int chasedViewId) { Character chased = null; PhotonView val = PhotonView.Find(chasedViewId); if ((Object)(object)val != (Object)null) { chased = ((Component)val).GetComponent(); } FinalAscentScoutHunt.Retreat(chased); } } [HarmonyPatch(typeof(Character), "Awake")] internal static class FinalAscentTorchAttach { private static void Postfix(Character __instance) { PhotonView componentInParent = ((Component)__instance).GetComponentInParent(); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)((Component)componentInParent).GetComponent() != (Object)null)) { ((Component)componentInParent).gameObject.AddComponent(); componentInParent.RefreshRpcMonoBehaviourCache(); } } } [HarmonyPatch(typeof(ForceFogShaderHeight), "Update")] internal static class FinalAscentFogHeightPatch { private const string Tag = "[FinalAscent]"; private static int _frame = -1; private static readonly Dictionary Chosen = new Dictionary(); private static bool Prefix(ForceFogShaderHeight __instance) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected I4, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!FinalAscent.Active) { return true; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { return true; } if (_frame != Time.frameCount) { _frame = Time.frameCount; Choose(localCharacter.Center.y); } int key = (int)__instance.fogType; if (Chosen.TryGetValue(key, out var value)) { return (Object)(object)value == (Object)(object)__instance; } return false; } private static void Choose(float playerHeight) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected I4, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) Chosen.Clear(); Dictionary dictionary = new Dictionary(); ForceFogShaderHeight[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (ForceFogShaderHeight val in array) { if (!((Object)(object)val == (Object)null)) { int key = (int)val.fogType; float num = Mathf.Abs(((Component)val).transform.position.y - playerHeight); if (!dictionary.TryGetValue(key, out var value) || num < value) { dictionary[key] = num; Chosen[key] = val; } } } } } [HarmonyPatch(typeof(OrbFogHandler), "WaitForFogCatchUp")] internal static class FinalAscentFogRescue { private const string Tag = "[FinalAscent]"; private const float PatienceSeconds = 15f; private static void Prefix() { if (FinalAscent.Active && !((Object)(object)Plugin.Instance == (Object)null)) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(Watch()); } } private static IEnumerator Watch() { OrbFogHandler fog = Singleton.Instance; if ((Object)(object)fog == (Object)null) { yield break; } float since = Time.realtimeSinceStartup; float started = fog.currentSize; float lastReport = 0f; while ((Object)(object)fog != (Object)null && fog.isMoving && !fog.hasArrived && fog.currentSize > 30f) { float num = Time.realtimeSinceStartup - since; if (num - lastReport >= 3f) { lastReport = num; Plugin.Log.LogInfo((object)(string.Format("{0} Nebel zieht seit {1:F0}s zu: Groesse {2:F0} ", "[FinalAscent]", num, fog.currentSize) + $"(Start {started:F0}, Ziel 30).")); } if (num >= 15f) { Plugin.Log.LogWarning((object)(string.Format("{0} Der Nebel zieht seit {1:F0}s zu und ist bei ", "[FinalAscent]", num) + $"{fog.currentSize:F0} statt 30 - der Segmentwechsel haengt daran. " + "Er wird jetzt durchgelassen, sonst geht es nie weiter.")); fog.isMoving = false; yield break; } yield return null; } Plugin.Log.LogInfo((object)(string.Format("{0} Nebel zugezogen nach {1:F1}s ", "[FinalAscent]", Time.realtimeSinceStartup - since) + $"(von {started:F0} auf {(((Object)(object)fog != (Object)null) ? fog.currentSize : 0f):F0}).")); } } internal sealed class FinalAscentFogVoices : MonoBehaviour { private sealed class Voice { internal VoiceObscuranceFilter Works; internal AudioSource Source; internal bool WasEnabled; internal float WasBlend; internal bool WasLow; internal bool WasHigh; internal bool WasReverb; internal float WasCutoff; internal AudioReverbPreset WasPreset; internal bool Bent; } private const string Tag = "[FinalAscent]"; private const float Close = 5f; private const float Muffle = 3200f; private const float Thin = 180f; private readonly Dictionary _known = new Dictionary(); private static FinalAscentFogVoices _instance; private bool _told; internal static void Install() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("FA_FogVoices"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } } private void LateUpdate() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) bool num = FinalAscentSleepFogSky.Lift > 0f; Character localCharacter = Character.localCharacter; if (!num || (Object)(object)localCharacter == (Object)null) { Straighten(); return; } List allPlayerCharacters = PlayerHandler.GetAllPlayerCharacters(); for (int i = 0; i < allPlayerCharacters.Count; i++) { Character val = allPlayerCharacters[i]; if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)localCharacter) { continue; } VoiceObscuranceFilter componentInChildren = ((Component)val).GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { continue; } Voice voice = Remember(componentInChildren); if (voice != null) { if (Vector3.Distance(val.Center, localCharacter.Center) > 5f) { Bend(voice); } else { Straighten(voice); } } } } private Voice Remember(VoiceObscuranceFilter works) { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if (_known.TryGetValue(works, out var value)) { return value; } value = new Voice { Works = works, Source = ((Component)works).GetComponent(), WasEnabled = ((Behaviour)works).enabled }; if ((Object)(object)value.Source != (Object)null) { value.WasBlend = value.Source.spatialBlend; } if ((Object)(object)works.lowPass != (Object)null) { value.WasLow = ((Behaviour)works.lowPass).enabled; value.WasCutoff = works.lowPass.cutoffFrequency; } if ((Object)(object)works.highPass != (Object)null) { value.WasHigh = ((Behaviour)works.highPass).enabled; } if ((Object)(object)works.reverb != (Object)null) { value.WasReverb = ((Behaviour)works.reverb).enabled; value.WasPreset = works.reverb.reverbPreset; } _known[works] = value; return value; } private void Bend(Voice voice) { if (!voice.Bent) { voice.Bent = true; ((Behaviour)voice.Works).enabled = false; if ((Object)(object)voice.Source != (Object)null) { voice.Source.spatialBlend = 0f; } if ((Object)(object)voice.Works.lowPass != (Object)null) { ((Behaviour)voice.Works.lowPass).enabled = true; voice.Works.lowPass.cutoffFrequency = 3200f; } if ((Object)(object)voice.Works.highPass != (Object)null) { ((Behaviour)voice.Works.highPass).enabled = true; voice.Works.highPass.cutoffFrequency = 180f; } if ((Object)(object)voice.Works.reverb != (Object)null) { ((Behaviour)voice.Works.reverb).enabled = true; voice.Works.reverb.reverbPreset = (AudioReverbPreset)9; } if (!_told) { _told = true; Plugin.Log.LogInfo((object)(string.Format("{0} Schlafnebel: Stimmen jenseits von {1:0}m werden ", "[FinalAscent]", 5f) + "richtungslos, hallig und flach.")); } } } private void Straighten(Voice voice) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) if (voice.Bent) { voice.Bent = false; if ((Object)(object)voice.Source != (Object)null) { voice.Source.spatialBlend = voice.WasBlend; } if ((Object)(object)voice.Works.lowPass != (Object)null) { ((Behaviour)voice.Works.lowPass).enabled = voice.WasLow; voice.Works.lowPass.cutoffFrequency = voice.WasCutoff; } if ((Object)(object)voice.Works.highPass != (Object)null) { ((Behaviour)voice.Works.highPass).enabled = voice.WasHigh; } if ((Object)(object)voice.Works.reverb != (Object)null) { ((Behaviour)voice.Works.reverb).enabled = voice.WasReverb; voice.Works.reverb.reverbPreset = voice.WasPreset; } ((Behaviour)voice.Works).enabled = voice.WasEnabled; } } private void Straighten() { if (_known.Count == 0) { return; } foreach (Voice value in _known.Values) { if ((Object)(object)value.Works != (Object)null) { Straighten(value); } } _known.Clear(); _told = false; } } internal static class FinalAscentWallProbe { internal static void Dump(string when, Vector3 near) { //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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_013b: Unknown result type (might be due to invalid IL or missing references) int num = 0; Collider[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (Collider val in array) { if ((Object)(object)val == (Object)null || !val.enabled || val.isTrigger) { continue; } string text = ((Object)val).name + "/" + (((Object)(object)((Component)val).transform.parent != (Object)null) ? ((Object)((Component)val).transform.parent).name : "-"); if (text.IndexOf("fog", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("wall", StringComparison.OrdinalIgnoreCase) >= 0) { Bounds bounds = val.bounds; float num2 = Vector3.Distance(((Bounds)(ref bounds)).center, near); if (!(num2 > 400f) && num < 12) { num++; ManualLogSource log = Plugin.Log; string[] obj = new string[8] { "[FinalAscent] Wand ", when, ": '", ((Object)val).name, "' unter '", ((Object)(object)((Component)val).transform.parent != (Object)null) ? ((Object)((Component)val).transform.parent).name : "-", "' ", null }; bounds = val.bounds; obj[7] = $"bei {FinalAscentBuilder.Fmt(((Bounds)(ref bounds)).center)}, {num2:F0} entfernt."; log.LogInfo((object)string.Concat(obj)); } } } if (num == 0) { Plugin.Log.LogInfo((object)("[FinalAscent] Wand " + when + ": keine feste Nebelwand in Reichweite.")); } } } public class FinalAscentFogWatchdog : MonoBehaviour { private const float ClosedSizeThreshold = 60f; private const float MaxSecondsClosed = 25f; private float _closedSince = -1f; private void Update() { if (!FinalAscent.Active) { _closedSince = -1f; return; } FinalAscentBuilder.HeightFog.Tick(); OrbFogHandler instance = Singleton.Instance; if (!((Object)(object)instance == (Object)null)) { if (instance.currentSize > 60f) { _closedSince = -1f; } else if (_closedSince < 0f) { _closedSince = Time.time; } else if (!(Time.time - _closedSince < 25f)) { _closedSince = -1f; ForceReveal(instance); } } } private static void ForceReveal(OrbFogHandler fog) { Plugin.Log.LogWarning((object)($"[FinalAscent] Nebel haengt seit {25f:F0}s geschlossen " + $"(currentSize={fog.currentSize:F1}, isMoving={fog.isMoving}, hasArrived={fog.hasArrived}) " + "- wird zwangsweise geoeffnet.")); object? obj = AccessTools.Field(typeof(OrbFogHandler), "sphere")?.GetValue(fog); FogSphere val = (FogSphere)((obj is FogSphere) ? obj : null); if (val != null) { val.REVEAL_AMOUNT = 1f; val.ENABLE = 0f; } fog.currentSize = 800f; fog.hasArrived = true; fog.isMoving = false; } } [HarmonyPatch(typeof(MapHandler), "GoToSegment")] internal static class FinalAscentGoToSegmentPatch { internal static float TransitionStart = -1f; private unsafe static void Prefix(Segment s) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected I4, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected I4, but got Unknown //IL_003d: 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_0045: Expected I4, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected I4, but got Unknown //IL_004b: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Invalid comparison between Unknown and I4 //IL_0072: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (FinalAscent.Active) { TransitionStart = Time.realtimeSinceStartup; Plugin.Log.LogInfo((object)$"[FinalAscent] GoToSegment({s}) angefordert."); FinalAscentSegments.HandOverSegmentParent(s - 1); FinalAscentRoom.PublishStage(s * 16); FinalAscentSegments.WallsOnSegmentLeave(s - 1); FinalAscentSegments.WallsOnSegmentEnter((int)s); FinalAscentBiomes.LeaveSegment(s); FinalAscentAmbience.OnSegmentEntered(s); BiomeType key = (((int)s == 2) ? ((BiomeType)2) : ((s - 3 > 1) ? ((BiomeType)1) : ((BiomeType)3))); FinalAscentBuilder.HeightFog.SetLift(FinalAscentBuilder.Offsets.TryGetValue(key, out var value) ? value.y : 0f, ((object)(*(Segment*)(&s))/*cast due to .constrained prefix*/).ToString()); } } } [HarmonyPatch(typeof(OrbFogHandler), "WaitForFogCatchUp")] internal static class FinalAscentFogCatchUpTimingPatch { private static void Prefix() { LogElapsed("Nebel beginnt zuzuziehen"); } internal static void LogElapsed(string what) { if (FinalAscent.Active && !(FinalAscentGoToSegmentPatch.TransitionStart < 0f)) { float num = Time.realtimeSinceStartup - FinalAscentGoToSegmentPatch.TransitionStart; Plugin.Log.LogInfo((object)$"[FinalAscent] +{num:F1}s: {what}"); } } } [HarmonyPatch(typeof(OrbFogHandler), "WaitForReveal")] internal static class FinalAscentFogRevealTimingPatch { private static void Prefix() { FinalAscentFogCatchUpTimingPatch.LogElapsed("Reveal beginnt"); } } [HarmonyPatch(typeof(OrbFogHandler), "InitNewSphere")] internal static class FinalAscentFogThresholdPatch { private const float ShareAlong = 0.18f; private const float ShareUp = 0.18f; private static void Postfix(OrbFogHandler __instance, FogSphereOrigin newOrigin) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) if (!FinalAscent.Active || (Object)(object)Character.localCharacter == (Object)null || (Object)(object)newOrigin == (Object)null || newOrigin.moveOnHeight > 9000f) { return; } float num = float.MaxValue; float num2 = float.MaxValue; foreach (Character allCharacter in Character.AllCharacters) { if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.data.dead) { num = Mathf.Min(num, allCharacter.Center.y); num2 = Mathf.Min(num2, allCharacter.Center.z); } } if (num != float.MaxValue) { Vector3 position = ((Component)newOrigin).transform.position; float currentStartHeight = __instance.currentStartHeight; float currentStartForward = __instance.currentStartForward; __instance.currentStartHeight = num + 0.18f * (position.y - num); __instance.currentStartHeight = Mathf.Max(__instance.currentStartHeight, num); __instance.currentStartForward = num2 + 0.18f * (position.z - num2); Plugin.Log.LogInfo((object)("[FinalAscent] Nebelschwelle '" + ((Object)newOrigin).name + "' auf die laufende Etappe " + $"gesetzt: y={currentStartHeight:F0} z={currentStartForward:F0} -> y={__instance.currentStartHeight:F0} " + $"z={__instance.currentStartForward:F0} (Gruppe bei y={num:F0} z={num2:F0}, " + $"Ziel z={position.z:F0}, {0.18f:P0} der Etappe).")); } } } [HarmonyPatch(typeof(OrbFogHandler), "SetFogOrigin")] internal static class FinalAscentFogOriginPatch { private static void Postfix(OrbFogHandler __instance, int id) { //IL_0061: 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_007b: 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_0119: Unknown result type (might be due to invalid IL or missing references) if (!FinalAscent.Active) { return; } FogSphereOrigin[] array = AccessTools.Field(typeof(OrbFogHandler), "origins")?.GetValue(__instance) as FogSphereOrigin[]; string arg = "(ausser Reichweite)"; if (array != null && id >= 0 && id < array.Length && (Object)(object)array[id] != (Object)null) { Vector3 position = ((Component)array[id]).transform.position; float num = (((Object)(object)Character.localCharacter != (Object)null) ? Vector3.Distance(position, Character.localCharacter.Center) : (-1f)); if (num > 0f && num > array[id].size) { float num2 = FinalAscentSegments.RadiusForStage(num); Plugin.Log.LogInfo((object)($"[FinalAscent] Nebelkugel zu klein ({array[id].size:F0}) fuer {num:F0} " + $"Einheiten Abstand - auf {num2:F0} vergroessert.")); array[id].size = num2; __instance.currentSize = num2; } arg = "'" + ((Object)array[id]).name + "' " + FinalAscentBuilder.Fmt(position) + ", " + $"Abstand zum Spieler {num:F0}, Radius {array[id].size:F0}"; } Plugin.Log.LogInfo((object)$"[FinalAscent] Nebelursprung {id}: {arg}"); } } [HarmonyPatch(typeof(OrbFogHandler), "StartMovingRPC")] internal static class FinalAscentFogTriggerLog { private static void Prefix(OrbFogHandler __instance) { //IL_0054: 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) if (!FinalAscent.Active) { return; } float currentWaitTime = __instance.currentWaitTime; float maxWaitTime = __instance.maxWaitTime; float num = float.MaxValue; float num2 = float.MaxValue; foreach (Character allCharacter in Character.AllCharacters) { if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.data.dead) { num = Mathf.Min(num, allCharacter.Center.y); num2 = Mathf.Min(num2, allCharacter.Center.z); } } bool flag = num >= __instance.currentStartHeight && num2 >= __instance.currentStartForward; Plugin.Log.LogInfo((object)("[FinalAscent] Nebel laeuft los: " + (flag ? "die Gruppe ist ueber der Schwelle" : "die UHR ist abgelaufen") + $". Gewartet {currentWaitTime:F0}s von {maxWaitTime:F0}s erlaubt; " + $"Schwelle y={__instance.currentStartHeight:F0} z={__instance.currentStartForward:F0}, " + $"hinterster Spieler y={num:F0} z={num2:F0}.")); } } [HarmonyPatch(typeof(OrbFogHandler), "StartMovingRPC")] internal static class FinalAscentFogRisesPatch { private static void Postfix(OrbFogHandler __instance) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (FinalAscent.Active) { Vector3 val = Vector3.zero; object? obj = AccessTools.Field(typeof(OrbFogHandler), "sphere")?.GetValue(__instance); FogSphere val2 = (FogSphere)((obj is FogSphere) ? obj : null); if (val2 != null) { val = val2.fogPoint; } float num = (((Object)(object)Character.localCharacter != (Object)null) ? Vector3.Distance(val, Character.localCharacter.Center) : (-1f)); Plugin.Log.LogInfo((object)("[FinalAscent] Nebel steigt: Mittelpunkt " + FinalAscentBuilder.Fmt(val) + ", " + $"Radius {__instance.currentSize:F0}, Abstand zum Spieler {num:F0}, " + $"Aufstiegsschwelle y={__instance.currentStartHeight:F0} z={__instance.currentStartForward:F0}")); } } } [HarmonyPatch(typeof(MountainProgressHandler), "SetSegmentComplete")] internal static class FinalAscentSegmentTitlePatch { private static void Prefix(MountainProgressHandler __instance, ref int segment) { if (FinalAscent.Active && __instance.progressPoints != null) { string text; switch (segment) { default: return; case 1: text = "TROPICS"; break; case 2: text = "ALPINE"; break; case 3: text = "CALDERA"; break; case 4: text = "THE KILN"; break; } int num = FinalAscentProgress.IndexOfTitle(__instance, text); if (num >= 0 && num != segment) { Plugin.Log.LogInfo((object)$"[FinalAscent] Biom-Titel fuer Segment {segment}: Index {segment} -> {num} ('{text}')."); segment = num; } } } } internal sealed class FinalAscentFogWorms : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const float Every = 40f; private const float Nearest = 6f; private const float Furthest = 12f; private const int Tries = 8; private float _clock; private readonly List _laid = new List(); private static FinalAscentFogWorms _instance; private static Item _worm; private static bool _searched; 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_FogWorms"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } if (!((Object)(object)_instance == (Object)null)) { if (on) { _instance._clock = 0f; } else { _instance.Collect(); } } } private void Update() { if (!FinalAscentSleepFogSky.Wanted) { _clock = 0f; } else if (PhotonNetwork.IsMasterClient) { _clock += Time.deltaTime; if (!(_clock < 40f)) { _clock -= 40f; Lay(); } } } private void Lay() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) Item val = Worm(); if ((Object)(object)val == (Object)null) { return; } List allPlayerCharacters = PlayerHandler.GetAllPlayerCharacters(); int num = 0; int num2 = 0; for (int i = 0; i < allPlayerCharacters.Count; i++) { Character val2 = allPlayerCharacters[i]; if ((Object)(object)val2 == (Object)null || (Object)(object)val2.data == (Object)null || val2.data.dead || val2.data.fullyPassedOut) { continue; } if (!FinalAscentSpot.OnGround(val2.Center, 6f, 12f, 8, out var where)) { num2++; continue; } GameObject val3 = PhotonNetwork.InstantiateItemRoom(((Object)((Component)val).gameObject).name, where, Quaternion.Euler(0f, Random.value * 360f, 0f)); if ((Object)(object)val3 == (Object)null) { num2++; continue; } PhotonView componentInChildren = val3.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { _laid.Add(componentInChildren.ViewID); } num++; } Plugin.Log.LogInfo((object)(string.Format("{0} Schlafnebel treibt aus: {1} Wuermer gelegt", "[FinalAscent]", num) + ((num2 > 0) ? $", {num2} fanden keinen Boden" : "") + " - " + $"{_laid.Count} liegen insgesamt.")); } private void Collect() { if (!PhotonNetwork.IsMasterClient) { _laid.Clear(); return; } int num = 0; int num2 = 0; foreach (int item in _laid) { PhotonView val = PhotonView.Find(item); if ((Object)(object)val == (Object)null) { num2++; continue; } PhotonNetwork.Destroy(((Component)val).gameObject); num++; } if (_laid.Count > 0) { Plugin.Log.LogInfo((object)(string.Format("{0} Schlafnebel zieht ab - {1} Wuermer gelegt: ", "[FinalAscent]", _laid.Count) + $"{num} eingesammelt, {num2} waren schon fort.")); } _laid.Clear(); } private static Item Worm() { if ((Object)(object)_worm != (Object)null || _searched) { return _worm; } _searched = true; try { ItemDatabase instance = SingletonAsset.Instance; if ((Object)(object)instance != (Object)null && instance.itemLookup != null) { foreach (KeyValuePair item in instance.itemLookup) { if (!((Object)(object)item.Value == (Object)null) && (Object)(object)((Component)item.Value).GetComponentInChildren(true) != (Object)null) { _worm = item.Value; Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel: Wurmvorlage '" + ((Object)((Component)_worm).gameObject).name + "' am Bauteil gefunden.")); return _worm; } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Schlafnebel: das Gegenstandsbuch war nicht zu lesen (" + ex.Message + ") - es bleibt beim Namen.")); } Item val = default(Item); if (ItemDatabase.TryGetItem("EarlyWorm", ref val) && (Object)(object)val != (Object)null) { _worm = val; Plugin.Log.LogInfo((object)"[FinalAscent] Schlafnebel: Wurmvorlage ueber den Namen gefunden."); return _worm; } Plugin.Log.LogWarning((object)"[FinalAscent] Schlafnebel: kein Frueher Wurm im Gegenstandsbuch - der Nebel treibt nichts aus."); return null; } } internal static class FinalAscentFrames { private const float BudgetSeconds = 1f / 15f; private const int PiecesPerFrame = 32; private static float _last; private static int _pieces; private static State _ours; private static State _theirs; private static bool _split; internal static bool Due => _pieces >= 32; internal static float SinceFrame => Time.realtimeSinceStartup - _last; internal static void Piece() { _pieces++; } internal static void Mark() { _last = Time.realtimeSinceStartup; _pieces = 0; } internal static void Hold() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) _ours = Random.state; if (_split) { Random.state = _theirs; } } internal static void Resume() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) _theirs = Random.state; _split = true; Random.state = _ours; } internal static void Split() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) _split = false; _ours = Random.state; _theirs = Random.state; } internal static IEnumerable Through(IEnumerator inner) { if (inner != null) { while (inner.MoveNext()) { yield return inner.Current; } } } } internal static class FinalAscentGeneration { private readonly struct Deferred { internal LevelGenStep Source { get; } internal IDeferredStep Step { get; } internal Deferred(LevelGenStep source, IDeferredStep step) { Source = source; Step = step; } } private sealed class Counter { internal int Value; } private const string Tag = "[FinalAscent]"; private static readonly HashSet _executed = new HashSet(); private static readonly HashSet _hiddenCleared = new HashSet(); private static readonly Dictionary _props = new Dictionary(); private static readonly Dictionary _sums = new Dictionary(); private static readonly Dictionary _seats = new Dictionary(); private static readonly Dictionary _shown = new Dictionary(); private static readonly Dictionary _solid = new Dictionary(); private static double _clearSeconds; private static string _lastBiome; private static readonly BiomeType[] ClimbOrder; private static string FingerprintPath => FinalAscentStore.Note("TrueFinalAscent.Abdruck.txt"); internal static bool WasCleared(LevelGenStep step) { if (!_executed.Contains(step)) { return _hiddenCleared.Contains(step); } return true; } internal static IEnumerator Run(PropGrouper grouper) { FinalAscentGenProfiler.Begin(); _executed.Clear(); _hiddenCleared.Clear(); FinalAscentRayBatch.Reset(); FinalAscentLoadProbe.Begin(); FinalAscentStepPrint.Begin(SettingsKey()); _clearSeconds = 0.0; bool autoSync = Physics.autoSyncTransforms; Physics.autoSyncTransforms = false; Physics.SyncTransforms(); Plugin.Log.LogInfo((object)("[FinalAscent] Automatischer Physik-Abgleich war " + (autoSync ? "AN" : "aus") + " - waehrend der Generierung aus, jeder Spawner entscheidet selbst.")); Stopwatch total = Stopwatch.StartNew(); Stopwatch phase = Stopwatch.StartNew(); long memoryBefore = Profiler.GetTotalAllocatedMemoryLong(); ClearEverythingFirst(grouper); List source = (from step in ((Component)grouper).GetComponentsInChildren() where (Object)(object)step != (Object)null select step).ToList(); List list = source.Where((LevelGenStep step) => TimingRank(step) == 0).ToList(); List late = source.Where((LevelGenStep step) => TimingRank(step) != 0).ToList(); Plugin.Log.LogInfo((object)(string.Format("{0} Schritte einsammeln: {1:F1}s ", "[FinalAscent]", phase.Elapsed.TotalSeconds) + $"({list.Count} frueh, {late.Count} spaet).")); List deferred = new List(); CountBiomes(list, late); phase.Restart(); foreach (object item in FinalAscentFrames.Through(RunSteps(list, deferred))) { yield return item; } Plugin.Log.LogInfo((object)string.Format("{0} Fruehe Schritte: {1:F1}s.", "[FinalAscent]", phase.Elapsed.TotalSeconds)); phase.Restart(); Counter count = new Counter(); foreach (object item2 in FinalAscentFrames.Through(RunDeferred(deferred, count))) { yield return item2; } Plugin.Log.LogInfo((object)string.Format("{0} Nachlaeufe der fruehen: {1:F1}s ({2}).", "[FinalAscent]", phase.Elapsed.TotalSeconds, count.Value)); phase.Restart(); foreach (object item3 in FinalAscentFrames.Through(RunSteps(late, deferred))) { yield return item3; } Plugin.Log.LogInfo((object)string.Format("{0} Spaete Schritte: {1:F1}s.", "[FinalAscent]", phase.Elapsed.TotalSeconds)); phase.Restart(); foreach (object item4 in FinalAscentFrames.Through(RunDeferred(deferred, count))) { yield return item4; } Plugin.Log.LogInfo((object)string.Format("{0} Nachlaeufe der spaeten: {1:F1}s ({2}).", "[FinalAscent]", phase.Elapsed.TotalSeconds, count.Value)); phase.Restart(); ILevelGenFinalizer[] componentsInChildren = ((Component)grouper).GetComponentsInChildren(); Plugin.Log.LogInfo((object)(string.Format("{0} Abschluss-Schritte suchen: {1:F1}s ", "[FinalAscent]", phase.Elapsed.TotalSeconds) + $"({componentsInChildren.Length}).")); phase.Restart(); ILevelGenFinalizer[] array = componentsInChildren; foreach (ILevelGenFinalizer val in array) { FinalAscentFrames.Mark(); try { FinalAscentKeepAlive.Tick(); SeedFor((Component)(object)((val is Component) ? val : null)); val.OnLevelGenFinished(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Abschluss-Schritt wirft: " + ex.Message)); } } Plugin.Log.LogInfo((object)string.Format("{0} Abschluss: {1:F1}s.", "[FinalAscent]", phase.Elapsed.TotalSeconds)); ClearPiles(grouper); ClearHiddenSteps(grouper); SecondPass(grouper); GroundStrandedStatues(); CountStatues(); DropSpawnZoneColliders(); Fingerprint(); FinalAscentStepPrint.Finish(); if (Plugin.Diagnosing) { ProbeTempleEntrance(grouper); } FinalAscentRayBatch.Report(); FinalAscentMatchMaterialProbe.Report(); FinalAscentRayTargetMaterialProbe.Report(); Physics.autoSyncTransforms = autoSync; Physics.SyncTransforms(); Plugin.Log.LogInfo((object)(string.Format("{0} Props gesetzt nach {1:F1}s ", "[FinalAscent]", total.Elapsed.TotalSeconds) + $"(davon {_clearSeconds:F1}s Abraeumen der mitgelieferten Props).")); WeighTheMountain(grouper, memoryBefore); FinalAscentGenProfiler.Report((float)total.Elapsed.TotalSeconds); FinalAscentLoadProbe.Report(); FinalAscentLoadHud.BiomesFull(); if (Plugin.Diagnosing) { DescribeKilnSpawners(grouper); ProbeKilnShaft(grouper); ReportCitadel(grouper); } } private static void SecondPass(PropGrouper grouper) { Transform val = DeepFind(((Component)grouper).transform, "Temple_Segment"); if ((Object)(object)val == (Object)null) { return; } List list = (from spawner in ((Component)val).GetComponentsInChildren() where (Object)(object)spawner != (Object)null && ((Component)spawner).transform.childCount == 0 && spawner.nrOfSpawns > 0 select spawner).ToList(); if (list.Count == 0) { return; } int num = 0; int num2 = 0; foreach (PropSpawner item in list) { try { FinalAscentKeepAlive.Tick(); SeedFor((LevelGenStep)(object)item); IEnumerator enumerator2 = ((LevelGenStep)item).Execute(); while (enumerator2.MoveNext()) { } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + ((Object)item).name + "' im zweiten Anlauf: " + ex.Message)); } if (((Component)item).transform.childCount > 0) { num++; num2 += ((Component)item).transform.childCount; } } Plugin.Log.LogInfo((object)(string.Format("{0} Zweiter Anlauf in der Zitadelle: {1} von {2} Spawnern ", "[FinalAscent]", num, list.Count) + $"haben diesmal gesetzt ({num2} Stueck).")); } private static void GroundStrandedStatues() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: 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_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) Campfire[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); RespawnChest[] array2 = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (RespawnChest val in array2) { if ((Object)(object)val == (Object)null) { continue; } Biome componentInParent = ((Component)val).GetComponentInParent(true); if ((Object)(object)componentInParent == (Object)null || (int)componentInParent.biomeType != 3) { continue; } Transform val2 = ((Component)val).transform; while ((Object)(object)val2.parent != (Object)null && (Object)(object)((Component)val2.parent).GetComponent() == (Object)null && (Object)(object)val2.parent != (Object)(object)((Component)componentInParent).transform) { val2 = val2.parent; } Campfire val3 = null; float num = float.MaxValue; Campfire[] array3 = array; foreach (Campfire val4 in array3) { if (!((Object)(object)val4 == (Object)null)) { float num2 = Vector2.Distance(new Vector2(((Component)val4).transform.position.x, ((Component)val4).transform.position.z), new Vector2(((Component)val).transform.position.x, ((Component)val).transform.position.z)); if (num2 < num) { num = num2; val3 = val4; } } } if ((Object)(object)val3 == (Object)null || num > 80f) { Plugin.Log.LogInfo((object)("[FinalAscent] Statue '" + ((Object)val2).name + "' im Vulkanbiom hat kein Lagerfeuer in " + $"Reichweite ({num:F0}) - bleibt, wo sie ist.")); continue; } float num3 = ((Component)val).transform.position.y - ((Component)val3).transform.position.y; if (!(num3 <= 3f) && !(num3 > 400f)) { Transform obj = val2; obj.position -= Vector3.up * num3; Vector3 val5 = FinalAscentBuilder.SnapToGround(((Component)componentInParent).gameObject, ((Component)val).transform.position, 8f); float num4 = ((Component)val).transform.position.y - val5.y; if (Mathf.Abs(num4) > 0.05f && Mathf.Abs(num4) < 8f) { Transform obj2 = val2; obj2.position -= Vector3.up * num4; } Plugin.Log.LogInfo((object)(string.Format("{0} Statue '{1}' stand {2:F0} ueber '{3}' - ", "[FinalAscent]", ((Object)val2).name, num3, ((Object)val3).name) + "abgesetzt auf " + FinalAscentBuilder.Fmt(((Component)val).transform.position) + ".")); } } } internal static void CountStatues() { //IL_00af: Unknown result type (might be due to invalid IL or missing references) RespawnChest[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); Plugin.Log.LogInfo((object)string.Format("{0} {1} Statuen in der Szene:", "[FinalAscent]", array.Length)); RespawnChest[] array2 = array; foreach (RespawnChest val in array2) { if ((Object)(object)val == (Object)null) { continue; } Biome componentInParent = ((Component)val).GetComponentInParent(true); string text = ((Object)val).name; Transform parent = ((Component)val).transform.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; if ((Object)(object)componentInParent != (Object)null && (Object)(object)parent == (Object)(object)((Component)componentInParent).transform) { break; } parent = parent.parent; } Plugin.Detail("[FinalAscent] " + FinalAscentBuilder.Fmt(((Component)val).transform.position) + " " + $"sichtbar={((Component)val).gameObject.activeInHierarchy} {text}"); } } private static void ProbeKilnShaft(PropGrouper grouper) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)DeepFind(((Component)grouper).transform, "Volcano_Segment") == (Object)null) { return; } Vector3 val = FinalAscentBuilder.KilnSummit(); Dictionary dictionary = new Dictionary(); int num = 0; int num2 = 0; for (float num3 = 10f; num3 <= 330f; num3 += 15f) { for (int i = 0; i < 8; i++) { float num4 = (float)i * 45f * (MathF.PI / 180f); float[] array = new float[2] { 6f, 15f }; foreach (float num5 in array) { Vector3 val2 = new Vector3(val.x + Mathf.Cos(num4) * num5, val.y - num3, val.z + Mathf.Sin(num4) * num5); num++; Collider[] array2 = Physics.OverlapSphere(val2, 4f); foreach (Collider val3 in array2) { if (!((Object)(object)val3 == (Object)null)) { num2++; Biome componentInParent = ((Component)val3).GetComponentInParent(true); string text = (((Object)(object)componentInParent != (Object)null) ? PathUnder(((Component)componentInParent).transform, ((Component)val3).transform) : ("(ausserhalb der Biome)/" + ((Object)val3).name)); string[] array3 = text.Split('/'); string key = (((Object)(object)componentInParent != (Object)null) ? (((object)Unsafe.As(ref componentInParent.biomeType)/*cast due to .constrained prefix*/).ToString() + ": ") : "") + ((array3.Length > 2) ? (array3[0] + "/" + array3[1]) : text); dictionary.TryGetValue(key, out var value); dictionary[key] = value + 1; } } } } } Plugin.Log.LogInfo((object)string.Format("{0} Im Schlot des Kiln (ab {1:F0} abwaerts): {2} Treffer aus {3} Proben.", "[FinalAscent]", val.y, num2, num)); foreach (KeyValuePair item in dictionary.OrderByDescending((KeyValuePair e) => e.Value).Take(15)) { Plugin.Detail(string.Format("{0} {1,5}x {2}", "[FinalAscent]", item.Value, item.Key)); } } private static void ClearHiddenSteps(PropGrouper grouper) { Stopwatch stopwatch = Stopwatch.StartNew(); int num = 0; int num2 = 0; int num3 = 0; LevelGenStep[] componentsInChildren = ((Component)grouper).GetComponentsInChildren(true); foreach (LevelGenStep val in componentsInChildren) { if ((Object)(object)val == (Object)null || ((Component)val).gameObject.activeInHierarchy) { continue; } if (_executed.Contains(val)) { num3++; continue; } if (InsideInactiveVariant(((Component)val).transform)) { num2++; continue; } if (FinalAscentVoid.Owns(((Component)val).transform)) { num2++; continue; } try { val.Clear(); _hiddenCleared.Add(val); num++; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + ((Object)val).name + "' liess sich nicht leeren: " + ex.Message)); } } Plugin.Log.LogInfo((object)(string.Format("{0} {1} abgeschaltete Spawner geleert ({2} Varianten ", "[FinalAscent]", num, num2) + $"ausgelassen, {num3} frisch bestueckte verschont) " + $"in {stopwatch.Elapsed.TotalSeconds:F1}s.")); } internal static bool InsideInactiveVariant(Transform member) { Transform val = member; while ((Object)(object)val != (Object)null) { if (!((Component)val).gameObject.activeSelf && ((Object)(object)((Component)val).GetComponent() != (Object)null || (Object)(object)((Component)val).GetComponent() != (Object)null)) { return true; } val = val.parent; } return false; } private static void ClearPiles(PropGrouper grouper) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) int num = 0; int num2 = 0; PropSpawner[] componentsInChildren = ((Component)grouper).GetComponentsInChildren(true); Bounds val2 = default(Bounds); foreach (PropSpawner val in componentsInChildren) { int childCount = ((Component)val).transform.childCount; if (childCount < 25) { continue; } ((Bounds)(ref val2))..ctor(((Component)val).transform.GetChild(0).position, Vector3.zero); for (int j = 1; j < childCount; j++) { ((Bounds)(ref val2)).Encapsulate(((Component)val).transform.GetChild(j).position); } Vector3 size = ((Bounds)(ref val2)).size; if (!(((Vector3)(ref size)).magnitude > 20f)) { string text = string.Format("{0} Haufen: '{1}' hat {2} Teile auf ", "[FinalAscent]", ((Object)val).name, childCount); size = ((Bounds)(ref val2)).size; Plugin.Detail(text + $"{((Vector3)(ref size)).magnitude:F1} Einheiten gestapelt, bei " + FinalAscentBuilder.Fmt(((Bounds)(ref val2)).center) + " - abgeraeumt."); try { ((LevelGenStep)val).Clear(); num++; num2 += childCount; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + ((Object)val).name + "' liess sich nicht raeumen: " + ex.Message)); } } } Plugin.Log.LogInfo((object)string.Format("{0} {1} Haufen mit {2} Teilen abgeraeumt.", "[FinalAscent]", num, num2)); } private static void DescribeKilnSpawners(PropGrouper grouper) { //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) Transform val = DeepFind(((Component)grouper).transform, "Volcano_Segment"); if ((Object)(object)val == (Object)null) { return; } string[] array = new string[2] { "Middle", "Edges" }; foreach (string text in array) { Transform val2 = DeepFind(val, text); if ((Object)(object)val2 == (Object)null) { continue; } List list = new List(); Component[] components = ((Component)val2).GetComponents(); foreach (Component val3 in components) { if ((Object)(object)val3 != (Object)null && !(val3 is Transform)) { list.Add(((object)val3).GetType().Name); } } Plugin.Detail("[FinalAscent] Kiln/" + text + ": Bauteile [" + string.Join(", ", list) + "], " + $"{val2.childCount} Kinder."); PropSpawner[] componentsInChildren = ((Component)val2).GetComponentsInChildren(true); foreach (PropSpawner val4 in componentsInChildren) { List list2 = new List(); Vector3 up = ((Component)val4).transform.up; Vector3 position = ((Component)val4).transform.position; for (int k = 0; k < ((Component)val4).transform.childCount; k++) { Vector3 val5 = ((Component)val4).transform.GetChild(k).position - position; Vector3 val6 = Vector3.ProjectOnPlane(val5, up); list2.Add(((Vector3)(ref val6)).magnitude); } list2.Sort(); PropSpawner_Line val7 = (PropSpawner_Line)(object)((val4 is PropSpawner_Line) ? val4 : null); string text2 = ((val7 != null) ? ($"Laenge {val7.height:F0}, Kern {val7.coreWidth:F1}, " + $"Streuung {val7.RayWiggle:F2}, Richtungsdrall {val7.castDirectionBias:F2}") : $"Flaeche {val4.area.x:F1}x{val4.area.y:F1}"); string arg = ((list2.Count > 0) ? ($"Abstand zur Achse min {list2[0]:F1} / mittel {list2[list2.Count / 2]:F1} " + $"/ max {list2[list2.Count - 1]:F1}") : "nichts gesetzt"); Plugin.Detail("[FinalAscent] " + ((object)val4).GetType().Name + " '" + ((Object)val4).name + "': " + text2 + ", " + $"Strahl {val4.rayLength:F0}, Soll {val4.nrOfSpawns}, " + $"gesetzt {((Component)val4).transform.childCount}, {arg}, " + $"sieht sich selbst: {val4.syncTransforms}."); } } } internal static void ClearEverything(PropGrouper grouper) { ClearEverythingFirst(grouper); } private static void ClearEverythingFirst(PropGrouper grouper) { Stopwatch stopwatch = Stopwatch.StartNew(); LevelGenStep[] componentsInChildren = ((Component)grouper).GetComponentsInChildren(true); int num = 0; int num2 = 0; int num3 = 0; LevelGenStep[] array = componentsInChildren; foreach (LevelGenStep val in array) { if ((Object)(object)val == (Object)null) { continue; } if (FinalAscentVoid.Owns(((Component)val).transform)) { num3++; continue; } try { val.Clear(); num++; } catch (Exception ex) { num2++; if (num2 <= 3) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + ((Object)val).name + "' laesst sich nicht abraeumen: " + ex.Message)); } } } Physics.SyncTransforms(); if (num3 > 0) { Plugin.Log.LogInfo((object)(string.Format("{0} {1} Schritte des Nichts ausgelassen - was nicht gebaut ", "[FinalAscent]", num3) + "wird, wird auch nicht abgeraeumt. Sonst faellt die Nadir-Strecke weg.")); } Plugin.Log.LogInfo((object)(string.Format("{0} Berg abgeraeumt: {1} von {2} Schritten in ", "[FinalAscent]", num, componentsInChildren.Length) + $"{stopwatch.Elapsed.TotalSeconds:F1}s" + ((num2 > 0) ? $", {num2} verweigert." : ".") + " Erst jetzt wird gesetzt.")); } private static void ProbeTempleEntrance(PropGrouper grouper) { //IL_004c: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) Transform val = DeepFind(((Component)grouper).transform, "Temple Entrance") ?? DeepFind(((Component)grouper).transform, "Temple_Segment"); if ((Object)(object)val == (Object)null) { return; } Transform val2 = DeepFind(((Component)grouper).transform, "Temple_Segment") ?? val; List list = new List { val.position }; Transform val3 = DeepFind(((Component)grouper).transform, "Campfire-Temple"); if ((Object)(object)val3 != (Object)null) { list.Add(val3.position); } Transform val4 = DeepFind(((Component)grouper).transform, "Central Tower Entry") ?? DeepFind(((Component)grouper).transform, "Central Tower maze"); if ((Object)(object)val4 != (Object)null) { list.Add(val4.position); } Dictionary dictionary = new Dictionary(); int num = 0; Vector3 val6 = default(Vector3); foreach (Vector3 item in list) { for (int i = 0; i < 4; i++) { float num2 = 1f + (float)i * 2.5f; for (int j = 0; j < 20; j++) { float num3 = (float)j * 18f * (MathF.PI / 180f); Vector3 val5 = item + Vector3.up * num2; ((Vector3)(ref val6))..ctor(Mathf.Cos(num3), 0f, Mathf.Sin(num3)); num++; RaycastHit[] array = Physics.RaycastAll(val5, val6, 26f, -1, (QueryTriggerInteraction)1); for (int k = 0; k < array.Length; k++) { RaycastHit val7 = array[k]; if ((Object)(object)((RaycastHit)(ref val7)).collider == (Object)null || ((Component)((RaycastHit)(ref val7)).collider).transform.IsChildOf(val2)) { continue; } Transform val8 = ((Component)((RaycastHit)(ref val7)).collider).transform; bool flag = false; Transform val9 = val8; while ((Object)(object)val9 != (Object)null) { if (((Object)val9).name.EndsWith("(Clone)")) { val8 = val9; flag = true; break; } val9 = val9.parent; } if (flag) { string key = (((Object)(object)val8.parent != (Object)null) ? (((Object)val8.parent).name + "/" + ((Object)val8).name) : ((Object)val8).name); dictionary.TryGetValue(key, out var value); dictionary[key] = value + 1; } } } } } if (dictionary.Count == 0) { Plugin.Log.LogInfo((object)string.Format("{0} Eingang der Zitadelle frei ({1} Proben, nichts Fremdes im Weg).", "[FinalAscent]", num)); return; } List list2 = new List(); foreach (KeyValuePair item2 in dictionary.OrderByDescending((KeyValuePair e) => e.Value).Take(6)) { list2.Add($"{item2.Value}x {item2.Key}"); } Plugin.Log.LogWarning((object)(string.Format("{0} Am Eingang der Zitadelle steht etwas ({1} Proben): ", "[FinalAscent]", num) + string.Join(", ", list2))); } private static string SettingsKey() { return $"seed={FinalAscent.Seed}" + (FinalAscentSetup.RandomSeed ? "(ausgelost)" : "") + "|" + (FinalAscentSetup.RandomVariants ? "varianten=zufall" : FinalAscentSetup.Serialize()); } internal static void FingerprintNow() { try { Fingerprint(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Abdruck nach dem Auspacken misslungen: " + ex.Message)); } } private static void Fingerprint() { //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) Stopwatch stopwatch = Stopwatch.StartNew(); string key = SettingsKey(); SortedDictionary sortedDictionary = new SortedDictionary(); _props.Clear(); _sums.Clear(); _seats.Clear(); _shown.Clear(); _solid.Clear(); Biome[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Biome val in array) { if ((Object)(object)val == (Object)null) { continue; } long num = 0L; int num2 = 0; PropSpawner[] componentsInChildren = ((Component)val).GetComponentsInChildren(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")) { Vector3 val3 = ((Component)val).transform.InverseTransformPoint(child.position); long num3 = 1469598103934665603L; num3 = (num3 ^ Mathf.RoundToInt(val3.x * 100f)) * 1099511628211L; num3 = (num3 ^ Mathf.RoundToInt(val3.y * 100f)) * 1099511628211L; num3 = (num3 ^ Mathf.RoundToInt(val3.z * 100f)) * 1099511628211L; num += num3; num2++; } } } int num4 = 0; Renderer[] componentsInChildren2 = ((Component)val).GetComponentsInChildren(true); foreach (Renderer val4 in componentsInChildren2) { if ((Object)(object)val4 != (Object)null && val4.enabled && ((Component)val4).gameObject.activeInHierarchy) { num4++; } } int num5 = 0; Collider[] componentsInChildren3 = ((Component)val).GetComponentsInChildren(true); foreach (Collider val5 in componentsInChildren3) { if ((Object)(object)val5 != (Object)null && val5.enabled && ((Component)val5).gameObject.activeInHierarchy) { num5++; } } _props.TryGetValue(val.biomeType, out var value); _sums.TryGetValue(val.biomeType, out var value2); _shown.TryGetValue(val.biomeType, out var value3); _solid.TryGetValue(val.biomeType, out var value4); _props[val.biomeType] = value + num2; _sums[val.biomeType] = value2 ^ num; _shown[val.biomeType] = value3 + num4; _solid[val.biomeType] = value4 + num5; if (!_seats.ContainsKey(val.biomeType)) { _seats[val.biomeType] = ((Component)val).transform.position; } } foreach (KeyValuePair prop in _props) { int value5 = prop.Value; long num6 = _sums[prop.Key]; Vector3 val6 = _seats[prop.Key]; sortedDictionary[((object)prop.Key/*cast due to .constrained prefix*/).ToString()] = $"{value5}/{num6 & 0xFFFFFF:X6}/{_shown[prop.Key]}s/{_solid[prop.Key]}k" + $" @ {val6.x:F1},{val6.y:F1},{val6.z:F1}"; } Compare(key, sortedDictionary); Save(key, sortedDictionary); SortedDictionary sortedDictionary2 = FinalAscentMatch.Trim(sortedDictionary); FinalAscentMatch.Publish(sortedDictionary2); FinalAscentMatch.CompareLater(sortedDictionary2); FinalAscentExact.PublishSteps(); FinalAscentExact.CompareAndRepairLater(); Plugin.Detail(string.Format("{0} Abdruck genommen in {1:F1}s.", "[FinalAscent]", stopwatch.Elapsed.TotalSeconds)); } private static void Compare(string key, SortedDictionary now) { SortedDictionary sortedDictionary = new SortedDictionary(); string text = null; try { if (File.Exists(FingerprintPath)) { string[] array = File.ReadAllLines(FingerprintPath); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.StartsWith("#") || text2.Length == 0) { continue; } if (text == null) { text = text2; continue; } int num = text2.IndexOf('='); if (num > 0) { sortedDictionary[text2.Substring(0, num)] = text2.Substring(num + 1); } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Abdruck des vorigen Laufs unlesbar: " + ex.Message)); } foreach (KeyValuePair item in now) { Plugin.Log.LogInfo((object)("[FinalAscent] Abdruck " + item.Key + ": " + item.Value)); } if (text == null) { Plugin.Log.LogInfo((object)"[FinalAscent] Kein Abdruck vom vorigen Lauf - beim naechsten Start mit denselben Einstellungen wird verglichen."); return; } bool flag = text == key; List list = new List(); List list2 = new List(); foreach (KeyValuePair item2 in now) { sortedDictionary.TryGetValue(item2.Key, out var value); if (value == item2.Value) { list.Add(item2.Key); continue; } list2.Add(item2.Key + ": war " + (value ?? "-") + ", jetzt " + item2.Value); } if (list2.Count == 0) { Plugin.Log.LogInfo((object)("[FinalAscent] SEED-TREUE: derselbe Berg wie im vorigen Lauf, in allen " + $"{now.Count} Biomen.")); return; } if (flag) { Plugin.Log.LogWarning((object)("[FinalAscent] SEED-TREUE VERLETZT bei gleichen Einstellungen: " + string.Join("; ", list2))); return; } Plugin.Log.LogInfo((object)("[FinalAscent] Einstellungen wurden geaendert. Unveraendert: " + ((list.Count > 0) ? string.Join(", ", list) : "keines") + ". Anders: " + string.Join("; ", list2))); Plugin.Log.LogInfo((object)("[FinalAscent] Damals: " + text)); } private static void Save(string key, SortedDictionary now) { try { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# Abdruck des letzten Final Ascent - zum Vergleich beim naechsten Lauf."); stringBuilder.AppendLine("# Erste Zeile: die Einstellungen. Danach je Biom Props/Pruefsumme."); stringBuilder.AppendLine(key); foreach (KeyValuePair item in now) { stringBuilder.AppendLine(item.Key + "=" + item.Value); } if (Plugin.Diagnosing) { File.WriteAllText(FingerprintPath, stringBuilder.ToString()); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Abdruck nicht abgelegt: " + ex.Message)); } } private static void SeedFor(LevelGenStep step) { SeedFor((Component)(object)step); } private static void SeedFor(Component owner) { Random.InitState(((Object)(object)owner != (Object)null) ? (FinalAscent.Seed ^ StableHash(PathOf(owner.transform))) : FinalAscent.Seed); } private static string PathOf(Transform leaf) { StringBuilder stringBuilder = new StringBuilder(((Object)leaf).name); Transform parent = leaf.parent; while ((Object)(object)parent != (Object)null) { stringBuilder.Insert(0, '/').Insert(0, ((Object)parent).name); parent = parent.parent; } return stringBuilder.ToString(); } private static int StableHash(string text) { uint num = 2166136261u; foreach (char c in text) { num = (num ^ c) * 16777619; } return (int)num; } internal static void PostUnpackCleanup() { try { DropSpawnZoneColliders(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Nachlese gestolpert: " + ex.Message)); } } private static void DropSpawnZoneColliders() { int num = 0; int num2 = 0; SpawnZone[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (SpawnZone val in array) { if (!((Object)(object)val == (Object)null)) { num2++; int num3 = 0; Collider[] components = ((Component)val).GetComponents(); for (int j = 0; j < components.Length; j++) { Object.Destroy((Object)(object)components[j]); num++; num3++; } if (num3 > 0) { Plugin.Detail(string.Format("{0} Zone ({1} Kollider): {2}", "[FinalAscent]", num3, PathOf(((Component)val).transform))); } } } Plugin.Log.LogInfo((object)(string.Format("{0} {1} Kollider an {2} Spawnzonen abgeraeumt - ", "[FinalAscent]", num, num2) + "sie haben ihren Dienst getan.")); } private static IEnumerator RunSteps(List steps, List deferred) { foreach (LevelGenStep step in steps) { foreach (object item in FinalAscentFrames.Through(RunOneStep(step, deferred))) { yield return item; } } } private static IEnumerator RunOneStep(LevelGenStep step, List deferred) { if ((Object)(object)step == (Object)null) { yield break; } Announce(step); _executed.Add(step); FinalAscentLoadHud.BiomeBegin(_lastBiome); FinalAscentKeepAlive.Tick(); Stopwatch clock = Stopwatch.StartNew(); SeedFor(step); Physics.queriesHitBackfaces = false; FinalAscentRayBatch.Begin(step); FinalAscentSpawnAudit.Begin(); IEnumerator run = null; try { Stopwatch stopwatch = Stopwatch.StartNew(); step.Clear(); _clearSeconds += stopwatch.Elapsed.TotalSeconds; run = step.Execute(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + ((Object)step).name + "' abgebrochen: " + ex.Message)); } if (run != null) { FinalAscentLoadProbe.Where(PathOf(((Component)step).transform)); FinalAscentLoadProbe.Piece(); PropSpawner val = (PropSpawner)(object)((step is PropSpawner) ? step : null); float target = ((val != null && val.nrOfSpawns > 0) ? ((float)val.nrOfSpawns) : 0f); int placed = 0; while (true) { bool flag; try { flag = run.MoveNext(); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + ((Object)step).name + "' abgebrochen: " + ex2.Message)); break; } if (!flag) { break; } FinalAscentKeepAlive.Tick(); Physics.SyncTransforms(); FinalAscentLoadProbe.Piece(); FinalAscentFrames.Piece(); if (target > 0f) { placed++; FinalAscentLoadHud.BiomeProgress((float)placed / target); } if (FinalAscentFrames.Due) { FinalAscentStepPrint.Boundary(((Component)step).transform.childCount); FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); } } } FinalAscentRayBatch.End(); FinalAscentStepPrint.Note((Component)(object)step); FinalAscentGenProfiler.Record(step, (float)clock.Elapsed.TotalSeconds); FinalAscentLoadHud.BiomeStep(_lastBiome); string lastBiome = _lastBiome; _lastBiome = null; if ((int)step.DeferredTiming == 0) { yield break; } bool flag2 = false; try { IDeferredStep val2 = step.ConstructDeferred((IMayHaveDeferredStep)(object)step); if (val2 != null) { deferred.Add(new Deferred(step, val2)); flag2 = true; } } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + ((Object)step).name + "' ohne Nachlauf: " + ex3.Message)); } if (!flag2) { FinalAscentLoadHud.BiomeCredit(lastBiome, DeferredWeight(step)); } } private static IEnumerator RunDeferred(List deferred, Counter counter) { counter.Value = deferred.Count; List list = new List(deferred); deferred.Clear(); foreach (Deferred later in list) { try { SeedFor(later.Source); FinalAscentLoadProbe.Where("Nachlauf " + PathOf(((Component)later.Source).transform)); Plugin.Detail("[FinalAscent] Nachlauf von '" + PathOf(((Component)later.Source).transform) + "'."); FinalAscentLoadHud.Detail("Nachlauf " + PathOf(((Component)later.Source).transform)); Biome componentInParent = ((Component)later.Source).GetComponentInParent(true); _lastBiome = (((Object)(object)componentInParent != (Object)null) ? ((object)Unsafe.As(ref componentInParent.biomeType)/*cast due to .constrained prefix*/).ToString() : null); FinalAscentLoadHud.BiomeBegin(_lastBiome, DeferredWeight(later.Source)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Nachlauf wirft: " + ex.Message)); continue; } foreach (object item in FinalAscentFrames.Through(RunOneDeferred(later.Step))) { yield return item; } FinalAscentStepPrint.Note((Component)(object)later.Source, "+nachlauf"); FinalAscentLoadHud.BiomeStep(_lastBiome); _lastBiome = null; } } private static IEnumerator RunOneDeferred(IDeferredStep later) { FinalAscentKeepAlive.Tick(); FieldInfo fieldInfo = AccessTools.Field(((object)later).GetType(), "_steps"); if (fieldInfo != null && fieldInfo.GetValue(later) is List list) { foreach (IDeferredStep item in list) { foreach (object item2 in FinalAscentFrames.Through(RunChildSpawners(item))) { yield return item2; } } FinalAscentKeepAlive.Tick(); } else { Stopwatch stopwatch = Stopwatch.StartNew(); try { later.DeferredGo(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Nachlauf wirft: " + ex.Message)); } FinalAscentKeepAlive.Tick(); Plugin.Log.LogInfo((object)("[FinalAscent] Nachlauf '" + ((object)later).GetType().Name + "' war nicht zu zerlegen und lief " + $"{stopwatch.Elapsed.TotalSeconds:F1}s am Stueck.")); } } private static IEnumerator RunChildSpawners(IDeferredStep part) { FinalAscentKeepAlive.Tick(); object obj = AccessTools.Field(((object)part).GetType(), "_behavior")?.GetValue(part); object obj2 = AccessTools.Field(((object)part).GetType(), "_spawnedObjects")?.GetValue(part); if (!(obj is PSB_ChildSpawners) || !(obj2 is List spawned)) { Stopwatch stopwatch = Stopwatch.StartNew(); part.DeferredGo(); FinalAscentKeepAlive.Tick(); Plugin.Log.LogInfo((object)("[FinalAscent] Nachlauf '" + ((object)part).GetType().Name + "' (Verhalten '" + ((obj != null) ? obj.GetType().Name : "unbekannt") + "', Liste '" + ((obj2 != null) ? obj2.GetType().Name : "unbekannt") + "') " + $"lief {stopwatch.Elapsed.TotalSeconds:F1}s am Stueck.")); yield break; } object obj3 = AccessTools.Field(((object)part).GetType(), "_syncTransforms")?.GetValue(part); bool flag = default(bool); int num; if (obj3 is bool) { flag = (bool)obj3; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { Physics.SyncTransforms(); } int missing = 0; string lastName = string.Empty; for (int i = 0; i < spawned.Count; i++) { GameObject item = spawned[i]; if ((Object)(object)item == (Object)null) { missing++; continue; } lastName = ((Object)item).name; LevelGenStep[] inner = item.GetComponentsInChildren(); for (int j = 0; j < inner.Length; j++) { LevelGenStep val = inner[j]; FinalAscentLoadHud.Detail("Sofortschritt " + ((Object)item).name + " / " + ((Object)val).name); FinalAscentLoadHud.BiomeProgress(((float)i + ((float)j + 1f) / (float)inner.Length) / (float)spawned.Count); foreach (object item2 in FinalAscentFrames.Through(RunImmediate(val, ((Object)item).name))) { yield return item2; } FinalAscentKeepAlive.Tick(); FinalAscentFrames.Piece(); if (FinalAscentFrames.Due) { FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); } } } if (missing > 0) { Plugin.Log.LogError((object)(string.Format("{0} {1} fehlende ", "[FinalAscent]", missing) + ((lastName.Length == 0) ? "Objekte" : lastName) + " in einer Liste von " + $"{spawned.Count} Kind-Spawnern.")); } Plugin.Detail(string.Format("{0} Nachlauf 'PSB_ChildSpawners' ueber {1} Props gelaufen.", "[FinalAscent]", spawned.Count)); } private static IEnumerator RunImmediate(LevelGenStep step, string owner) { if ((Object)(object)step == (Object)null) { yield break; } PropSpawner val = (PropSpawner)(object)((step is PropSpawner) ? step : null); if (val == null) { try { step.ExecuteImmediately(); yield break; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Sofortschritt '" + ((Object)step).name + "' abgebrochen: " + ex.Message)); yield break; } } IEnumerator run = null; try { ((LevelGenStep)val).Clear(); run = val.SpawnNew(true); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[FinalAscent] Sofortschritt '" + ((Object)step).name + "' abgebrochen: " + ex2.Message)); } if (run == null) { yield break; } FinalAscentLoadProbe.Where("Sofortschritt " + ((Object)step).name + " in " + owner); FinalAscentLoadProbe.Piece(); while (true) { bool flag; try { flag = run.MoveNext(); } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[FinalAscent] Sofortschritt '" + ((Object)step).name + "' abgebrochen: " + ex3.Message)); break; } if (flag) { FinalAscentKeepAlive.Tick(); Physics.SyncTransforms(); FinalAscentLoadProbe.Piece(); FinalAscentFrames.Piece(); if (FinalAscentFrames.Due) { FinalAscentFrames.Hold(); yield return null; FinalAscentFrames.Resume(); FinalAscentFrames.Mark(); } continue; } break; } } private static void WeighTheMountain(PropGrouper grouper, long before) { if ((Object)(object)grouper == (Object)null || !Plugin.Diagnosing) { return; } try { Transform[] componentsInChildren = ((Component)grouper).GetComponentsInChildren(true); long totalAllocatedMemoryLong = Profiler.GetTotalAllocatedMemoryLong(); long num = totalAllocatedMemoryLong - before; Plugin.Log.LogInfo((object)(string.Format("{0} Der Berg wiegt: {1} Objekte, ", "[FinalAscent]", componentsInChildren.Length) + $"waehrend der Generierung kamen {(float)num / 1048576f:F0} MB dazu " + $"(jetzt insgesamt {(float)totalAllocatedMemoryLong / 1048576f:F0} MB).")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Berg liess sich nicht wiegen: " + ex.Message)); } } private static int DeferredWeight(LevelGenStep step) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 PropSpawner val = (PropSpawner)(object)((step is PropSpawner) ? step : null); if (val == null || val.postSpawnBehaviors == null) { return 0; } bool flag = false; foreach (PostSpawnBehavior postSpawnBehavior in val.postSpawnBehaviors) { if (postSpawnBehavior != null && !postSpawnBehavior.mute && (int)postSpawnBehavior.DeferredTiming == 2) { flag = true; break; } } if (!flag) { return 0; } if (val.nrOfSpawns <= 0) { return 1; } return val.nrOfSpawns; } private static void CountBiomes(List early, List late) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = new Dictionary(); List[] array = new List[2] { early, late }; for (int i = 0; i < array.Length; i++) { foreach (LevelGenStep item in array[i]) { Biome val = (((Object)(object)item != (Object)null) ? ((Component)item).GetComponentInParent(true) : null); if (!((Object)(object)val == (Object)null)) { string key = ((object)Unsafe.As(ref val.biomeType)/*cast due to .constrained prefix*/).ToString(); dictionary.TryGetValue(key, out var value); dictionary[key] = value + 1 + DeferredWeight(item); } } } List> list = new List>(); BiomeType[] climbOrder = ClimbOrder; for (int i = 0; i < climbOrder.Length; i++) { string key2 = ((object)climbOrder[i]/*cast due to .constrained prefix*/).ToString(); if (dictionary.TryGetValue(key2, out var value2)) { list.Add(new KeyValuePair(key2, value2)); dictionary.Remove(key2); } } foreach (KeyValuePair item2 in dictionary) { list.Add(item2); } FinalAscentLoadHud.Biomes(list); Plugin.Log.LogInfo((object)("[FinalAscent] Soll je Landschaft (Schritte plus Gewicht der Nachlaeufe): " + string.Join(", ", list.ConvertAll((KeyValuePair e) => $"{e.Key} {e.Value}")))); } private static void Announce(LevelGenStep step) { if (!((Object)(object)step == (Object)null)) { Biome componentInParent = ((Component)step).GetComponentInParent(true); if ((Object)(object)componentInParent == (Object)null) { FinalAscentLoadHud.Detail("(ausserhalb der Biome) / " + ((Object)step).name); _lastBiome = null; } else { FinalAscentLoadHud.DetailBiome(((object)Unsafe.As(ref componentInParent.biomeType)/*cast due to .constrained prefix*/).ToString(), ((Object)step).name); _lastBiome = ((object)Unsafe.As(ref componentInParent.biomeType)/*cast due to .constrained prefix*/).ToString(); } } } private static int TimingRank(LevelGenStep step) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 PropGrouper componentInParent = ((Component)step).GetComponentInParent(true); if (!((Object)(object)componentInParent != (Object)null) || (int)componentInParent.timing != 1) { return 0; } return 1; } private static void ReportCitadel(PropGrouper grouper) { //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_057d: Unknown result type (might be due to invalid IL or missing references) Transform val = DeepFind(((Component)grouper).transform, "Temple_Segment"); if ((Object)(object)val == (Object)null) { return; } PropSpawner[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); int num = 0; List list = new List(); PropSpawner[] array = componentsInChildren; foreach (PropSpawner val2 in array) { if (((Component)val2).transform.childCount > 0) { num++; } else if (list.Count < 25) { string arg = ((val2.constraints == null) ? "-" : string.Join("+", from c in val2.constraints where c != null && !c.mute select ((object)c).GetType().Name.Replace("PSC_", ""))); list.Add($"{((Object)val2).name} (0 von {val2.nrOfSpawns}, " + $"aktiv={((Component)val2).gameObject.activeInHierarchy}): {arg}"); } } SpawnZone[] componentsInChildren2 = ((Component)val).GetComponentsInChildren(true); Plugin.Log.LogInfo((object)string.Format("{0} Zitadelle: {1} SpawnZones.", "[FinalAscent]", componentsInChildren2.Length)); for (int num2 = 0; num2 < componentsInChildren2.Length && num2 < 10; num2++) { Collider component = ((Component)componentsInChildren2[num2]).GetComponent(); Plugin.Detail("[FinalAscent] Zone '" + ((Object)componentsInChildren2[num2]).name + "' bei " + FinalAscentBuilder.Fmt(((Component)componentsInChildren2[num2]).transform.position) + ", " + $"aktiv={((Component)componentsInChildren2[num2]).gameObject.activeInHierarchy}, " + "Kollider=" + (((Object)(object)component == (Object)null) ? "KEINER" : (((object)component).GetType().Name + (component.enabled ? "" : " (aus)") + (component.isTrigger ? " (Trigger)" : "")))); } Plugin.Detail(string.Format("{0} Kugelabfragen treffen Trigger: {1}", "[FinalAscent]", Physics.queriesHitTriggers)); Plugin.Log.LogInfo((object)string.Format("{0} Zitadelle: {1} von {2} Spawnern haben gesetzt.", "[FinalAscent]", num, componentsInChildren.Length)); foreach (string item in list) { Plugin.Detail("[FinalAscent] leer: " + item); } array = componentsInChildren; foreach (PropSpawner val3 in array) { if (((Component)val3).transform.childCount <= 0 && !((Component)val3).gameObject.activeInHierarchy) { Transform val4 = ((Component)val3).transform; while ((Object)(object)val4 != (Object)null && ((Component)val4).gameObject.activeSelf) { val4 = val4.parent; } Plugin.Detail("[FinalAscent] '" + ((Object)val3).name + "' ist aus, weil '" + (((Object)(object)val4 != (Object)null) ? ((Object)val4).name : "?") + "' aus ist."); } } array = componentsInChildren; foreach (PropSpawner val5 in array) { if (((Component)val5).transform.childCount <= 0 && ((Component)val5).gameObject.activeInHierarchy && val5.constraints != null && val5.constraints.Count != 0) { AskConstraints(val5); } } Transform val6 = DeepFind(((Component)grouper).transform, "Volcano_Segment"); if (!((Object)(object)val6 != (Object)null)) { return; } List> list2 = new List>(); array = ((Component)val6).GetComponentsInChildren(true); foreach (PropSpawner val7 in array) { list2.Add(new KeyValuePair(((Object)val7).name, ((Component)val7).transform.childCount)); } Plugin.Detail(string.Format("{0} Kiln: {1} Props aus {2} Spawnern. Die dichtesten:", "[FinalAscent]", list2.Sum((KeyValuePair c) => c.Value), list2.Count)); foreach (PropSpawner item2 in (from sp in ((Component)val6).GetComponentsInChildren(true) orderby ((Component)sp).transform.childCount descending select sp).Take(12)) { string text = ((item2.constraints == null || item2.constraints.Count == 0) ? "keine" : string.Join("+", from c in item2.constraints where c != null && !c.mute select ((object)c).GetType().Name.Replace("PSC_", ""))); Plugin.Detail(string.Format("{0} {1,5}x {2} bei ", "[FinalAscent]", ((Component)item2).transform.childCount, PathUnder(val6, ((Component)item2).transform)) + FinalAscentBuilder.Fmt(((Component)item2).transform.position) + ", Bedingungen: " + text); } foreach (PropSpawner item3 in (from sp in ((Component)val6).GetComponentsInChildren(true) orderby ((Component)sp).transform.childCount descending select sp).Take(4)) { if (item3.constraints != null && item3.constraints.Count > 0) { AskConstraints(item3); } } } private static void AskConstraints(PropSpawner spawner) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown //IL_02ce: Unknown result type (might be due to invalid IL or missing references) int[] array = new int[spawner.constraints.Count]; int num = 0; RaycastHit hit = default(RaycastHit); for (int i = 0; i < 30; i++) { if (!Physics.Raycast(((Component)spawner).transform.position + ((Component)spawner).transform.right * Random.Range(-0.5f, 0.5f) * spawner.area.x + ((Component)spawner).transform.up * Random.Range(-0.5f, 0.5f) * spawner.area.y, ((Component)spawner).transform.forward, ref hit, spawner.rayLength, LayerMask.op_Implicit(HelperFunctions.GetMask(spawner.layerType)))) { continue; } num++; SpawnData val = new SpawnData { spawnerTransform = ((Component)spawner).transform, pos = ((RaycastHit)(ref hit)).point, normal = ((RaycastHit)(ref hit)).normal, rayDir = ((Component)spawner).transform.forward, hit = hit, placement = Vector2.one * 0.5f, spawnCount = 0 }; for (int j = 0; j < spawner.constraints.Count; j++) { PropSpawnerConstraint val2 = spawner.constraints[j]; if (val2 != null && !val2.mute) { bool flag; try { flag = val2.CheckConstraint(val); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + ((Object)spawner).name + "': " + ((object)val2).GetType().Name + " wirft " + ex.GetType().Name + ".")); flag = false; } if (!flag) { array[j]++; } } } } for (int k = 0; k < spawner.constraints.Count; k++) { if (array[k] == 0) { continue; } PropSpawnerConstraint obj = spawner.constraints[k]; PSC_NearObject val3 = (PSC_NearObject)(object)((obj is PSC_NearObject) ? obj : null); if (val3 == null) { continue; } string text = ((val3.objects == null) ? "(nichts)" : string.Join(", ", from o in val3.objects where (Object)(object)o != (Object)null select ((Object)o).name)); Plugin.Detail(string.Format("{0} '{1}' sucht (Radius {2:F1}): {3}", "[FinalAscent]", ((Object)spawner).name, val3.radius, text)); HashSet hashSet = new HashSet(); Collider[] array2 = Physics.OverlapSphere(((Component)spawner).transform.position, Mathf.Max(val3.radius, 25f)); foreach (Collider val4 in array2) { if ((Object)(object)val4 != (Object)null && (Object)(object)((Component)val4).transform.parent != (Object)null && hashSet.Count < 15) { hashSet.Add(((Object)((Component)val4).transform.parent).name); } } Plugin.Detail("[FinalAscent] tatsaechlich in der Naehe: " + ((hashSet.Count > 0) ? string.Join(", ", hashSet) : "nichts")); } List list = new List(); for (int num3 = 0; num3 < spawner.constraints.Count; num3++) { if (array[num3] > 0) { list.Add(((object)spawner.constraints[num3]).GetType().Name.Replace("PSC_", "") + " " + $"{array[num3]}/{num}"); } } Plugin.Detail(string.Format("{0} '{1}': {2} von {3} Proben trafen Boden, ", "[FinalAscent]", ((Object)spawner).name, num, 30) + "abgelehnt von " + ((list.Count > 0) ? string.Join(", ", list) : "nichts") + "."); } private static string PathUnder(Transform root, Transform member) { string text = ((Object)member).name; Transform parent = member.parent; while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private static Transform DeepFind(Transform root, string name) { if (((Object)root).name == name) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = DeepFind(root.GetChild(i), name); if ((Object)(object)val != (Object)null) { return val; } } return null; } static FinalAscentGeneration() { BiomeType[] array = new BiomeType[7]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); ClimbOrder = (BiomeType[])(object)array; } } [HarmonyPatch(typeof(SpawnZone), "Start")] internal static class FinalAscentSpawnZonePatch { private static bool Prefix() { return !FinalAscent.Active; } } internal static class FinalAscentGhostBallProbe { private const string Tag = "[FinalAscent]"; internal static void Report() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) GhostBallSpawner val = Object.FindFirstObjectByType((FindObjectsInactive)1); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[FinalAscent] GROSSER GEIST: kein GhostBallSpawner in der Szene - dann kann er gar nicht kommen."); return; } string text; try { text = RunSettings.GetValue((SETTINGTYPE)3200, false).ToString(); } catch (Exception ex) { text = "unlesbar (" + ex.Message + ")"; } PhotonView component = ((Component)val).GetComponent(); Plugin.Log.LogInfo((object)("[FinalAscent] GROSSER GEIST: Spawner '" + ((Object)val).name + "' bei " + FinalAscentBuilder.Fmt(((Component)val).transform.position) + ", " + $"aktiv={((Component)val).gameObject.activeInHierarchy}, " + $"Rufnummer={(((Object)(object)component != (Object)null) ? component.ViewID : 0)}, " + $"gehoert mir={(Object)(object)component != (Object)null && component.IsMine}.")); Plugin.Log.LogInfo((object)("[FinalAscent] Lauf-Einstellung Hazard_BigGhost = " + text + " (0 hiesse: abgeschaltet, dann ist alles andere gleichgueltig).")); Plugin.Log.LogInfo((object)("[FinalAscent] Schranken: Hoehe " + Height(val, "maxHeightTransform") + ", Tiefe " + Height(val, "spawnMaxDepthTransform", z: true) + ", Spawnabstand " + Num(val, "spawnOffset") + ", Streuung " + Num(val, "spawnOffsetRandomization") + ".")); Plugin.Log.LogInfo((object)"[FinalAscent] ZUR ERINNERUNG: ein Ziel gilt nur, wenn KEIN anderer Spieler naeher als (Streuung + 5) an ihm steht. Wer zu zweit beieinander bleibt, sieht den Geist womoeglich nie - das ist Vanilla, nicht wir."); } private static string Height(object who, string field, bool z = false) { //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) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) object? obj = AccessTools.Field(who.GetType(), field)?.GetValue(who); Transform val = (Transform)((obj is Transform) ? obj : null); if ((Object)(object)val == (Object)null) { return field + "=fehlt"; } if (!z) { return "y=" + val.position.y.ToString("F0"); } return "z=" + val.position.z.ToString("F0"); } private static string Num(object who, string field) { object obj = AccessTools.Field(who.GetType(), field)?.GetValue(who); if (obj != null) { return ((float)obj).ToString("F1"); } return "?"; } } internal sealed class FinalAscentGloomBand : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const float Drown = 10f; private static readonly int FogHeightKey = Shader.PropertyToID("FogHeight"); private static FinalAscentGloomBand _instance; private Fog _fog; private bool _looked; private float _was; private float _fogWas; private bool _held; private readonly FinalAscentLedger _book = new FinalAscentLedger(); private DayNightProfile _wasProfile; private GameObject _sheet; private bool _built; private static readonly string[] Wanted = new string[4] { "Gloom", "Swamp Profile", "Void Profile", "Caldera Profile" }; private float _lastTold; private static readonly Color Deep = new Color(0.105f, 0.075f, 0.145f, 1f); internal static bool Drowning { get; private set; } internal static bool Lit { get; private set; } internal static void Install() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("FA_GloomBand"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } } private void LateUpdate() { float lift = FinalAscentSleepFogSky.Lift; Character localCharacter = Character.localCharacter; if (!FinalAscentSleepFogSky.Wanted) { Daylight(); } if (lift <= 0f || (Object)(object)localCharacter == (Object)null) { Release(); return; } Find(); float num = Highest() + 10f; if (!_held) { _held = true; _was = Shader.GetGlobalFloat(FogHeightKey); _fogWas = (((Object)(object)_fog != (Object)null) ? _fog.fogHeight : 0f); Drowning = (Object)(object)_fog != (Object)null; Beacon(); Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel: Pegel uebernommen. Global stand bei " + $"{_was:0.#}, echter Gloom " + (((Object)(object)_fog != (Object)null) ? ("'" + ((Object)_fog).name + "' bei " + _fogWas.ToString("0.#")) : "keiner") + ".")); } Shader.SetGlobalFloat(FogHeightKey, num); localCharacter.data.isInFog = true; Gloomy(lift); Sheet(localCharacter, num); if ((Object)(object)_fog != (Object)null) { _fog.fogHeight = num; } } private void Release() { if (_held) { _held = false; Drowning = false; Shader.SetGlobalFloat(FogHeightKey, _was); if ((Object)(object)_fog != (Object)null) { _fog.fogHeight = _fogWas; } if ((Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.data != (Object)null) { Character.localCharacter.data.isInFog = false; } if ((Object)(object)_sheet != (Object)null) { _sheet.SetActive(false); } Daylight(); _book.Return("[FinalAscent] Schlafnebel"); Plugin.Log.LogInfo((object)string.Format("{0} Schlafnebel: Pegel auf {1:0.#} zurueckgelegt.", "[FinalAscent]", _was)); } } private static float Highest() { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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) float num = float.MinValue; List allPlayerCharacters = PlayerHandler.GetAllPlayerCharacters(); 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 && val.Center.y > num) { num = val.Center.y; } } if (num > float.MinValue) { return num; } if (!((Object)(object)Character.localCharacter != (Object)null)) { return 0f; } return Character.localCharacter.Center.y; } private void Daylight() { if (Lit) { Lit = false; DayNightManager instance = DayNightManager.instance; if ((Object)(object)instance != (Object)null && (Object)(object)_wasProfile != (Object)null) { instance.BlendProfiles(_wasProfile); Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel: Beleuchtung zurueck auf '" + ((Object)_wasProfile).name + "' - waehrend der Nebel noch ausblendet.")); } _wasProfile = null; } } private void Beacon() { DayNightManager instance = DayNightManager.instance; if ((Object)(object)instance == (Object)null) { return; } DayNightProfile[] array = Resources.FindObjectsOfTypeAll(); string text = ""; DayNightProfile[] array2 = array; foreach (DayNightProfile val in array2) { if ((Object)(object)val != (Object)null) { text = text + ((text.Length > 0) ? ", " : "") + ((Object)val).name; } } DayNightProfile val2 = null; string[] wanted = Wanted; foreach (string value in wanted) { array2 = array; foreach (DayNightProfile val3 in array2) { if ((Object)(object)val3 != (Object)null && ((Object)val3).name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { val2 = val3; break; } } if ((Object)(object)val2 != (Object)null) { break; } } if ((Object)(object)val2 == (Object)null || (Object)(object)val2 == (Object)(object)instance.currentProfile) { Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel: kein passendes Lichtprofil (gefunden: " + ((text.Length > 0) ? text : "keine") + ") - es bleibt beim Anstrich.")); return; } _wasProfile = instance.currentProfile; Lit = true; instance.BlendProfiles(val2); Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel: Beleuchtung auf '" + ((Object)val2).name + "' geblendet (vorher '" + (((Object)(object)_wasProfile != (Object)null) ? ((Object)_wasProfile).name : "keins") + "'). Vorhanden: " + text + ".")); } private void Gloomy(float thick) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) float num = _book.Was("HeightFogAmount", Shader.GetGlobalFloat(Shader.PropertyToID("HeightFogAmount"))); float num2 = _book.Was("GloomSoften", Shader.GetGlobalFloat(Shader.PropertyToID("GloomSoften"))); Color val = _book.Was("DeepFogColor", Shader.GetGlobalColor(Shader.PropertyToID("DeepFogColor"))); _book.SetFloat("HeightFogAmount", Mathf.Lerp(num, 1f, thick)); _book.SetFloat("GloomSoften", Mathf.Lerp(num2, 1f, thick)); _book.SetColor("DeepFogColor", Color.Lerp(val, Deep, thick)); } private void Sheet(Character me, float level) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) if (!_built) { _built = true; _sheet = Raise(); } if (!((Object)(object)_sheet == (Object)null)) { _sheet.SetActive(true); _sheet.transform.position = new Vector3(me.Center.x, level, me.Center.z); if (Time.unscaledTime - _lastTold >= 2f) { _lastTold = Time.unscaledTime; Renderer componentInChildren = _sheet.GetComponentInChildren(true); Plugin.Log.LogInfo((object)(string.Format("{0} Schlafnebel: Flaeche auf {1:0.#} (ich ", "[FinalAscent]", level) + string.Format("{0:0.#}, hoechster {1:0.#}, Blende {2:0.00}), sichtbar {3}, ", me.Center.y, Highest(), FinalAscentSleepFogSky.Lift, ((Object)(object)componentInChildren != (Object)null && componentInChildren.isVisible) ? "ja" : "nein") + "Werkstoff " + (((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.sharedMaterial != (Object)null) ? ((Object)componentInChildren.sharedMaterial).name : "keiner") + ", " + string.Format("Bodennebel {0:0.##}.", Shader.GetGlobalFloat(Shader.PropertyToID("HeightFogAmount"))))); } } } private GameObject Raise() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) MeshFilter val = null; MeshRenderer val2 = null; if ((Object)(object)_fog != (Object)null) { val = ((Component)_fog).GetComponentInChildren(true); val2 = ((Component)_fog).GetComponentInChildren(true); } GameObject val3 = new GameObject("FA_GloomSheet"); Object.DontDestroyOnLoad((Object)(object)val3); MeshFilter val4 = val3.AddComponent(); MeshRenderer val5 = val3.AddComponent(); ((Renderer)val5).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val5).receiveShadows = false; if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null && (Object)(object)val.sharedMesh != (Object)null) { val4.sharedMesh = val.sharedMesh; ((Renderer)val5).sharedMaterials = ((Renderer)val2).sharedMaterials; val3.transform.localScale = ((Component)val).transform.lossyScale; Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel: Nebelflaeche vom echten Gloom uebernommen " + $"('{((Renderer)val2).sharedMaterial}').")); return val3; } Material val6 = Fabric(); if ((Object)(object)val6 == (Object)null) { Object.Destroy((Object)(object)val3); Plugin.Log.LogWarning((object)"[FinalAscent] Schlafnebel: kein Nebelwerkstoff ('GD/FogSurface') zu finden - es bleibt beim Anstrich."); return null; } Object.Destroy((Object)(object)val4); Object.Destroy((Object)(object)val5); GameObject obj = GameObject.CreatePrimitive((PrimitiveType)5); Mesh sharedMesh = obj.GetComponent().sharedMesh; Object.Destroy((Object)(object)obj); for (int i = 0; i < 2; i++) { GameObject val7 = new GameObject((i == 0) ? "Down" : "Up"); val7.transform.SetParent(val3.transform, false); val7.AddComponent().sharedMesh = sharedMesh; MeshRenderer obj2 = val7.AddComponent(); ((Renderer)obj2).sharedMaterial = val6; ((Renderer)obj2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj2).receiveShadows = false; val7.transform.localRotation = Quaternion.Euler((i == 0) ? 90f : (-90f), 0f, 0f); val7.transform.localScale = new Vector3(4000f, 4000f, 1f); } Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel: eigene Nebelflaeche gebaut (beidseitig), Werkstoff '" + ((Object)val6).name + "'.")); return val3; } private static Material Fabric() { return FinalAscentLarder.ByShader("FogSurface"); } private void Find() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (_looked) { return; } _looked = true; Fog[] array = Resources.FindObjectsOfTypeAll(); foreach (Fog val in array) { if ((Object)(object)val != (Object)null) { Scene scene = ((Component)val).gameObject.scene; if (((Scene)(ref scene)).IsValid()) { _fog = val; break; } } } } } internal static class FinalAscentGuests { private const string Tag = "[FinalAscent]"; private static readonly List _disabled = new List(); private static readonly List _paused = new List(); internal static void Sleep() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) _disabled.Clear(); _paused.Clear(); int num = 0; ValueIterator enumerator = PhotonNetwork.PhotonViewCollection.GetEnumerator(); try { while (enumerator.MoveNext()) { PhotonView current = enumerator.Current; if ((Object)(object)current == (Object)null || !current.isRuntimeInstantiated || (Object)(object)((Component)current).gameObject == (Object)null) { continue; } num++; Collider[] componentsInChildren = ((Component)current).GetComponentsInChildren(true); foreach (Collider val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.enabled) { val.enabled = false; _disabled.Add(val); } } Rigidbody[] componentsInChildren2 = ((Component)current).GetComponentsInChildren(true); foreach (Rigidbody val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null && !val2.isKinematic) { val2.isKinematic = true; _paused.Add(val2); } } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } Plugin.Log.LogInfo((object)(string.Format("{0} {1} uebers Netz erzeugte Dinge aus dem Strahlengang genommen: ", "[FinalAscent]", num) + $"{_disabled.Count} Kollider aus, {_paused.Count} Koerper angehalten. Die " + "Objekte selbst bleiben an - nur ihre Koerperlichkeit pausiert.")); } internal static void Wake() { int num = 0; foreach (Collider item in _disabled) { if ((Object)(object)item != (Object)null) { item.enabled = true; num++; } } foreach (Rigidbody item2 in _paused) { if ((Object)(object)item2 != (Object)null) { item2.isKinematic = false; } } _disabled.Clear(); _paused.Clear(); if (num > 0) { Plugin.Log.LogInfo((object)string.Format("{0} {1} Kollider der Netz-Dinge sind wieder an.", "[FinalAscent]", num)); } } } internal static class FinalAscentHeightmap { private const string Tag = "[FinalAscent]"; private static readonly Dictionary Built = new Dictionary(); private static readonly HashSet Delivered = new HashSet(); internal static int Count => Built.Count; internal static void Reset() { Built.Clear(); Delivered.Clear(); } internal static void Note(HeightmapMesh who, float[,] heights) { if ((Object)(object)who != (Object)null && heights != null) { Built[who] = heights; } } internal static bool TryGet(HeightmapMesh who, out float[,] heights) { return Built.TryGetValue(who, out heights); } internal static bool IsDelivered(HeightmapMesh who) { if ((Object)(object)who != (Object)null) { return Delivered.Contains(who); } return false; } internal static void MarkDelivered(HeightmapMesh who) { if ((Object)(object)who != (Object)null) { Delivered.Add(who); } } } [HarmonyPatch(typeof(HeightmapMesh), "Generate")] internal static class FinalAscentHeightmapLog { private static void Postfix(HeightmapMesh __instance, float[,] heights) { if (FinalAscent.Active) { FinalAscentHeightmap.Note(__instance, heights); } } } [HarmonyPatch(typeof(SwampMeshGen), "Generate")] internal static class FinalAscentSwampGenGuard { private static bool Prefix(SwampMeshGen __instance) { if (!FinalAscent.Active) { return true; } HeightmapMesh component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null && FinalAscentHeightmap.IsDelivered(component)) { Plugin.Detail("[FinalAscent] '" + ((Object)__instance).name + "' wollte den Sumpfboden neu erstrahlen - die gelieferte Hoehenkarte des Hosts gilt."); return false; } return true; } } internal static class FinalAscentHeights { [HarmonyPatch(typeof(CharacterStats), "Record")] internal static class RecordPatch { private static IEnumerable Transpiler(IEnumerable instructions) { return Swap(instructions, 1200f, CapGetter, "CharacterStats.Record"); } } [HarmonyPatch(typeof(CharacterStats), "FixLastEntry")] internal static class FixLastEntryPatch { private static IEnumerable Transpiler(IEnumerable instructions) { return Swap(instructions, 1200f, SummitGetter, "CharacterStats.FixLastEntry"); } } [HarmonyPatch(typeof(CharacterStats), "UnitsToMeters")] internal static class UnitsToMetersPatch { private static IEnumerable Transpiler(IEnumerable instructions) { return Swap(instructions, 1200f, CapGetter, "CharacterStats.UnitsToMeters"); } } [HarmonyPatch] internal static class TimelineRoutinePatch { private static MethodBase TargetMethod() { return AccessTools.EnumeratorMoveNext((MethodBase)AccessTools.Method(typeof(EndScreen), "TimelineRoutine", (Type[])null, (Type[])null)); } private static IEnumerable Transpiler(IEnumerable instructions) { return Swap(instructions, 1300f, CapGetter, "EndScreen.TimelineRoutine"); } } [HarmonyPatch(typeof(EndScreen), "DrawPip")] internal static class DrawPipPatch { private static IEnumerable Transpiler(IEnumerable instructions) { return Swap(instructions, 1200f, SummitGetter, "EndScreen.DrawPip"); } } private const string Tag = "[FinalAscent]"; internal const float VanillaSummit = 1200f; private static float _summit = 1200f; private static readonly MethodInfo SummitGetter = AccessTools.PropertyGetter(typeof(FinalAscentHeights), "Summit"); private static readonly MethodInfo CapGetter = AccessTools.PropertyGetter(typeof(FinalAscentHeights), "Cap"); internal static float Summit { get { if (!FinalAscent.Active) { return 1200f; } return _summit; } } internal static float Cap => Summit + 300f; internal static void Reset() { _summit = 1200f; } internal static void Measure() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) MountainProgressHandler instance = Singleton.Instance; if (instance?.progressPoints == null) { Plugin.Log.LogWarning((object)("[FinalAscent] Kein MountainProgressHandler - der Endscreen rechnet weiter mit " + $"{1200f:F0} Einheiten.")); return; } float num = 0f; string text = "?"; ProgressPoint[] progressPoints = instance.progressPoints; foreach (ProgressPoint val in progressPoints) { if (!((Object)(object)val?.transform == (Object)null) && val.transform.position.y > num) { num = val.transform.position.y; text = val.title; } } float num2 = HighestFoothold(); if (num2 > num) { Plugin.Log.LogInfo((object)(string.Format("{0} Hoechster Fortschrittspunkt '{1}' bei {2:F0}, hoechster ", "[FinalAscent]", text, num) + $"begehbarer Punkt bei {num2:F0} - es gilt der begehbare.")); num = num2; text = "Gipfelfels"; } if (num <= 1200f) { Plugin.Log.LogInfo((object)(string.Format("{0} Gipfel bei {1:F0} Einheiten - nicht hoeher als die Tageskarte, ", "[FinalAscent]", num) + "der Endscreen bleibt wie er ist.")); return; } _summit = num; Plugin.Log.LogInfo((object)(string.Format("{0} Gipfel '{1}' bei {2:F0} Einheiten ({3:F0} m). ", "[FinalAscent]", text, num, num * CharacterStats.unitsToMeters) + $"Vanilla rechnet mit {1200f:F0} ({1200f * CharacterStats.unitsToMeters:F0} m) - " + "Aufzeichnung, Kurve und Hoehenmeter laufen ab jetzt bis oben.")); } private static IEnumerable Swap(IEnumerable instructions, float wanted, MethodInfo replacement, string where) { List list = new List(instructions); int num = 0; for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldc_R4 && list[i].operand is float num2 && num2 == wanted) { list[i].opcode = OpCodes.Call; list[i].operand = replacement; num++; } } if (num != 1) { Plugin.Log.LogWarning((object)(string.Format("{0} {1}: {2:F0} kommt {3}x vor, erwartet war 1x. ", "[FinalAscent]", where, wanted, num) + "Der Endscreen kann dadurch falsch rechnen.")); } return list; } private static float HighestFoothold() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) PeakHandler instance = Singleton.Instance; if ((Object)(object)instance == (Object)null) { return 0f; } float num = 0f; Collider[] componentsInChildren = ((Component)instance).GetComponentsInChildren(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !val.isTrigger) { Bounds bounds = val.bounds; float y = ((Bounds)(ref bounds)).max.y; if (y > num) { num = y; } } } return num; } } internal sealed class FinalAscentHotSun : MonoBehaviour { internal float rate = 5f; internal float amount = 0.025f; private const float Reach = 1000f; internal Bounds bounds = new Bounds(Vector3.zero, new Vector3(1000000f, 1000000f, 1000000f)); private float counter; private bool _told; private static FinalAscentHotSun _instance; 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_HotSun"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } if (!((Object)(object)_instance == (Object)null)) { _instance.counter = 0f; _instance._told = false; if (on) { _instance.Adopt(); } } } private void Adopt() { //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) HotSun[] array = Resources.FindObjectsOfTypeAll(); foreach (HotSun val in array) { if (!((Object)(object)val == (Object)null)) { Scene scene = ((Component)val).gameObject.scene; if (((Scene)(ref scene)).IsValid()) { Plugin.Log.LogInfo((object)("[FinalAscent] Zum Vergleich: echtes HotSun '" + ((Object)val).name + "' auf dieser " + $"Karte steht auf {val.amount:0.###} je {val.rate:0.##}s " + $"(= {((val.rate > 0f) ? (val.amount / val.rate) : 0f):0.###} je Sekunde). " + $"Wir bleiben bei {amount:0.###} je {rate:0.##}s.")); return; } } } Plugin.Log.LogInfo((object)($"[FinalAscent] Brennende Sonne: {amount:0.###} je {rate:0.##}s " + $"(= {amount / rate:0.###} je Sekunde). Kein echtes HotSun auf dieser " + "Karte zum Vergleich.")); } private void Update() { //IL_0047: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (!FinalAscentHotSunSky.Wanted && FinalAscentHotSunSky.Lift <= 0f) { return; } Character localCharacter = Character.localCharacter; DayNightManager instance = DayNightManager.instance; if ((Object)(object)localCharacter == (Object)null || (Object)(object)instance == (Object)null || (Object)(object)instance.sun == (Object)null || !((Bounds)(ref bounds)).Contains(localCharacter.Center) || instance.sun.intensity < 5f) { return; } Transform transform = ((Component)instance.sun).transform; RaycastHit val = HelperFunctions.LineCheck(localCharacter.Center + transform.forward * -1000f, localCharacter.Center, (LayerType)0, 0f, (QueryTriggerInteraction)1); if ((Object)(object)((RaycastHit)(ref val)).transform != (Object)null && (Object)(object)((RaycastHit)(ref val)).transform.root != (Object)(object)((Component)localCharacter).transform.root) { return; } counter += Time.deltaTime; if (counter > rate) { counter = 0f; localCharacter.refs.afflictions.AddSunHeat(amount); if (!_told) { _told = true; Plugin.Log.LogInfo((object)("[FinalAscent] Brennende Sonne brennt: Tageszeit " + $"{instance.timeOfDay:0.0}, Sonnenstaerke {instance.sun.intensity:0.0}.")); } } } } [HarmonyPatch(typeof(DayNightManager), "UpdateCycle")] internal static class FinalAscentHotSunSky { private const float Blazing = 6f; private const float FadeSeconds = 6f; internal static bool Wanted; internal static float Lift; private static void Prefix(DayNightManager __instance) { bool flag = Wanted && __instance.isDay >= 0.5f; Lift = Mathf.MoveTowards(Lift, flag ? 1f : 0f, Time.deltaTime / 6f); } private static void Postfix(DayNightManager __instance) { if (!(Lift <= 0f) && !((Object)(object)__instance.sun == (Object)null)) { float num = Mathf.Lerp(__instance.sun.intensity, 6f, Lift); if (num > __instance.sun.intensity) { __instance.sun.intensity = num; } } } } internal static class FinalAscentWeatherOwn { internal static void Register() { FinalAscentWeather.Register(new WeatherEffect { Key = "storm", Label = FinalAscentText.Get("weather.storm"), Set = delegate(bool on) { FinalAscentWindStorm.Run(FinalAscentWindStorm.Kind.Wind, on); Plugin.Log.LogInfo((object)("[FinalAscent] Sturm " + (on ? "zieht auf." : "zieht ab."))); } }); FinalAscentWeather.Register(new WeatherEffect { Key = "rain", Label = FinalAscentText.Get("weather.rain"), Set = delegate(bool on) { FinalAscentWindStorm.Run(FinalAscentWindStorm.Kind.Rain, on); Plugin.Log.LogInfo((object)("[FinalAscent] Regen " + (on ? "setzt ein." : "hoert auf."))); } }); FinalAscentWeather.Register(new WeatherEffect { Key = "snow", Label = FinalAscentText.Get("weather.snow"), Set = delegate(bool on) { FinalAscentWindStorm.Run(FinalAscentWindStorm.Kind.Snow, on); Plugin.Log.LogInfo((object)("[FinalAscent] Schneesturm " + (on ? "zieht auf." : "zieht ab."))); } }); FinalAscentWeather.Register(new WeatherEffect { Key = "sand", Label = FinalAscentText.Get("weather.sand"), Set = delegate(bool on) { FinalAscentWindStorm.Run(FinalAscentWindStorm.Kind.Sand, on); Plugin.Log.LogInfo((object)("[FinalAscent] Sandsturm " + (on ? "faellt ein." : "legt sich."))); } }); FinalAscentWeather.Register(new WeatherEffect { Key = "sleepfog", Label = FinalAscentText.Get("weather.sleepfog"), Set = delegate(bool on) { FinalAscentSleepFogSky.Wanted = on; FinalAscentSleepFog.Run(on); Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel " + (on ? "zieht auf." : "loest sich auf."))); } }); FinalAscentWeather.Register(new WeatherEffect { Key = "spores", Label = FinalAscentText.Get("weather.spores"), Set = delegate(bool on) { FinalAscentSporeSky.Wanted = on; FinalAscentSporeCloud.Run(on); Plugin.Log.LogInfo((object)("[FinalAscent] Sporenwolke " + (on ? "steigt auf." : "kondensiert und zieht ab."))); } }); FinalAscentWeather.Register(new WeatherEffect { Key = "dark", Label = FinalAscentText.Get("weather.dark"), Set = delegate(bool on) { FinalAscentDarkSky.Wanted = on; FinalAscentDarkness.Run(on); Plugin.Log.LogInfo((object)("[FinalAscent] Finsternis " + (on ? "faellt - das Licht geht." : "weicht - das Licht kommt zurueck."))); } }); FinalAscentWeather.Register(new WeatherEffect { Key = "quake", Label = FinalAscentText.Get("weather.quake"), Set = delegate(bool on) { FinalAscentQuake.Run(on); Plugin.Log.LogInfo((object)("[FinalAscent] Erdbeben " + (on ? "beginnt - der Berg wird unruhig." : "beruhigt sich."))); } }); FinalAscentWeather.Register(new WeatherEffect { Key = "blood", Label = FinalAscentText.Get("weather.blood"), Set = delegate(bool on) { FinalAscentBloodMoonSky.Wanted = on; FinalAscentBloodMoon.Run(on); Plugin.Log.LogInfo((object)("[FinalAscent] Blutmond " + (on ? "geht auf - es kommt Gesellschaft." : "geht unter."))); } }); FinalAscentWeather.Register(new WeatherEffect { Key = "moon", Label = FinalAscentText.Get("weather.moon"), Set = delegate(bool on) { FinalAscentBlueMoonSky.Wanted = on; FinalAscentBlueMoon.Run(on); Plugin.Log.LogInfo((object)("[FinalAscent] Blauer Mond " + (on ? "geht auf - die Nacht zieht herauf." : "geht unter."))); } }); FinalAscentWeather.Register(new WeatherEffect { Key = "petrify", Label = FinalAscentText.Get("weather.petrify"), Set = delegate(bool on) { FinalAscentPetrifySunSky.Wanted = on; FinalAscentPetrifySun.Run(on); Plugin.Log.LogInfo((object)("[FinalAscent] Versteinernde Sonne " + (on ? "an - der Himmel faerbt sich." : "aus - blendet ab."))); } }); FinalAscentWeather.Register(new WeatherEffect { Key = "sun", Label = FinalAscentText.Get("weather.sun"), Set = delegate(bool on) { FinalAscentHotSunSky.Wanted = on; FinalAscentHotSun.Run(on); Plugin.Log.LogInfo((object)("[FinalAscent] Brennende Sonne " + (on ? "an - blendet auf Mittag auf." : "aus - blendet ab."))); } }); } } [HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")] internal static class FinalAscentHurtWatch { private const string Tag = "[FinalAscent]"; private const float Notable = 0.05f; private const int Budget = 12; private static int _told; private static float _last; internal static void Reset() { _told = 0; _last = 0f; } private static void Prefix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (Plugin.Diagnosing && FinalAscent.Active && (int)statusType == 0 && !(amount < 0.05f) && _told < 12 && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.character == (Object)null) && __instance.character.IsLocal && !(Time.realtimeSinceStartup - _last < 0.25f)) { _last = Time.realtimeSinceStartup; _told++; Vector3 center = __instance.character.Center; Plugin.Log.LogWarning((object)(string.Format("{0} SCHADEN {1:F3} bei ({2:F1} / {3:F1} / {4:F1}) - ", "[FinalAscent]", amount, center.x, center.y, center.z) + "ausgeloest von: " + Trail())); if (_told == 12) { Plugin.Log.LogWarning((object)(string.Format("{0} Schadensmelder: das waren {1} Meldungen, ab jetzt ", "[FinalAscent]", 12) + "still. Die Frage sollte damit beantwortet sein.")); } } } private static string Trail() { try { StackTrace stackTrace = new StackTrace(2, fNeedFileInfo: false); string text = ""; int num = 0; for (int i = 0; i < stackTrace.FrameCount; i++) { if (num >= 5) { break; } MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod(); Type type = methodBase?.DeclaringType; if (!(type == null)) { string text2 = type.Namespace ?? ""; if (!text2.StartsWith("HarmonyLib", StringComparison.Ordinal) && !text2.StartsWith("MonoMod", StringComparison.Ordinal) && !(type == typeof(CharacterAfflictions)) && !type.Name.StartsWith("FinalAscentHurtWatch", StringComparison.Ordinal)) { text = text + ((text.Length > 0) ? " <- " : "") + type.Name + "." + methodBase.Name; num++; } } } return (text.Length > 0) ? text : "unlesbar"; } catch { return "unlesbar"; } } } [HarmonyPatch(typeof(CollisionModifier), "Collide")] internal static class FinalAscentBumpWatch { private const string Tag = "[FinalAscent]"; private const int Budget = 20; private static int _told; private static bool _looked; private static readonly Dictionary Seen = new Dictionary(); private static void Prefix(CollisionModifier __instance, Character character) { //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) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) if (Plugin.Diagnosing && !((Object)(object)__instance == (Object)null) && !((Object)(object)character == (Object)null) && character.IsLocal && _told < 20) { int instanceID = ((Object)__instance).GetInstanceID(); Seen.TryGetValue(instanceID, out var value); Seen[instanceID] = value + 1; _told++; Vector3 position = ((Component)__instance).transform.position; Plugin.Log.LogWarning((object)(string.Format("{0} STOSS #{1} auf Bauteil {2} bei ", "[FinalAscent]", value + 1, instanceID) + $"({position.x:F1} / {position.y:F1} / {position.z:F1}), Schaden {__instance.damage:F2} " + $"({__instance.statusType}), Sperre {__instance.cooldown:F1}s, " + $"Bauteil aktiv={((Behaviour)__instance).isActiveAndEnabled}, " + $"Objekt an={((Component)__instance).gameObject.activeInHierarchy} - " + "'" + PathOf(((Component)__instance).transform) + "'")); if (!_looked) { _looked = true; LookAround(((Component)__instance).transform.position); } if (_told == 20) { Plugin.Log.LogWarning((object)(string.Format("{0} STOSS-MELDER: {1} VERSCHIEDENE Bauteile bei ", "[FinalAscent]", Seen.Count) + $"{20} Treffern. Mehr als eines = mehrere Bruecken " + "uebereinander; genau eines = seine Sperre greift nicht.")); } } } private static void LookAround(Vector3 here) { //IL_0057: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) try { CollisionModifier[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); int num = 0; Plugin.Log.LogWarning((object)(string.Format("{0} UMFELD des Stosses ({1} Bauteile ", "[FinalAscent]", array.Length) + "in der ganzen Szene), im Umkreis von 8 Metern:")); CollisionModifier[] array2 = array; foreach (CollisionModifier val in array2) { if ((Object)(object)val == (Object)null) { continue; } Vector3 val2 = ((Component)val).transform.position - here; if (!(((Vector3)(ref val2)).sqrMagnitude > 64f)) { num++; Vector3 position = ((Component)val).transform.position; Plugin.Log.LogWarning((object)(string.Format("{0} {1} bei ({2:F2} / {3:F2} / ", "[FinalAscent]", ((Object)val).GetInstanceID(), position.x, position.y) + $"{position.z:F2}) an={((Component)val).gameObject.activeInHierarchy} " + "'" + PathOf(((Component)val).transform) + "'")); if (num >= 24) { Plugin.Log.LogWarning((object)"[FinalAscent] ... und weitere."); break; } } } Plugin.Log.LogWarning((object)string.Format("{0} UMFELD: {1} Bauteile in Reichweite.", "[FinalAscent]", num)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Umfeld-Blick misslang: " + ex.Message)); } } private static string PathOf(Transform leaf) { if ((Object)(object)leaf == (Object)null) { return "?"; } string text = ((Object)leaf).name; Transform parent = leaf.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } } [HarmonyPatch(typeof(Item), "Awake")] internal static class FinalAscentItemBirth { private const string Tag = "[FinalAscent]"; private const int Limit = 120; private static int _said; internal static void Reset() { _said = 0; } private static void Postfix(Item __instance) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00a6: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance == (Object)null) && !FinalAscentBuilder.Building && FinalAscent.Active && _said < 120) { _said++; Vector3 position = ((Component)__instance).transform.position; PhotonView component = ((Component)__instance).GetComponent(); Plugin.Log.LogWarning((object)("[FinalAscent] GEGENSTAND GEBOREN (" + (PhotonNetwork.IsMasterClient ? "HOST" : "GAST") + "): '" + ((Object)((Component)__instance).gameObject).name + "' bei " + $"({position.x:F0} / {position.y:F0} / {position.z:F0}), Rufnummer " + $"{(((Object)(object)component != (Object)null) ? component.ViewID : 0)}, " + (((Object)(object)component != (Object)null && component.IsMine) ? "meiner" : "fremd") + "." + ((_said == 120) ? $" (Ab hier still - {120} Zeilen erreicht.)" : string.Empty))); } } } internal static class FinalAscentItemResync { private sealed class Ear : IOnEventCallback { public void OnEvent(EventData photonEvent) { if (photonEvent.Code == 183 && PhotonNetwork.IsMasterClient) { Resend(photonEvent.Sender); } } } private const string Tag = "[FinalAscent]"; internal const byte EventPlease = 183; private static readonly MethodInfo ForceSync = AccessTools.Method(typeof(Item), "ForceSyncForFrames", (Type[])null, (Type[])null); private static readonly FieldInfo SyncerField = AccessTools.Field(typeof(Item), "physicsSyncer"); private static bool _listening; internal static void Listen() { if (!_listening) { PhotonNetwork.AddCallbackTarget((object)new Ear()); _listening = true; } } private static void Resend(int forWhom) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) if (ForceSync == null) { Plugin.Log.LogWarning((object)"[FinalAscent] ForceSyncForFrames nicht gefunden - Ruhelagen bleiben aus."); return; } int num = 0; int num2 = 0; int num3 = 0; Dictionary dictionary = new Dictionary(); Item[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (Item val in array) { if ((Object)(object)val == (Object)null || (int)val.itemState != 0) { continue; } object obj = null; try { obj = SyncerField?.GetValue(val); } catch { } if (SyncerField != null && obj == null) { num2++; dictionary.TryGetValue(((Object)val).name, out var value); dictionary[((Object)val).name] = value + 1; try { PhotonView component = ((Component)val).GetComponent(); Rigidbody component2 = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null && component.ViewID != 0) { component.RPC("SetKinematicRPC", (RpcTarget)0, new object[3] { component2.isKinematic, component2.position, component2.rotation }); num3++; } } catch (Exception ex) { Plugin.Detail("[FinalAscent] '" + ((Object)val).name + "' laesst sich nicht setzen: " + ex.Message); } } else { try { ForceSync.Invoke(val, new object[1] { 30 }); num++; } catch (Exception ex2) { Plugin.Detail("[FinalAscent] '" + ((Object)val).name + "' sendet nicht: " + ex2.Message); } } } if (num2 > 0) { List> list = new List>(dictionary); list.Sort((KeyValuePair a, KeyValuePair b) => b.Value.CompareTo(a.Value)); StringBuilder stringBuilder = new StringBuilder(); for (int num4 = 0; num4 < list.Count && num4 < 10; num4++) { if (stringBuilder.Length > 0) { stringBuilder.Append(", "); } stringBuilder.Append(list[num4].Value).Append("x ").Append(list[num4].Key); } Plugin.Log.LogInfo((object)(string.Format("{0} {1} Gegenstaende haben keinen Positions-Synchronisierer ", "[FinalAscent]", num2) + $"({stringBuilder}) - fuer {num3} davon ist die Lage per SetKinematicRPC " + "hinausgegangen, Vanillas zweitem Weg.")); } Plugin.Log.LogInfo((object)(string.Format("{0} Ruhelage von {1} frei liegenden Gegenstaenden geht an ", "[FinalAscent]", num) + $"Platz {forWhom} - Vanillas Nachreichung, diesmal zum richtigen Zeitpunkt.")); } internal static void AskWhenReady() { if (!((Object)(object)Plugin.Instance == (Object)null) && FinalAscent.Active) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(Ask()); } } private static IEnumerator Ask() { float[] when = new float[3] { 1f, 6f, 20f }; for (int i = 0; i < when.Length; i++) { yield return (object)new WaitForSecondsRealtime(when[i]); if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient || PhotonNetwork.OfflineMode) { break; } PhotonNetwork.RaiseEvent((byte)183, (object)null, new RaiseEventOptions { Receivers = (ReceiverGroup)2 }, SendOptions.SendReliable); Plugin.Detail(string.Format("{0} Um die Ruhelage der Gegenstaende gebeten ({1}. Mal).", "[FinalAscent]", i + 1)); } } } internal static class FinalAscentItems { private const string Tag = "[FinalAscent]"; private const float WaitSeconds = 20f; private static readonly FieldInfo SyncerField = AccessTools.Field(typeof(Item), "physicsSyncer"); private static readonly FieldInfo ShouldSyncField = AccessTools.Field(AccessTools.TypeByName("ItemPhysicsSyncer"), "shouldSync"); internal static void ReportLater() { if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(Delayed()); } } private static IEnumerator Delayed() { yield return (object)new WaitForSecondsRealtime(20f); Report($"{20f:F0}s nach dem Aufbau"); } internal static void Report(string when) { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) Item[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); List list = new List(); long num = 0L; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; Item[] array2 = array; foreach (Item val in array2) { if (!((Object)(object)val == (Object)null)) { PhotonView component = ((Component)val).GetComponent(); int num8 = (((Object)(object)component != (Object)null) ? component.ViewID : 0); if (num8 == 0) { num4++; } else if (component.CreatorActorNr == 0) { num3++; } else { num2++; } bool flag = (Object)(object)((Component)val).GetComponentInParent() != (Object)null; bool flag2 = !flag && (Object)(object)((Component)val).transform.parent != (Object)null; if (flag) { num5++; } else if (flag2) { num6++; } else { num7++; Vector3 position = ((Component)val).transform.position; long num9 = 1469598103934665603L; num9 = (num9 ^ val.itemID) * 1099511628211L; num9 = (num9 ^ Mathf.RoundToInt(position.x)) * 1099511628211L; num9 = (num9 ^ Mathf.RoundToInt(position.y)) * 1099511628211L; num9 = (num9 ^ Mathf.RoundToInt(position.z)) * 1099511628211L; num += num9; } Vector3 position2 = ((Component)val).transform.position; list.Add($"{((Object)val).name} (#{val.itemID}) bei " + $"({position2.x:F0} / {position2.y:F0} / {position2.z:F0}): " + string.Format("Nummer {0}, {1}, ", num8, flag ? "getragen" : (flag2 ? "verankert" : "liegt frei")) + Presence(val) + ", " + Sync(val)); } } Plugin.Log.LogInfo((object)(string.Format("{0} Gegenstaende ({1}): {2} liegen frei, {3} in der ", "[FinalAscent]", when, num7, num6) + $"Landschaft verankert, {num5} werden getragen. Pruefsumme der frei " + $"liegenden {num & 0xFFFFFF:X6} - sie muss bei allen Mitspielern gleich sein.")); Plugin.Log.LogInfo((object)(string.Format("{0} Herkunft: {1} aus dem Raum (vom Host gesetzt und ", "[FinalAscent]", num3) + $"gepuffert), {num2} von einem Spieler erzeugt, {num4} ohne Rufnummer.")); Dump(list, when); if (num7 == 0) { Plugin.Log.LogWarning((object)"[FinalAscent] KEIN einziger Gegenstand liegt frei in der Welt. Beim Host duerfte das anders sein - dann sind die gepufferten Ereignisse nicht angekommen oder wurden nach der Zustellung wieder abgeraeumt."); } bool flag3 = when.StartsWith("auf Zuruf", StringComparison.Ordinal); list.Sort(StringComparer.Ordinal); foreach (string item in list) { if (flag3) { Plugin.Log.LogInfo((object)("[FinalAscent] " + item)); } else { Plugin.Detail("[FinalAscent] " + item); } } if (list.Count > 0 && !flag3 && !Plugin.Diagnosing) { Plugin.Log.LogInfo((object)(string.Format("{0} ({1} Einzelzeilen - auf Zuruf (Bild ab) oder mit ", "[FinalAscent]", list.Count) + "eingeschalteter Diagnose stehen sie hier namentlich.)")); } } private static string Sync(Item item) { object obj = null; try { obj = SyncerField?.GetValue(item); } catch { } string text = "?"; if (obj != null && ShouldSyncField != null) { try { text = (((bool)ShouldSyncField.GetValue(obj)) ? "ja" : "NEIN"); } catch { text = "?"; } } Rigidbody component = ((Component)item).GetComponent(); string text2 = (((Object)(object)component == (Object)null) ? "kein Koerper" : (component.isKinematic ? "starr" : (component.IsSleeping() ? "schlaeft" : "wach"))); return "Sync " + ((obj != null) ? "vorhanden" : "FEHLT") + ", sendet " + text + ", " + text2; } private static void Dump(List lines, string when) { try { lines.Sort(StringComparer.Ordinal); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# Gegenstaende " + when + " - Zeile fuer Zeile vergleichbar."); stringBuilder.AppendLine($"# ANZAHL: {lines.Count}"); foreach (string line in lines) { stringBuilder.AppendLine(line); } if (Plugin.Diagnosing) { File.WriteAllText(FinalAscentStore.Note("TrueFinalAscent.Gegenstaende.txt"), stringBuilder.ToString()); Plugin.Log.LogInfo((object)string.Format("{0} Liste abgelegt (TrueFinalAscent.Gegenstaende.txt, {1} Zeilen).", "[FinalAscent]", lines.Count)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Gegenstands-Liste nicht abgelegt: " + ex.Message)); } } private static string Presence(Item item) { GameObject gameObject = ((Component)item).gameObject; if (gameObject.activeInHierarchy) { return "da"; } if (!gameObject.activeSelf) { return "NICHT DA (selbst aus)"; } Transform parent = gameObject.transform.parent; while ((Object)(object)parent != (Object)null) { if (!((Component)parent).gameObject.activeSelf) { return "NICHT DA (Ast '" + ((Object)parent).name + "' aus)"; } parent = parent.parent; } return "NICHT DA"; } } internal static class FinalAscentJitterRadar { private const string Tag = "[FinalAscent]"; private static bool _running; internal static void Begin() { if (!_running && !((Object)(object)Plugin.Instance == (Object)null)) { _running = true; ((MonoBehaviour)Plugin.Instance).StartCoroutine(Watch()); } } private static IEnumerator Watch() { while ((Object)(object)Character.localCharacter == (Object)null) { yield return (object)new WaitForSeconds(1f); } Dictionary last = new Dictionary(); Dictionary restless = new Dictionary(); HashSet reported = new HashSet(); float until = Time.realtimeSinceStartup + 240f; while (Time.realtimeSinceStartup < until) { yield return (object)new WaitForSeconds(5f); Item[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (Item val in array) { if ((Object)(object)val == (Object)null) { continue; } Rigidbody component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null) { continue; } int instanceID = ((Object)val).GetInstanceID(); if (component.IsSleeping() || component.isKinematic) { restless[instanceID] = 0; continue; } Vector3 position = ((Component)val).transform.position; if (last.TryGetValue(instanceID, out var value)) { Vector3 val2 = position - value; if (((Vector3)(ref val2)).magnitude < 0.3f) { restless.TryGetValue(instanceID, out var value2); restless[instanceID] = value2 + 1; if (restless[instanceID] >= 3 && reported.Add(instanceID)) { string text = "fremd"; try { PhotonView component2 = ((Component)val).GetComponent(); text = (((Object)(object)component2 == (Object)null) ? "ohne Rufnummer" : (component2.IsMine ? "MEINER" : "fremd")); } catch { } Plugin.Log.LogWarning((object)("[FinalAscent] ZITTERER (" + text + "): '" + ((Object)val).name + "' bei " + FinalAscentBuilder.Fmt(position) + " liegt auf: " + Below(val))); } } else { restless[instanceID] = 0; } } last[instanceID] = position; } } Plugin.Log.LogInfo((object)string.Format("{0} Zitter-Radar fertig: {1} Dauer-Wache in vier Minuten.", "[FinalAscent]", reported.Count)); _running = false; } private static string Below(Item item) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) RaycastHit[] array = Physics.RaycastAll(((Component)item).transform.position + Vector3.up * 0.3f, Vector3.down, 5f); Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); RaycastHit[] array2 = array; for (int num = 0; num < array2.Length; num++) { RaycastHit val = array2[num]; if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(((Component)item).transform)) { return PathOf(((Component)((RaycastHit)(ref val)).collider).transform) + $" (Abstand {((RaycastHit)(ref val)).distance - 0.3f:F2})"; } } return "nichts in fuenf Metern"; } private static string PathOf(Transform leaf) { StringBuilder stringBuilder = new StringBuilder(((Object)leaf).name); Transform parent = leaf.parent; while ((Object)(object)parent != (Object)null) { stringBuilder.Insert(0, '/').Insert(0, ((Object)parent).name); parent = parent.parent; } return stringBuilder.ToString(); } } internal static class FinalAscentJoinCatchup { private const string Tag = "[FinalAscent]"; internal static void Run() { if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient) { Plugin.Detail("[FinalAscent] Beitritts-Nachzug ist Sache des Hosts - hier passiert nichts."); return; } int num = Ring("Zitadellen-Einrichtung"); int num2 = Ring("Seil am Anker"); Plugin.Log.LogInfo((object)(string.Format("{0} Beitritts-Nachzug: {1} Zitadellen-Einrichtung(en) und ", "[FinalAscent]", num) + $"{num2} Seil(e) nachgeholt. Diese Bauteile handeln in OnJoinedRoom, " + "und den Ruf verpasst, wer beim Beitritt abgeschaltet ist - bei uns also fast der ganze Berg.")); } private static int Ring(string what) where T : MonoBehaviourPunCallbacks { int num = 0; T[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (T val in array) { if (!((Object)(object)val == (Object)null)) { try { ((MonoBehaviourPunCallbacks)val).OnJoinedRoom(); num++; Plugin.Detail("[FinalAscent] " + what + ": '" + ((Object)(object)val).name + "' nachgeholt."); } catch (Exception ex) { Plugin.Detail("[FinalAscent] " + what + ": '" + ((Object)(object)val).name + "' liess sich nicht nachholen: " + ex.Message); } } } return num; } } [HarmonyPatch(typeof(MapHandler), "SetSegmentOnSpawn")] internal static class FinalAscentSpawnSegmentPatch { private static string _done; private static int _repeats; private unsafe static void Postfix(Segment segment, int lastRevivedSegment) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) if (!FinalAscent.Active) { return; } if (FinalAscentBuilder.Building) { Plugin.Log.LogInfo((object)"[FinalAscent] Einstiegs-Abgleich kommt mitten im Aufbau - er wird uebersprungen, der Bau stellt den Stand am Ende selbst her."); return; } int stage = FinalAscentRoom.Stage; string text = stage + "/" + ((object)(*(Segment*)(&segment))/*cast due to .constrained prefix*/).ToString() + "/" + lastRevivedSegment; if (text == _done) { _repeats++; if (_repeats == 1) { Plugin.Detail("[FinalAscent] Einstieg wiederholt sich unveraendert - der Berg steht schon so. Weitere Wiederholungen bleiben still."); } return; } Plugin.Log.LogInfo((object)($"[FinalAscent] Einstieg in Segment {segment} (letzte Wiederbelebung " + $"{lastRevivedSegment}); im Raum steht Etappenstand {stage}.")); if (FinalAscentSegments.RestoreToStage(stage)) { _done = text; _repeats = 0; } } internal static void Forget() { _done = null; _repeats = 0; } } [HarmonyPatch(typeof(MapHandler), "InitializeMap")] internal static class FinalAscentPublishStartStagePatch { private static void Postfix() { if (FinalAscent.Active && PhotonNetwork.IsMasterClient && !FinalAscentInitializeMapPatch.Suppressed && !((Object)(object)Singleton.Instance == (Object)null)) { FinalAscentRoom.PublishStage(FinalAscentSegments.KeyOf(FinalAscentSegments.CurrentStage)); } } } [HarmonyPatch(typeof(MapHandler), "JumpToSegmentLogic")] internal static class FinalAscentJumpGate { private const string Tag = "[FinalAscent]"; private static bool _stashed; private static Segment _segment; private static HashSet _players; private static bool _sendToEveryone; private static bool _updateFog; private static string _lastApplied; private static int _sameRepeats; private unsafe static bool Prefix(Segment newSegment, HashSet playersToTeleport, bool sendToEveryone, bool updateFog) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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) if (!FinalAscent.Active) { return true; } if (!FinalAscentBuilder.Building) { string text = ((object)(*(Segment*)(&newSegment))/*cast due to .constrained prefix*/).ToString() + "/" + FinalAscentRoom.Stage; if (text == _lastApplied) { if (_sameRepeats++ == 0) { Plugin.Log.LogInfo((object)(string.Format("{0} Segmentsprung nach {1} wiederholt sich ohne ", "[FinalAscent]", newSegment) + "Aenderung - die Welt steht schon so. Weitere Wiederholungen bleiben still.")); } return false; } _lastApplied = text; _sameRepeats = 0; return true; } _stashed = true; _segment = newSegment; _players = playersToTeleport; _sendToEveryone = sendToEveryone; _updateFog = updateFog; Plugin.Log.LogInfo((object)(string.Format("{0} Segmentsprung nach {1} kommt mitten im Aufbau - er wird ", "[FinalAscent]", newSegment) + "beiseitegelegt und nach dem Aufbau nachgeholt. Mitten im Bauen schaltete er sonst das halbe Gelaende ab, und die Spawner schoessen ins Leere.")); return false; } internal static void ReplayIfStashed() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (!_stashed) { return; } _stashed = false; _lastApplied = null; _sameRepeats = 0; Plugin.Log.LogInfo((object)string.Format("{0} Beiseitegelegter Segmentsprung nach {1} wird nachgeholt.", "[FinalAscent]", _segment)); try { AccessTools.Method(typeof(MapHandler), "JumpToSegmentLogic", (Type[])null, (Type[])null)?.Invoke(null, new object[4] { _segment, _players, _sendToEveryone, _updateFog }); } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("{0} Nachgeholter Segmentsprung wirft: {1}", "[FinalAscent]", arg)); } } } internal static class FinalAscentKeepAlive { private const string Tag = "[FinalAscent]"; private const double IntervalMs = 200.0; private static Stopwatch _total; private static Stopwatch _since; private static int _beats; private static double _longestGap; private static string _longestAt = "-"; private static string _where = "-"; private static int _photonAcksAtStart = -1; private static int _budgetWas = -1; private static int _timeoutWas = -1; private const int BudgetDuringBuildMs = 300000; private const int TimeoutDuringBuildMs = 30000; private static ConnectionHandler Handler() { ConnectionHandler[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); if (array == null || array.Length == 0) { return null; } ConnectionHandler val = null; ConnectionHandler[] array2 = array; foreach (ConnectionHandler val2 in array2) { if (!((Object)(object)val2 == (Object)null)) { if (val2 is PhotonHandler) { val = val2; break; } if ((Object)(object)val == (Object)null || ((object)val2).GetType() != typeof(ConnectionHandler)) { val = val2; } } } if (array.Length > 1) { array2 = array; foreach (ConnectionHandler val3 in array2) { if ((Object)(object)val3 != (Object)null) { Plugin.Log.LogInfo((object)("[FinalAscent] ConnectionHandler '" + ((object)val3).GetType().Name + "' auf " + $"'{((Object)((Component)val3).gameObject).name}': laeuft={val3.FallbackThreadRunning}, " + $"Bestaetigungen {val3.CountSendAcksOnly}.")); } } } return val; } internal static void Begin() { //IL_01bc: Unknown result type (might be due to invalid IL or missing references) ConnectionHandler val = Handler(); if ((Object)(object)val != (Object)null) { _budgetWas = val.KeepAliveInBackground; val.KeepAliveInBackground = 300000; Plugin.Log.LogInfo((object)("[FinalAscent] Photons Not-Faden bekommt fuer den Aufbau " + $"{300}s Budget statt {_budgetWas / 1000}s.")); } try { LoadBalancingClient networkingClient = PhotonNetwork.NetworkingClient; if (((networkingClient != null) ? networkingClient.LoadBalancingPeer : null) != null) { _timeoutWas = ((PhotonPeer)PhotonNetwork.NetworkingClient.LoadBalancingPeer).DisconnectTimeout; ((PhotonPeer)PhotonNetwork.NetworkingClient.LoadBalancingPeer).DisconnectTimeout = 30000; Plugin.Log.LogInfo((object)("[FinalAscent] Trennschwelle des Klienten fuer den Aufbau auf " + $"{30}s angehoben (vorher {_timeoutWas / 1000}s).")); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Trennschwelle nicht anhebbar: " + ex.Message)); } if ((Object)(object)val != (Object)null) { _photonAcksAtStart = val.CountSendAcksOnly; Plugin.Log.LogInfo((object)("[FinalAscent] Photons eigener Faden (" + ((object)val).GetType().Name + " auf " + $"'{((Object)((Component)val).gameObject).name}'): laeuft={val.FallbackThreadRunning}, " + $"Budget {val.KeepAliveInBackground / 1000}s, " + $"trennt danach={val.DisconnectAfterKeepAlive}, " + $"bisher {_photonAcksAtStart} eigene Bestaetigungen, " + $"verbunden={PhotonNetwork.IsConnected}, " + $"Zustand={PhotonNetwork.NetworkClientState}.")); } else { _photonAcksAtStart = -1; Plugin.Log.LogInfo((object)"[FinalAscent] Kein ConnectionHandler - vermutlich Alleingang."); } _total = Stopwatch.StartNew(); _since = Stopwatch.StartNew(); _beats = 0; _longestGap = 0.0; _longestAt = "-"; _where = "Anfang"; } internal static void Doing(string what) { _where = what; } internal static void Flush() { if (_since != null) { _since.Restart(); } if (!PhotonNetwork.IsConnected || PhotonNetwork.NetworkingClient == null) { return; } try { ((PhotonPeer)PhotonNetwork.NetworkingClient.LoadBalancingPeer).SendAcksOnly(); _beats++; } catch { } } internal static void Tick() { if (_since == null) { return; } double totalMilliseconds = _since.Elapsed.TotalMilliseconds; if (totalMilliseconds > _longestGap) { _longestGap = totalMilliseconds; _longestAt = _where; } if (totalMilliseconds < 200.0) { return; } _since.Restart(); if (!PhotonNetwork.IsConnected || PhotonNetwork.NetworkingClient == null) { return; } try { ((PhotonPeer)PhotonNetwork.NetworkingClient.LoadBalancingPeer).SendAcksOnly(); _beats++; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Herzschlag an Photon fehlgeschlagen: " + ex.Message)); _since = null; } } internal static void End() { if (_total == null) { return; } Tick(); Plugin.Log.LogInfo((object)(string.Format("{0} Verbindung waehrend des Umbaus gehalten: {1} Herzschlaege in ", "[FinalAscent]", _beats) + $"{_total.Elapsed.TotalSeconds:F1}s, groesste Luecke {_longestGap / 1000.0:F1}s " + "(bei '" + _longestAt + "').")); ConnectionHandler val = Handler(); if ((Object)(object)val != (Object)null && _photonAcksAtStart >= 0) { int num = val.CountSendAcksOnly - _photonAcksAtStart; Plugin.Log.LogInfo((object)(string.Format("{0} Photons eigener Faden hat waehrenddessen {1} Mal selbst ", "[FinalAscent]", num) + $"bestaetigt (Budget {val.KeepAliveInBackground / 1000}s, " + $"Aufbau {_total.Elapsed.TotalSeconds:F0}s).")); if (num == 0) { Plugin.Log.LogWarning((object)"[FinalAscent] Photons Faden hat NICHTS geschickt - dann haengt alles an unserem Herzschlag, und jede Luecke ist echtes Schweigen."); } else if (_total.Elapsed.TotalSeconds > (double)val.KeepAliveInBackground / 1000.0) { Plugin.Log.LogWarning((object)("[FinalAscent] Der Aufbau dauert laenger als Photons Budget von " + $"{val.KeepAliveInBackground / 1000}s. Ab dort schweigt sein " + "Faden, und nur unser Herzschlag haelt die Verbindung.")); } } if (_longestGap > 5000.0) { Plugin.Log.LogWarning((object)("[FinalAscent] Diese Luecke ist zu gross - falls Photons Faden zu dem Zeitpunkt schon aufgegeben hatte, war es echtes Schweigen. Nachzubessern ist an '" + _longestAt + "'.")); } if ((Object)(object)val != (Object)null && _budgetWas > 0) { val.KeepAliveInBackground = _budgetWas; _budgetWas = -1; } try { if (_timeoutWas > 0) { LoadBalancingClient networkingClient = PhotonNetwork.NetworkingClient; if (((networkingClient != null) ? networkingClient.LoadBalancingPeer : null) != null) { ((PhotonPeer)PhotonNetwork.NetworkingClient.LoadBalancingPeer).DisconnectTimeout = _timeoutWas; } } } catch { } _timeoutWas = -1; _total = null; _since = null; _photonAcksAtStart = -1; } } internal static class FinalAscentLarder { private const string Tag = "[FinalAscent]"; private static readonly Dictionary Fabrics = new Dictionary(); private static readonly Dictionary Sounds = new Dictionary(); private static Material[] _allFabrics; private static AudioClip[] _allSounds; private static AudioMixerGroup _bus; private static readonly Dictionary Pictures = new Dictionary(); private static Texture[] _allPictures; internal static Material ByShader(string part) { if (Fabrics.TryGetValue(part, out var value) && (Object)(object)value != (Object)null) { return value; } foreach (Material item in Stock()) { if (!((Object)(object)item == (Object)null) && !((Object)(object)item.shader == (Object)null) && ((Object)item.shader).name.IndexOf(part, StringComparison.OrdinalIgnoreCase) >= 0) { Fabrics[part] = item; Plugin.Log.LogInfo((object)("[FinalAscent] Vorrat: Werkstoff '" + ((Object)item).name + "' fuer '" + part + "' eingelagert.")); return item; } } Plugin.Log.LogWarning((object)("[FinalAscent] Vorrat: kein Werkstoff mit '" + part + "' gefunden.")); return null; } internal static Material ByName(string name) { if (Fabrics.TryGetValue(name, out var value) && (Object)(object)value != (Object)null) { return value; } foreach (Material item in Stock()) { if ((Object)(object)item != (Object)null && string.Equals(((Object)item).name, name, StringComparison.OrdinalIgnoreCase)) { Fabrics[name] = item; return item; } } return null; } internal static AudioMixerGroup Bus() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_bus != (Object)null) { return _bus; } if ((Object)(object)SFX_Player.instance != (Object)null && (Object)(object)SFX_Player.instance.defaultMixerGroup != (Object)null) { _bus = SFX_Player.instance.defaultMixerGroup; Plugin.Log.LogInfo((object)("[FinalAscent] Vorrat: Tonschiene '" + ((Object)_bus).name + "' uebernommen.")); return _bus; } AudioSource[] array = Resources.FindObjectsOfTypeAll(); foreach (AudioSource val in array) { if ((Object)(object)val != (Object)null) { Scene scene = ((Component)val).gameObject.scene; if (((Scene)(ref scene)).IsValid() && (Object)(object)val.outputAudioMixerGroup != (Object)null) { _bus = val.outputAudioMixerGroup; Plugin.Log.LogInfo((object)("[FinalAscent] Vorrat: Tonschiene '" + ((Object)_bus).name + "' von '" + ((Object)((Component)val).gameObject).name + "' geliehen.")); return _bus; } } } return null; } internal static Texture Picture(string name) { if (Pictures.TryGetValue(name, out var value) && (Object)(object)value != (Object)null) { return value; } foreach (Texture item in Seen()) { if ((Object)(object)item != (Object)null && string.Equals(((Object)item).name, name, StringComparison.OrdinalIgnoreCase)) { Pictures[name] = item; Plugin.Log.LogInfo((object)(string.Format("{0} Vorrat: Bild '{1}' ({2}x{3}) ", "[FinalAscent]", ((Object)item).name, item.width, item.height) + "eingelagert.")); return item; } } Plugin.Log.LogWarning((object)("[FinalAscent] Vorrat: kein Bild namens '" + name + "' gefunden.")); return null; } private static IEnumerable Seen() { Texture[] array = Resources.FindObjectsOfTypeAll(); for (int i = 0; i < array.Length; i++) { yield return array[i]; } if (_allPictures == null) { float realtimeSinceStartup = Time.realtimeSinceStartup; _allPictures = Resources.LoadAll(""); Plugin.Log.LogInfo((object)(string.Format("{0} Vorrat: {1} Bilder aus dem Bestand ", "[FinalAscent]", _allPictures.Length) + $"geholt ({(Time.realtimeSinceStartup - realtimeSinceStartup) * 1000f:0} ms).")); } array = _allPictures; for (int i = 0; i < array.Length; i++) { yield return array[i]; } } internal static AudioClip Sound(string part) { if (Sounds.TryGetValue(part, out var value) && (Object)(object)value != (Object)null) { return value; } foreach (AudioClip item in Heard()) { if ((Object)(object)item != (Object)null && ((Object)item).name.IndexOf(part, StringComparison.OrdinalIgnoreCase) >= 0) { Sounds[part] = item; Plugin.Log.LogInfo((object)("[FinalAscent] Vorrat: Klang '" + ((Object)item).name + "' fuer '" + part + "' eingelagert.")); return item; } } return null; } private static IEnumerable Stock() { Material[] array = Resources.FindObjectsOfTypeAll(); for (int i = 0; i < array.Length; i++) { yield return array[i]; } if (_allFabrics == null) { float realtimeSinceStartup = Time.realtimeSinceStartup; _allFabrics = Resources.LoadAll(""); Plugin.Log.LogInfo((object)(string.Format("{0} Vorrat: {1} Werkstoffe aus dem Bestand ", "[FinalAscent]", _allFabrics.Length) + $"geholt ({(Time.realtimeSinceStartup - realtimeSinceStartup) * 1000f:0} ms).")); } array = _allFabrics; for (int i = 0; i < array.Length; i++) { yield return array[i]; } } private static IEnumerable Heard() { AudioClip[] array = Resources.FindObjectsOfTypeAll(); for (int i = 0; i < array.Length; i++) { yield return array[i]; } if (_allSounds == null) { float realtimeSinceStartup = Time.realtimeSinceStartup; _allSounds = Resources.LoadAll(""); Plugin.Log.LogInfo((object)(string.Format("{0} Vorrat: {1} Klaenge aus dem Bestand ", "[FinalAscent]", _allSounds.Length) + $"geholt ({(Time.realtimeSinceStartup - realtimeSinceStartup) * 1000f:0} ms).")); } array = _allSounds; for (int i = 0; i < array.Length; i++) { yield return array[i]; } } } internal static class FinalAscentLava { private const string Tag = "[FinalAscent]"; private static readonly FieldInfo BoundsField = AccessTools.Field(typeof(Lava), "bounds"); internal static void Remeasure() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) if (BoundsField == null) { Plugin.Log.LogWarning((object)"[FinalAscent] Lava: kein Feld 'bounds' gefunden - die Hitzezone bleibt, wo sie beim Erwachen vermessen wurde."); return; } int num = 0; int num2 = 0; int num3 = 0; float num4 = 0f; Lava[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Lava val in array) { if ((Object)(object)val == (Object)null) { continue; } try { MeshRenderer componentInChildren = ((Component)val).GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { num3++; continue; } Bounds bounds = ((Renderer)componentInChildren).bounds; Bounds val2 = (Bounds)BoundsField.GetValue(val); float num5 = Vector3.Distance(((Bounds)(ref val2)).center, ((Bounds)(ref bounds)).center); if (!(num5 < 0.01f)) { goto IL_00c6; } Vector3 size = ((Bounds)(ref val2)).size; if (!(((Vector3)(ref size)).sqrMagnitude > 0.0001f)) { goto IL_00c6; } num2++; goto end_IL_004f; IL_00c6: BoundsField.SetValue(val, bounds); num++; if (num5 > num4) { num4 = num5; } Plugin.Detail("[FinalAscent] Lava '" + ((Object)val).name + "'" + (val.isKiln ? " (Kiln)" : "") + ": Hitzezone lag " + FinalAscentBuilder.Fmt(((Bounds)(ref val2)).center) + ", liegt jetzt " + FinalAscentBuilder.Fmt(((Bounds)(ref bounds)).center) + " (Groesse " + FinalAscentBuilder.Fmt(((Bounds)(ref bounds)).size) + ")."); end_IL_004f:; } catch (Exception ex) { Plugin.Detail("[FinalAscent] Lava '" + ((Object)val).name + "' liess sich nicht neu vermessen: " + ex.Message); } } Plugin.Log.LogInfo((object)(string.Format("{0} Lava neu vermessen: {1} Hitzezonen nachgezogen ", "[FinalAscent]", num) + $"(groesster Versatz {num4:F0} Einheiten), {num2} standen schon richtig" + ((num3 > 0) ? $", {num3} ohne Mesh uebersprungen" : "") + ". Ohne das gibt weder Caldera- noch Kiln-Lava Hitze - ihre Kiste bliebe dort liegen, wo die Lava vor dem Versatz stand.")); } } internal sealed class FinalAscentLeaveWatch : IInRoomCallbacks { private static FinalAscentLeaveWatch _hooked; internal static void Begin() { if (_hooked == null) { _hooked = new FinalAscentLeaveWatch(); PhotonNetwork.AddCallbackTarget((object)_hooked); } } public void OnPlayerLeftRoom(Player otherPlayer) { if (FinalAscent.Active && PhotonNetwork.IsMasterClient) { Plugin.Log.LogInfo((object)("[FinalAscent] " + otherPlayer.NickName + " hat den Raum verlassen - das Melderegister wird sofort festgeschrieben.")); FinalAscentRoster.Flush(); } } public void OnPlayerEnteredRoom(Player newPlayer) { } public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { if (propertiesThatChanged != null && ((Dictionary)(object)propertiesThatChanged).ContainsKey((object)"FAtomb")) { FinalAscentTombGate.ApplyFromRoom(); } } public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { } public void OnMasterClientSwitched(Player newMasterClient) { } } internal sealed class FinalAscentLedger { private readonly Dictionary _floats = new Dictionary(); private readonly Dictionary _colours = new Dictionary(); private readonly Dictionary _names = new Dictionary(); internal bool Anything { get { if (_floats.Count <= 0) { return _colours.Count > 0; } return true; } } internal void SetFloat(string name, float value) { int num = Shader.PropertyToID(name); if (!_floats.ContainsKey(num)) { _floats[num] = Shader.GetGlobalFloat(num); _names[num] = name; } Shader.SetGlobalFloat(num, value); } internal void SetColor(string name, Color value) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) int num = Shader.PropertyToID(name); if (!_colours.ContainsKey(num)) { _colours[num] = Shader.GetGlobalColor(num); _names[num] = name; } Shader.SetGlobalColor(num, value); } internal Color Was(string name, Color ifNew) { //IL_0017: 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) if (!_colours.TryGetValue(Shader.PropertyToID(name), out var value)) { return ifNew; } return value; } internal float Was(string name, float ifNew) { if (!_floats.TryGetValue(Shader.PropertyToID(name), out var value)) { return ifNew; } return value; } internal void Return(string tag) { //IL_00ce: Unknown result type (might be due to invalid IL or missing references) if (!Anything) { return; } string text = ""; foreach (KeyValuePair @float in _floats) { Shader.SetGlobalFloat(@float.Key, @float.Value); text = text + ((text.Length > 0) ? ", " : "") + _names[@float.Key] + "=" + @float.Value.ToString("0.###"); } foreach (KeyValuePair colour in _colours) { Shader.SetGlobalColor(colour.Key, colour.Value); text = text + ((text.Length > 0) ? ", " : "") + _names[colour.Key]; } _floats.Clear(); _colours.Clear(); _names.Clear(); Plugin.Log.LogInfo((object)(tag + " zurueckgelegt: " + text + ".")); } } internal static class FinalAscentLeveling { private const string Tag = "[FinalAscent]"; internal static void Install(Harmony harmony) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown try { Type type = AccessTools.TypeByName("Leveling.LevelingAPI"); MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "AddExperience", (Type[])null, (Type[])null) : null); if (methodInfo == null) { Plugin.Detail("[FinalAscent] Leveling-Mod nicht gefunden - nichts einzuhaengen."); return; } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(FinalAscentLeveling), "LetItThrough", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)"[FinalAscent] Leveling-Mod gefunden: Erfahrung wird im Finalen Aufstieg gutgeschrieben. Sein Riegel haengt am Szenennamen, und unsere Szene heisst 'WilIsland' - deshalb dieser Griff."); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Leveling-Vertraeglichkeit misslang: " + ex.Message)); } } private static void LetItThrough(ref bool allowAwardInAirport) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (!allowAwardInAirport && FinalAscent.Active) { Scene activeScene = SceneManager.GetActiveScene(); if (!(((Scene)(ref activeScene)).name != "WilIsland")) { allowAwardInAirport = true; } } } } internal static class FinalAscentLightAudit { private const string Tag = "[FinalAscent]"; private const int Samples = 20000; private const float Every = 4f; private const float MustReach = 0.05f; private const float TooOpenShare = 0.9f; private static float _told; private static string Fence() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!SystemInfo.supportsGraphicsFence) { return "nein (schon laut SystemInfo)"; } try { GraphicsFence val = Graphics.CreateGraphicsFence((GraphicsFenceType)0, (SynchronisationStageFlags)4); return ((GraphicsFence)(ref val)).passed ? "ja" : "ja (noch offen)"; } catch (Exception ex) { return "NEIN, obwohl SystemInfo ja sagt (" + ex.GetType().Name + ")"; } } internal static bool Survey(string who) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) try { LightVolume val = LightVolume.Instance(); if ((Object)(object)val == (Object)null || (Object)(object)((CompressableLightMap)(ref val.lightMapData)).Uncompressed == (Object)null) { Plugin.Log.LogWarning((object)("[FinalAscent] Lichtprobe (" + who + "): kein Gitter da.")); return false; } Texture3D uncompressed = ((CompressableLightMap)(ref val.lightMapData)).Uncompressed; int width = ((Texture)uncompressed).width; int height = ((Texture)uncompressed).height; int depth = uncompressed.depth; int[] array = new int[10]; float num = 0f; float num2 = 0f; Random random = new Random(12345); for (int i = 0; i < 20000; i++) { int num3 = random.Next(width); int num4 = random.Next(height); int num5 = random.Next(depth); float a = uncompressed.GetPixel(num3, num4, num5).a; num += a; if (a > num2) { num2 = a; } int num6 = Mathf.Clamp((int)(a * 10f), 0, 9); array[num6]++; } StringBuilder stringBuilder = new StringBuilder(); for (int j = 0; j < array.Length; j++) { if (stringBuilder.Length > 0) { stringBuilder.Append(' '); } stringBuilder.Append($"{(float)j / 10f:0.0}-{(float)(j + 1) / 10f:0.0}:").Append($"{(float)array[j] * 100f / 20000f:0}%"); } Plugin.Log.LogInfo((object)(string.Format("{0} Lichtprobe ({1}): {2}x{3}x{4}, Raster ", "[FinalAscent]", who, width, height, depth) + $"{val.raySpacing:0.#}, Mittel {num / 20000f:0.000}, " + $"Hoechstwert {num2:0.000}. Verteilung: {stringBuilder}")); Plugin.Log.LogInfo((object)("[FinalAscent] Lichtprobe (" + who + "): zum Vergleich liest Vanilla unter offenem Himmel rund 0,40 und unter einem Vorsprung rund 0,21; die Sturmschwelle liegt bei 0,25 mit 0,12 Rand.")); if (num2 < 0.05f) { Plugin.Log.LogWarning((object)("[FinalAscent] Lichtprobe (" + who + "): DAS GITTER IST LEER (Hoechstwert " + $"{num2:0.000}). Ohne Licht gibt es weder Umgebungshelligkeit " + "noch Wetterdeckung - jede Stelle gaelte als gedeckt, und im Schnee kaeme nirgends Kaelte an. GPU: " + SystemInfo.graphicsDeviceName + " " + $"({SystemInfo.graphicsDeviceType}, " + SystemInfo.graphicsDeviceVersion + "), VRAM " + $"{SystemInfo.graphicsMemorySize} MB gegen " + $"{(long)width * (long)height * depth * 4 / 1048576} MB Lichtkarte. " + "Fence anlegbar: " + Fence() + ", Compute: " + $"{SystemInfo.supportsComputeShaders}, asynchrones Auslesen: " + $"{SystemInfo.supportsAsyncGPUReadback}.")); return false; } float num7 = (float)(array[9] + array[8]) / 20000f; if (num7 > 0.9f) { Plugin.Log.LogWarning((object)("[FinalAscent] Lichtprobe (" + who + "): KEINE VERSCHATTUNG gefunden " + $"({num7 * 100f:0}% der Zellen fast offen). Dann ist jede " + "Hoehle taghell - meist zu wenige lesbare Meshes.")); return false; } return true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Lichtprobe (" + who + ") gescheitert: " + ex.Message)); return true; } } internal static void AtPlayer(WindChillZone zone, Character who, float factor) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)zone == (Object)null || (Object)(object)who == (Object)null || Time.realtimeSinceStartup - _told < 4f) { return; } _told = Time.realtimeSinceStartup; try { LightVolume val = LightVolume.Instance(); float num = (((Object)(object)val != (Object)null && (Object)(object)((CompressableLightMap)(ref val.lightMapData)).Uncompressed != (Object)null) ? val.SamplePositionAlpha(who.Center, false) : (-1f)); float lightVolumeSampleThreshold_lower = zone.lightVolumeSampleThreshold_lower; float lightVolumeSampleThreshold_margin = zone.lightVolumeSampleThreshold_margin; string arg = ((num < lightVolumeSampleThreshold_lower) ? "GEDECKT (nichts kommt an)" : ((num > lightVolumeSampleThreshold_lower + lightVolumeSampleThreshold_margin) ? "voll im Wetter" : "anteilig")); Plugin.Log.LogInfo((object)(string.Format("{0} Wetterprobe '{1}': Lichtwert {2:0.000} gegen ", "[FinalAscent]", ((Object)zone).name, num) + $"Schwelle {lightVolumeSampleThreshold_lower:0.000} (+{lightVolumeSampleThreshold_margin:0.000}) -> {arg}, " + $"Faktor {factor:0.00}, Hoehe {who.Center.y:0}, " + $"Zustand {zone.statusType} zu {zone.statusApplicationPerSecond:0.000}/s.")); } catch (Exception) { } } } [HarmonyPatch(typeof(WindChillZone), "ApplyStatus")] internal static class FinalAscentWeatherProbePatch { private static void Postfix(WindChillZone __instance, Character character) { if ((Object)(object)character != (Object)null && character.IsLocal) { FinalAscentLightAudit.AtPlayer(__instance, character, __instance.windPlayerFactor); } } } internal static class FinalAscentLightBake { private const string Tag = "[FinalAscent]"; private const float CpuSpacing = 8f; private static FinalAscentLightBakeRunner _runner; internal static float Spacing => 8f; internal static bool Busy { get; private set; } internal static float Fraction { get; set; } internal static bool Ran { get; private set; } internal static void Reset() { Ran = false; if ((Object)(object)_runner != (Object)null) { Plugin.Log.LogWarning((object)"[FinalAscent] Lichtbake (eigen): alter Lauf abgebrochen."); Object.Destroy((Object)(object)((Component)_runner).gameObject); _runner = null; } Busy = false; Fraction = 0f; } internal static void Run(LightVolume volume, Action done) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown if ((Object)(object)volume == (Object)null) { done?.Invoke(obj: false); return; } if (Busy) { Plugin.Log.LogWarning((object)"[FinalAscent] Lichtbake (eigen): laeuft bereits."); return; } Busy = true; Fraction = 0f; GameObject val = new GameObject("FA_LightBake"); Object.DontDestroyOnLoad((Object)val); _runner = val.AddComponent(); _runner.Begin(volume, delegate(bool ok) { Busy = false; Fraction = (ok ? 1f : 0f); Ran = ok; _runner = null; done?.Invoke(ok); }); } } internal sealed class FinalAscentLightBakeRunner : MonoBehaviour { private sealed class Flight { internal NativeArray Shots; internal NativeArray Hits; internal NativeArray Open; internal JobHandle Done; internal int Start; internal int Count; internal bool Busy; } private struct Lamp { internal Vector3 Where; internal Vector3 Facing; internal Color Tint; internal float Reach; internal float Fade; internal float Cone; internal float ConeFade; } private struct FillJob : IJobParallelFor { [NativeDisableParallelForRestriction] internal NativeArray Shots; [ReadOnly] internal NativeArray Fan; internal int Rays; internal int Start; internal int Count; internal int W; internal int H; internal Vector3 Offset; internal float Spacing; internal QueryParameters Ask; internal float Far; public void Execute(int n) { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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) int num = n * Rays; if (n >= Count) { for (int i = 0; i < Rays; i++) { Shots[num + i] = new RaycastCommand(Vector3.zero, Vector3.up, Ask, 0f); } return; } int num2 = Start + n; int num3 = num2 % W; int num4 = num2 / W % H; int num5 = num2 / (W * H); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Offset.x + ((float)num3 + 0.5f) * Spacing, Offset.y + ((float)num4 + 0.5f) * Spacing, Offset.z + ((float)num5 + 0.5f) * Spacing); for (int j = 0; j < Rays; j++) { Shots[num + j] = new RaycastCommand(val, Fan[j], Ask, Far); } } } private struct EvalJob : IJobParallelFor { [NativeDisableParallelForRestriction] [ReadOnly] internal NativeArray Hits; internal NativeArray Open; internal int Rays; public void Execute(int n) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) int num = n * Rays; int num2 = 0; for (int i = 0; i < Rays; i++) { RaycastHit val = Hits[num + i]; if (((RaycastHit)(ref val)).colliderInstanceID == 0) { num2++; } } Open[n] = (float)num2 / (float)Rays; } } private const string Tag = "[FinalAscent]"; private const int Chunk = 262144; private const int Grain = 256; private const float Far = 400f; private const float LampBias = 0.5f; private const float Budget = 0.04f; private const int SubSpan = 256; private const int MainVoxels = 256; private const float MainBudget = 0.025f; private const float SkyShare = 0.94f; private const float LampShare = 0.97f; private LightVolume _volume; private Action _done; private int _w; private int _h; private int _d; private int _count; private Vector3 _offset; private Vector3 _middle; private int _rays; private int _solid; private Color _sky; private Color[] _grid; private Color[] _scratch; private List _lamps; private NativeArray _fan; private QueryParameters _ask; private Flight[] _flights; private NativeArray _mainShots; private NativeArray _mainHits; private int _cursor; private long _doneVoxels; private long _skipped; private int _lampCursor; private float _wasSpacing; private float _began; private float _told; private bool _finished; internal void Begin(LightVolume volume, Action done) { _volume = volume; _done = done; ((MonoBehaviour)this).StartCoroutine(Work()); } private IEnumerator Work() { if (!Setup()) { Finish(ok: false); yield break; } yield return null; while (_cursor < _count || Airborne()) { if (!Pump()) { Finish(ok: false); yield break; } yield return null; } while (_lampCursor < _lamps.Count) { if (!LampSlice()) { Finish(ok: false); yield break; } yield return null; } FinalAscentLightBake.Fraction = 0.97f; for (int pass = 0; pass < _volume.blurRadius; pass++) { for (int axis = 0; axis < 3; axis++) { if (!BlurAxis(axis)) { Finish(ok: false); yield break; } yield return null; } } FinalAscentLightBake.Fraction = 0.99f; yield return null; Finish(Deliver()); } private bool Airborne() { for (int i = 0; i < _flights.Length; i++) { if (_flights[i].Busy) { return true; } } return false; } private bool Setup() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) try { _began = Time.realtimeSinceStartup; _wasSpacing = _volume.raySpacing; _volume.raySpacing = FinalAscentLightBake.Spacing; _solid = LayerMask.op_Implicit(_volume.occluderMask); _rays = Mathf.Clamp(_volume.rayCount, 8, 64); _sky = _volume.skyColor; Bounds val = Extent(_volume); if (((Bounds)(ref val)).size.x < 1f || ((Bounds)(ref val)).size.y < 1f || ((Bounds)(ref val)).size.z < 1f) { Plugin.Log.LogWarning((object)"[FinalAscent] Lichtbake (eigen): kein Berg zu vermessen."); return false; } _w = Four(((Bounds)(ref val)).size.x / FinalAscentLightBake.Spacing); _h = Four(((Bounds)(ref val)).size.y / FinalAscentLightBake.Spacing); _d = Four(((Bounds)(ref val)).size.z / FinalAscentLightBake.Spacing); _count = _w * _h * _d; _offset = ((Bounds)(ref val)).min; _middle = ((Bounds)(ref val)).center; _grid = (Color[])(object)new Color[_count]; _lamps = Lamps(); _ask = new QueryParameters(_solid, false, (QueryTriggerInteraction)1, true); _fan = new NativeArray(_rays, (Allocator)4, (NativeArrayOptions)1); Fan(); _mainShots = new NativeArray(256 * _rays, (Allocator)4, (NativeArrayOptions)1); _mainHits = new NativeArray(256 * _rays, (Allocator)4, (NativeArrayOptions)1); int num = Mathf.Max(1, 262144 / _rays); _flights = new Flight[2]; for (int i = 0; i < _flights.Length; i++) { _flights[i] = new Flight { Shots = new NativeArray(num * _rays, (Allocator)4, (NativeArrayOptions)1), Hits = new NativeArray(num * _rays, (Allocator)4, (NativeArrayOptions)1), Open = new NativeArray(num, (Allocator)4, (NativeArrayOptions)1) }; } Plugin.Log.LogInfo((object)(string.Format("{0} Lichtbake (eigen) startet: {1}x{2}x{3} = {4} Voxel, ", "[FinalAscent]", _w, _h, _d, _count) + $"Raster {FinalAscentLightBake.Spacing:0}m, Ursprung " + $"{FinalAscentBuilder.Fmt(_offset)}, {_rays} Strahlen je Voxel " + $"(Volumen bestellt {_volume.rayCount}, Deckel 64 - siehe " + $"Kommentar), Weichzeichner {_volume.blurRadius}, " + $"{_lamps.Count} Lichtquellen, {(long)_count * (long)_rays} Himmelsstrahlen, " + $"{JobsUtility.JobWorkerCount} Arbeiterkerne " + $"({Environment.ProcessorCount} logische), zwei Fluege a " + $"{num} Voxel.")); return true; } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("{0} Lichtbake (eigen): Vorbereitung gescheitert - {1}", "[FinalAscent]", arg)); return false; } } private bool Pump() { try { for (int i = 0; i < _flights.Length; i++) { Flight flight = _flights[i]; if (flight.Busy && ((JobHandle)(ref flight.Done)).IsCompleted) { ((JobHandle)(ref flight.Done)).Complete(); Harvest(flight); flight.Busy = false; } } bool flag = false; for (int j = 0; j < _flights.Length; j++) { if (!_flights[j].Busy && _cursor < _count) { flag |= Load(_flights[j]); } } if (flag) { JobHandle.ScheduleBatchedJobs(); } if (_cursor < _count && Airborne()) { MainHelp(); } FinalAscentLightBake.Fraction = 0.94f * ((float)_doneVoxels / (float)_count); Progress(); FinalAscentKeepAlive.Tick(); return true; } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("{0} Lichtbake (eigen): Strahlen gescheitert - {1}", "[FinalAscent]", arg)); return false; } } private bool Load(Flight flight) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) int length = flight.Open.Length; int start; int num = NextSpan(length, out start); if (num <= 0) { return false; } JobHandle val = IJobParallelForExtensions.Schedule(new FillJob { Shots = flight.Shots, Fan = _fan, Rays = _rays, Start = start, Count = num, W = _w, H = _h, Offset = _offset, Spacing = FinalAscentLightBake.Spacing, Ask = _ask, Far = 400f }, length, 32, default(JobHandle)); JobHandle val2 = RaycastCommand.ScheduleBatch(flight.Shots, flight.Hits, 256, val); EvalJob evalJob = new EvalJob { Hits = flight.Hits, Open = flight.Open, Rays = _rays }; flight.Done = IJobParallelForExtensions.Schedule(evalJob, length, 32, val2); flight.Start = start; flight.Count = num; flight.Busy = true; return true; } private int NextSpan(int most, out int start) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) while (_cursor < _count) { int num = Mathf.Min(256, _count - _cursor); if (OnlyAir(_cursor, num)) { for (int i = 0; i < num; i++) { _grid[_cursor + i] = new Color(_sky.r, _sky.g, _sky.b, 1f); } _cursor += num; _doneVoxels += num; _skipped += num; continue; } start = _cursor; int num2 = Mathf.Min(num, most); _cursor += num2; while (num2 < most && _cursor < _count) { int num3 = Mathf.Min(256, _count - _cursor); if (num2 + num3 > most || OnlyAir(_cursor, num3)) { break; } num2 += num3; _cursor += num3; } return num2; } start = 0; return 0; } private void MainHelp() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_005d: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) float num = Time.realtimeSinceStartup + 0.025f; while (Time.realtimeSinceStartup < num) { int start; int num2 = NextSpan(256, out start); if (num2 <= 0) { break; } for (int i = 0; i < num2; i++) { Vector3 val = At(start + i); int num3 = i * _rays; for (int j = 0; j < _rays; j++) { _mainShots[num3 + j] = new RaycastCommand(val, _fan[j], _ask, 400f); } } for (int k = num2 * _rays; k < _mainShots.Length; k++) { _mainShots[k] = new RaycastCommand(Vector3.zero, Vector3.up, _ask, 0f); } NativeArray mainShots = _mainShots; NativeArray mainHits = _mainHits; JobHandle val2 = default(JobHandle); val2 = RaycastCommand.ScheduleBatch(mainShots, mainHits, 256, val2); ((JobHandle)(ref val2)).Complete(); for (int l = 0; l < num2; l++) { int num4 = 0; int num5 = l * _rays; for (int m = 0; m < _rays; m++) { RaycastHit val3 = _mainHits[num5 + m]; if (((RaycastHit)(ref val3)).colliderInstanceID == 0) { num4++; } } float num6 = (float)num4 / (float)_rays; _grid[start + l] = new Color(_sky.r * num6, _sky.g * num6, _sky.b * num6, num6); } _doneVoxels += num2; } } private bool OnlyAir(int start, int many) { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) float spacing = FinalAscentLightBake.Spacing; int num = start + many - 1; int num2 = start / (_w * _h); int num3 = num / (_w * _h); int num4 = 0; int num5 = _h - 1; if (num2 == num3) { num4 = start / _w % _h; num5 = num / _w % _h; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(_offset.x, _offset.y + (float)num4 * spacing, _offset.z + (float)num2 * spacing); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(_offset.x + (float)_w * spacing, _offset.y + (float)(num5 + 1) * spacing, _offset.z + (float)(num3 + 1) * spacing); Vector3 val3 = (val2 - val) * 0.5f + new Vector3(400f, 400f, 400f); return !Physics.CheckBox((val + val2) * 0.5f, val3, Quaternion.identity, _solid, (QueryTriggerInteraction)1); } private void Harvest(Flight flight) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < flight.Count; i++) { float num = flight.Open[i]; _grid[flight.Start + i] = new Color(_sky.r * num, _sky.g * num, _sky.b * num, num); } _doneVoxels += flight.Count; } private bool LampSlice() { try { float num = Time.realtimeSinceStartup + 0.04f; while (_lampCursor < _lamps.Count && Time.realtimeSinceStartup < num) { Shine(_lamps[_lampCursor]); _lampCursor++; FinalAscentKeepAlive.Tick(); } FinalAscentLightBake.Fraction = 0.94f + 0.030000031f * ((float)_lampCursor / (float)Mathf.Max(1, _lamps.Count)); return true; } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("{0} Lichtbake (eigen): Lampen gescheitert - {1}", "[FinalAscent]", arg)); return false; } } private void Shine(Lamp lamp) { //IL_0015: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) float spacing = FinalAscentLightBake.Spacing; int num = Mathf.CeilToInt(lamp.Reach / spacing); int num2 = Mathf.RoundToInt((lamp.Where.x - _offset.x) / spacing); int num3 = Mathf.RoundToInt((lamp.Where.y - _offset.y) / spacing); int num4 = Mathf.RoundToInt((lamp.Where.z - _offset.z) / spacing); for (int i = Mathf.Max(0, num4 - num); i <= Mathf.Min(_d - 1, num4 + num); i++) { for (int j = Mathf.Max(0, num3 - num); j <= Mathf.Min(_h - 1, num3 + num); j++) { for (int k = Mathf.Max(0, num2 - num); k <= Mathf.Min(_w - 1, num2 + num); k++) { int num5 = (i * _h + j) * _w + k; Vector3 val = At(num5); Vector3 val2 = lamp.Where - val; float magnitude = ((Vector3)(ref val2)).magnitude; if (magnitude > lamp.Reach || magnitude < 0.001f) { continue; } float num6 = 1f - Mathf.SmoothStep(lamp.Fade, 1f, magnitude / lamp.Reach); if (lamp.Cone > 0f) { float num7 = Vector3.Angle(lamp.Facing, -val2) * (MathF.PI / 180f); if (num7 > lamp.Cone) { continue; } num6 *= 1f - Mathf.SmoothStep(lamp.ConeFade, 1f, num7 / lamp.Cone); } if (!(num6 <= 0.001f) && !Physics.Raycast(val, val2 / magnitude, Mathf.Max(0.01f, magnitude - 0.5f), _solid)) { Color val3 = _grid[num5]; _grid[num5] = new Color(val3.r + lamp.Tint.r * num6, val3.g + lamp.Tint.g * num6, val3.b + lamp.Tint.b * num6, val3.a); } } } } } private bool BlurAxis(int axis) { //IL_004d: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) try { if (_scratch == null) { _scratch = (Color[])(object)new Color[_count]; } int num = axis switch { 1 => _w, 0 => 1, _ => _w * _h, }; Color[] grid = _grid; Color[] scratch = _scratch; for (int i = 0; i < _count; i++) { Color val = grid[i] * 2f; float num2 = 2f; int num3 = i - num; int num4 = i + num; if (num3 >= 0) { val += grid[num3]; num2 += 1f; } if (num4 < _count) { val += grid[num4]; num2 += 1f; } scratch[i] = val / num2; } _grid = scratch; _scratch = grid; return true; } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("{0} Lichtbake (eigen): Weichzeichner gescheitert - {1}", "[FinalAscent]", arg)); return false; } } private bool Deliver() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0029: 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) try { Texture3D val = new Texture3D(_w, _h, _d, (TextureFormat)17, false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = _volume.filterModeRT; val.SetPixels(_grid); val.Apply(false); if (!Install(_volume, val, _w, _h, _d, _offset, _middle)) { Object.Destroy((Object)(object)val); return false; } FinalAscentLightAudit.Survey("eigener Bake"); Plugin.Log.LogInfo((object)("[FinalAscent] Lichtbake (eigen) fertig nach " + $"{Time.realtimeSinceStartup - _began:F1}s: {_count} Voxel " + $"({_skipped * 100 / Mathf.Max(1, _count)}% als freie Luft " + $"uebersprungen), {(long)_count * 8L / 1048576} MB.")); return true; } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("{0} Lichtbake (eigen): Einhaengen gescheitert - {1}", "[FinalAscent]", arg)); return false; } } private void Finish(bool ok) { if (!_finished) { _finished = true; if (!ok && (Object)(object)_volume != (Object)null) { _volume.raySpacing = _wasSpacing; } Free(); Action done = _done; _done = null; done?.Invoke(ok); Object.Destroy((Object)(object)((Component)this).gameObject); } } private void Free() { if (_flights != null) { for (int i = 0; i < _flights.Length; i++) { Flight flight = _flights[i]; if (flight != null) { if (flight.Busy) { ((JobHandle)(ref flight.Done)).Complete(); flight.Busy = false; } if (flight.Shots.IsCreated) { flight.Shots.Dispose(); } if (flight.Hits.IsCreated) { flight.Hits.Dispose(); } if (flight.Open.IsCreated) { flight.Open.Dispose(); } } } _flights = null; } if (_mainShots.IsCreated) { _mainShots.Dispose(); } if (_mainHits.IsCreated) { _mainHits.Dispose(); } if (_fan.IsCreated) { _fan.Dispose(); } _grid = null; _scratch = null; } private void OnDestroy() { if (!_finished) { _finished = true; if ((Object)(object)_volume != (Object)null) { _volume.raySpacing = _wasSpacing; } Free(); Action done = _done; _done = null; done?.Invoke(obj: false); } } private void Progress() { if (!(Time.realtimeSinceStartup - _told < 5f)) { _told = Time.realtimeSinceStartup; float num = (float)_doneVoxels / (float)_count; float num2 = _told - _began; long num3 = (_doneVoxels - _skipped) * _rays; string arg = ((num >= 0.01f) ? $", noch etwa {num2 / num - num2:F0}s" : ", Hochrechnung folgt"); Plugin.Log.LogInfo((object)(string.Format("{0} Lichtbake (eigen): {1:0}% ({2}/{3} ", "[FinalAscent]", num * 100f, _doneVoxels, _count) + $"Voxel, {_skipped} als Luft uebersprungen), {num2:F0}s gelaufen, " + $"{(float)num3 / Mathf.Max(1f, num2) / 1000000f:F1} Mio Strahlen/s{arg}.")); } } private Vector3 At(int index) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) float spacing = FinalAscentLightBake.Spacing; int num = index % _w; int num2 = index / _w % _h; int num3 = index / (_w * _h); return new Vector3(_offset.x + ((float)num + 0.5f) * spacing, _offset.y + ((float)num2 + 0.5f) * spacing, _offset.z + ((float)num3 + 0.5f) * spacing); } private void Fan() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) float num = MathF.PI * (3f - Mathf.Sqrt(5f)); for (int i = 0; i < _rays; i++) { float num2 = 1f - ((float)i + 0.5f) / (float)_rays * 2f; float num3 = Mathf.Sqrt(Mathf.Max(0f, 1f - num2 * num2)); float num4 = num * (float)i; ref NativeArray fan = ref _fan; int num5 = i; Vector3 val = new Vector3(Mathf.Cos(num4) * num3, num2, Mathf.Sin(num4) * num3); fan[num5] = ((Vector3)(ref val)).normalized; } } private static Bounds Extent(LightVolume volume) { //IL_0047: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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) MethodInfo methodInfo = AccessTools.Method(typeof(LightVolume), "GetTotalBounds", (Type[])null, (Type[])null); if (methodInfo != null) { try { return (Bounds)methodInfo.Invoke(volume, null); } catch (Exception) { Plugin.Log.LogWarning((object)"[FinalAscent] Lichtbake (eigen): GetTotalBounds nicht nutzbar - es wird selbst vermessen."); } } Bounds result = default(Bounds); bool flag = true; MeshRenderer[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (MeshRenderer val in array) { if ((Object)(object)val == (Object)null) { continue; } string text = (((Object)(object)((Component)val).transform.parent != (Object)null) ? ((Object)((Component)val).transform.parent).name : ""); if (!(text == "WaterMesh") && !(text == "Water")) { if (flag) { result = ((Renderer)val).bounds; flag = false; } else { ((Bounds)(ref result)).Encapsulate(((Renderer)val).bounds); } } } return result; } private static List Lamps() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_00aa: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Invalid comparison between Unknown and I4 List list = new List(); BakedVolumeLight[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (BakedVolumeLight val in array) { if (!((Object)(object)val == (Object)null) && ((Behaviour)val).enabled && !(val.radius <= 0f)) { list.Add(new Lamp { Where = ((Component)val).transform.position, Facing = ((Component)val).transform.forward, Tint = new Color(val.color.r * val.intensity, val.color.g * val.intensity, val.color.b * val.intensity, 0f), Reach = val.radius, Fade = Mathf.Clamp01(val.falloff), Cone = (((int)val.mode == 1) ? (val.coneSize * (MathF.PI / 180f)) : 0f), ConeFade = Mathf.Clamp01(val.coneFalloff) }); } } return list; } private static bool Install(LightVolume volume, Texture3D tex, int w, int h, int d, Vector3 offset, Vector3 middle) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) FieldInfo fieldInfo = AccessTools.Field(typeof(CompressableLightMap), "k__BackingField"); if (fieldInfo == null) { Plugin.Log.LogError((object)"[FinalAscent] Lichtbake (eigen): 'Uncompressed' nicht gefunden - die Textur laesst sich nicht einhaengen."); return false; } object obj = volume.lightMapData; fieldInfo.SetValue(obj, tex); volume.lightMapData = (CompressableLightMap)obj; FieldInfo fieldInfo2 = AccessTools.Field(typeof(LightVolume), "gridRes"); if (fieldInfo2 != null) { object value = fieldInfo2.GetValue(volume); Type type = value.GetType(); type.GetField("x").SetValue(value, (uint)w); type.GetField("y").SetValue(value, (uint)h); type.GetField("z").SetValue(value, (uint)d); fieldInfo2.SetValue(volume, value); } volume.gridOffset = offset; volume.gridCenter = middle; volume.raySpacing = FinalAscentLightBake.Spacing; Shader.SetGlobalVector("_GridRes", new Vector4((float)w, (float)h, (float)d)); Shader.SetGlobalFloat("_RaySpacing", FinalAscentLightBake.Spacing); Shader.SetGlobalVector("_GridOffset", Vector4.op_Implicit(offset)); Shader.SetGlobalTexture("_LightMap", (Texture)(object)tex); return true; } private static int Four(float value) { return Mathf.Max(4, Mathf.CeilToInt(value / 4f) * 4); } } internal static class FinalAscentLightBudget { private struct Piece { internal long Triangles; internal long Vertices; internal float Size; } private const string Tag = "[FinalAscent]"; private const long BvhPerTriangle = 64L; private const long ScratchPerTriangle = 20L; private const long PositionPerVertex = 12L; private const float Share = 0.5f; private const string Breadcrumb = "lightbake.compute.attempt"; internal static float MinSize { get; private set; } internal static bool Tripped { get { try { string text = Path(); return text != null && File.Exists(text); } catch (Exception) { return false; } } } internal static void Reset() { MinSize = 0f; } private static string Path() { try { return FinalAscentStore.State("lightbake.compute.attempt"); } catch (Exception) { return null; } } internal static void Arm() { try { string text = Path(); if (text != null) { File.WriteAllText(text, DateTime.Now.ToString("s")); } } catch (Exception) { } } internal static void Disarm() { try { string text = Path(); if (text != null && File.Exists(text)) { File.Delete(text); } } catch (Exception) { } } private static bool Wanted(MeshRenderer renderer, LayerMask occluders) { if ((Object)(object)renderer == (Object)null || !((Renderer)renderer).enabled) { return false; } if (((1 << ((Component)renderer).gameObject.layer) & ((LayerMask)(ref occluders)).value) == 0) { return false; } if (((Component)renderer).CompareTag("DoNotBake")) { return false; } Transform parent = ((Component)renderer).transform.parent; LODGroup val = default(LODGroup); if ((Object)(object)parent == (Object)null || !((Component)parent).TryGetComponent(ref val)) { return true; } LOD[] lODs = val.GetLODs(); if (lODs == null || lODs.Length == 0) { return true; } Renderer[] array = ((lODs.Length <= 1) ? lODs[0].renderers : lODs[1].renderers); if (array != null && array.Length != 0) { return (Object)(object)array[0] == (Object)(object)renderer; } return false; } private static long Cost(Piece piece) { return piece.Triangles * 84 + piece.Vertices * 12; } internal static bool Fits(LightVolume volume) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) MinSize = 0f; Dictionary dictionary = new Dictionary(); int num = 0; try { LayerMask occluders = (((Object)(object)volume != (Object)null) ? volume.occluderMask : LayerMask.op_Implicit(-1)); MeshRenderer[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (MeshRenderer val in array) { FinalAscentKeepAlive.Tick(); if (!Wanted(val, occluders)) { continue; } MeshFilter component = ((Component)val).GetComponent(); Mesh val2 = (((Object)(object)component != (Object)null) ? component.sharedMesh : null); if ((Object)(object)val2 == (Object)null || !val2.isReadable || !val2.HasVertexAttribute((VertexAttribute)0)) { continue; } num++; float num2 = 0f; Bounds bounds = ((Renderer)val).bounds; Vector3 size = ((Bounds)(ref bounds)).size; num2 = Mathf.Max(size.x, Mathf.Max(size.y, size.z)); int instanceID = ((Object)val2).GetInstanceID(); if (dictionary.TryGetValue(instanceID, out var value)) { if (num2 > value.Size) { value.Size = num2; dictionary[instanceID] = value; } continue; } value = new Piece { Size = num2, Vertices = val2.vertexCount }; for (int j = 0; j < val2.subMeshCount; j++) { value.Triangles += (long)val2.GetIndexCount(j) / 3L; } dictionary[instanceID] = value; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Speicherrechnung fuer den Compute-Bake gescheitert (" + ex.Message + ") - er wird nicht gewagt.")); return false; } long num3 = 0L; long num4 = 0L; foreach (Piece value2 in dictionary.Values) { num3 += Cost(value2); num4 += value2.Triangles; } long num5 = num3 / 1048576; int graphicsMemorySize = SystemInfo.graphicsMemorySize; long num6 = (long)((float)graphicsMemorySize * 0.5f); Plugin.Log.LogInfo((object)(string.Format("{0} Compute-Bake braucht etwa {1} MB Grafikspeicher: ", "[FinalAscent]", num5) + $"{dictionary.Count} verschiedene Meshes in {num} Auftritten, " + $"{num4} Dreiecke (die geteilten NUR EINMAL gezaehlt - der Baum " + "wird je Mesh einmal gebaut, nicht je Auftritt). Karte meldet " + $"{graphicsMemorySize} MB, davon zugestanden {num6} MB.")); if (graphicsMemorySize <= 0) { Plugin.Log.LogWarning((object)"[FinalAscent] Die Karte meldet keinen Grafikspeicher - dann laesst sich nichts nachrechnen, und der Compute-Bake wird nicht gewagt."); return false; } if (num5 <= num6) { return true; } return Thin(volume, dictionary, num6, num5); } private static bool Thin(LightVolume volume, Dictionary unique, long allowMb, long wasMb) { float num = (((Object)(object)volume != (Object)null && volume.raySpacing > 0f) ? volume.raySpacing : 7f); List list = new List(unique.Values); list.Sort((Piece a, Piece b) => b.Size.CompareTo(a.Size)); long num2 = allowMb * 1048576; long num3 = 0L; int num4 = 0; float num5 = 0f; foreach (Piece item in list) { long num6 = num3 + Cost(item); if (num6 > num2) { num5 = item.Size; break; } num3 = num6; num4++; } if (num4 == list.Count) { return true; } if (num5 >= num) { Plugin.Log.LogWarning((object)(string.Format("{0} Selbst ohne alles unter {1:0.0} m passt es nicht - und ", "[FinalAscent]", num5) + $"das ist groesser als eine Rasterzelle ({num:0.0} m). Weiter " + "auszuduennen hiesse, echte Schattenwerfer wegzulassen. Es rechnet der eigene CPU-Bake: langsamer, aber er kommt an.")); return false; } MinSize = num5; Plugin.Log.LogInfo((object)("[FinalAscent] Compute-Bake wird ausgeduennt statt aufgegeben: alles unter " + $"{num5:0.00} m bleibt draussen ({num4} von {list.Count} Meshes " + $"bleiben, {wasMb} MB -> {num3 / 1048576} MB). Bei einer " + $"Rasterweite von {num:0.0} m liegt so ein Stueck ohnehin zwischen " + "zwei Abtastpunkten und aendert am Ergebnis nichts.")); return true; } } internal static class FinalAscentLightKernels { private const string Tag = "[FinalAscent]"; private const string FileName = "truefinalascent.rtkernels.bundle"; private static AssetBundle _bundle; private static bool _searched; private static bool _broken; internal static bool Ready { get { if (_broken) { return false; } if ((Object)(object)_bundle != (Object)null) { return true; } if (_searched) { return false; } _searched = true; try { string text = Path.Combine(Path.GetDirectoryName(typeof(FinalAscentLightKernels).Assembly.Location) ?? ".", "truefinalascent.rtkernels.bundle"); if (!File.Exists(text)) { return false; } _bundle = AssetBundle.LoadFromFile(text); if ((Object)(object)_bundle == (Object)null) { _broken = true; Plugin.Log.LogWarning((object)"[FinalAscent] Kernel-Bundle 'truefinalascent.rtkernels.bundle' liegt da, laesst sich aber nicht oeffnen - vermutlich mit einer anderen Unity-Fassung gebaut als 6000.3.15f1. Es bleibt beim CPU-Bake."); return false; } Plugin.Log.LogInfo((object)"[FinalAscent] Kernel-Bundle geladen: truefinalascent.rtkernels.bundle - Vanillas Compute-Bake steht damit auch ohne DXR zur Verfuegung."); return true; } catch (Exception ex) { _broken = true; Plugin.Log.LogWarning((object)("[FinalAscent] Kernel-Bundle nicht ladbar: " + ex.Message + " - es bleibt beim CPU-Bake.")); return false; } } } internal static bool Fill(RayTracingResources into) { if (into == null || !Ready) { return false; } ComputeShader[] array = _bundle.LoadAllAssets(); ComputeShader[] array2 = array; foreach (ComputeShader val in array2) { if (!((Object)(object)val == (Object)null)) { string name = ((Object)val).name; if (Same(name, "GeometryPoolKernels")) { into.geometryPoolKernels = val; } else if (Same(name, "CopyBuffer")) { into.copyBuffer = val; } else if (Same(name, "CopyPositions")) { into.copyPositions = val; } else if (Same(name, "bit_histogram")) { into.bitHistogram = val; } else if (Same(name, "scatter")) { into.scatter = val; } else if (Same(name, "block_reduce_part")) { into.blockReducePart = val; } else if (Same(name, "block_scan")) { into.blockScan = val; } else if (Same(name, "build_hlbvh")) { into.buildHlbvh = val; } else if (Same(name, "restructure_bvh")) { into.restructureBvh = val; } } } if (Complete(into)) { return true; } Plugin.Log.LogWarning((object)(string.Format("{0} Kernel unvollstaendig ({1} im Bundle): ", "[FinalAscent]", array.Length) + Missing(into))); return false; } private static bool Same(string a, string b) { return string.Equals(a, b, StringComparison.OrdinalIgnoreCase); } private static string Missing(RayTracingResources r) { StringBuilder stringBuilder = new StringBuilder(); if ((Object)(object)r.geometryPoolKernels == (Object)null) { stringBuilder.Append("GeometryPoolKernels "); } if ((Object)(object)r.copyBuffer == (Object)null) { stringBuilder.Append("CopyBuffer "); } if ((Object)(object)r.copyPositions == (Object)null) { stringBuilder.Append("CopyPositions "); } if ((Object)(object)r.bitHistogram == (Object)null) { stringBuilder.Append("bit_histogram "); } if ((Object)(object)r.scatter == (Object)null) { stringBuilder.Append("scatter "); } if ((Object)(object)r.blockReducePart == (Object)null) { stringBuilder.Append("block_reduce_part "); } if ((Object)(object)r.blockScan == (Object)null) { stringBuilder.Append("block_scan "); } if ((Object)(object)r.buildHlbvh == (Object)null) { stringBuilder.Append("build_hlbvh "); } if ((Object)(object)r.restructureBvh == (Object)null) { stringBuilder.Append("restructure_bvh "); } if (stringBuilder.Length <= 0) { return "keine Luecke"; } return "es fehlen " + stringBuilder.ToString().Trim(); } internal static bool Complete(RayTracingResources loaded) { if (loaded != null && (Object)(object)loaded.geometryPoolKernels != (Object)null && (Object)(object)loaded.copyBuffer != (Object)null && (Object)(object)loaded.copyPositions != (Object)null && (Object)(object)loaded.bitHistogram != (Object)null && (Object)(object)loaded.scatter != (Object)null && (Object)(object)loaded.blockReducePart != (Object)null && (Object)(object)loaded.blockScan != (Object)null && (Object)(object)loaded.buildHlbvh != (Object)null) { return (Object)(object)loaded.restructureBvh != (Object)null; } return false; } } [HarmonyPatch(typeof(RayTracingResources), "LoadFromRenderPipelineResources")] internal static class FinalAscentLightKernelsPatch { private const string Tag = "[FinalAscent]"; private static void Postfix(RayTracingResources __instance, ref bool __result) { if ((__result && FinalAscentLightKernels.Complete(__instance)) || !FinalAscentLightKernels.Ready) { return; } try { bool flag = FinalAscentLightKernels.Fill(__instance); Plugin.Log.LogInfo((object)("[FinalAscent] RadeonRays-Kernel aus dem Bundle nachgeladen: " + (flag ? "alle neun da." : "UNVOLLSTAENDIG - siehe Warnung."))); __result = flag; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Kernel-Nachladen gescheitert: " + ex.Message)); } } } [HarmonyPatch(typeof(RayTracingContext), "IsBackendSupported")] internal static class FinalAscentPretendNoDxrPatch { private static bool Prefix(RayTracingBackend backend, ref bool __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if ((int)backend != 0 || !FinalAscentLight.PretendNoDxr) { return true; } __result = false; return false; } } internal static class FinalAscentLightMeshGuard { private const string Tag = "[FinalAscent]"; private const int Names = 12; private static readonly Dictionary Verdicts = new Dictionary(); private static int _skipped; private static int _told; private static int _thinned; internal static void Reset() { Verdicts.Clear(); _skipped = 0; _told = 0; _thinned = 0; } internal static void Report() { if (_thinned > 0) { Plugin.Log.LogInfo((object)(string.Format("{0} Compute-Bake: {1} Mesh-Auftraege ausgeduennt ", "[FinalAscent]", _thinned) + $"(kleiner als {FinalAscentLightBudget.MinSize:0.00} m).")); } if (_skipped > 0) { Plugin.Log.LogInfo((object)(string.Format("{0} Compute-Bake: {1} Mesh-Auftraege uebersprungen, weil ", "[FinalAscent]", _skipped) + "das Mesh keinen Vertexpuffer auf der Grafikkarte hat " + $"({Verdicts.Count} verschiedene Meshes geprueft). Solche Meshes " + "werfen keinen Schatten; der Hardware-Weg fragt gar nicht erst nach ihnen.")); } } internal static bool Usable(MeshInstanceDesc desc) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) Mesh mesh = desc.mesh; if ((Object)(object)mesh == (Object)null) { return false; } float minSize = FinalAscentLightBudget.MinSize; if (minSize > 0f) { Vector3 lossyScale = ((Matrix4x4)(ref desc.localToWorldMatrix)).lossyScale; Bounds bounds = mesh.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (Mathf.Max(Mathf.Abs(size.x * lossyScale.x), Mathf.Max(Mathf.Abs(size.y * lossyScale.y), Mathf.Abs(size.z * lossyScale.z))) < minSize) { _thinned++; return false; } } int instanceID = ((Object)mesh).GetInstanceID(); if (Verdicts.TryGetValue(instanceID, out var value)) { return value; } bool flag = false; int num = 0; try { num = mesh.vertexCount; if (num > 0 && mesh.HasVertexAttribute((VertexAttribute)0)) { mesh.vertexBufferTarget = (Target)(mesh.vertexBufferTarget | 0x20); int vertexAttributeStream = mesh.GetVertexAttributeStream((VertexAttribute)0); GraphicsBuffer vertexBuffer = mesh.GetVertexBuffer(vertexAttributeStream); try { flag = vertexBuffer != null; } finally { ((IDisposable)vertexBuffer)?.Dispose(); } } } catch (Exception) { flag = false; } Verdicts[instanceID] = flag; if (!flag && _told < 12) { _told++; Plugin.Log.LogInfo((object)("[FinalAscent] Compute-Bake ueberspringt Mesh '" + ((Object)mesh).name + "' " + $"({num} Vertices): kein Vertexpuffer auf der Grafikkarte.")); } return flag; } internal static void Counted() { _skipped++; } } [HarmonyPatch] internal static class FinalAscentComputeMeshGuardPatch { private static bool Prepare() { return Target() != null; } private static MethodBase TargetMethod() { return Target(); } private static MethodBase Target() { Type type = AccessTools.TypeByName("UnityEngine.Rendering.UnifiedRayTracing.ComputeRayTracingAccelStruct"); if (!(type == null)) { return AccessTools.Method(type, "AddInstance", new Type[1] { typeof(MeshInstanceDesc) }, (Type[])null); } return null; } private static bool Prefix(MeshInstanceDesc meshInstance, ref int __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (FinalAscentLightMeshGuard.Usable(meshInstance)) { return true; } FinalAscentLightMeshGuard.Counted(); __result = -1; return false; } } [HarmonyPatch(typeof(DayNightManager), "BlendProfiles")] internal static class FinalAscentProfileLogPatch { private static void Prefix(DayNightManager __instance, DayNightProfile profile) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (FinalAscent.Active && Plugin.Diagnosing) { Plugin.Log.LogInfo((object)("[FinalAscent] Beleuchtungsprofil wechselt auf '" + (((Object)(object)profile != (Object)null) ? ((Object)profile).name : "-") + "' (bisher '" + (((Object)(object)__instance.currentProfile != (Object)null) ? ((Object)__instance.currentProfile).name : "-") + "', " + $"Etappe {MapHandler.CurrentSegmentNumber}).")); } } } internal static class FinalAscentLoadHud { private const string Tag = "[FinalAscent]"; private static GameObject _root; private static TMP_Text _mainLabel; private static TMP_Text _stripLabel; private static TMP_Text _keyLabel; private static TMP_Text _detailLabel; private static TMP_Text _bakeLabel; private static readonly Color BakeYellow = new Color(1f, 0.82f, 0.29f); private static string _main = string.Empty; private static string _key = string.Empty; private static bool _dots = true; private static string _detail = string.Empty; private static readonly List _biomeOrder = new List(); private static readonly Dictionary _biomeTotal = new Dictionary(); private static readonly Dictionary _biomeDone = new Dictionary(); private static string _biomeNow = string.Empty; private static float _biomeFraction; private static string _biomeUnit = string.Empty; private static string _activeBiome = string.Empty; private static float _activeUntil; private static int _biomeWeight = 1; private static string _tick = string.Empty; private static string _tickHow = "keiner"; private static TMP_SpriteAsset _tickSprites; internal static bool Up => (Object)(object)_root != (Object)null; internal static string CurrentPhase => _key + " / " + _detail; internal static void Show() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Expected O, but got Unknown //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Expected O, but got Unknown //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Expected O, but got Unknown if (!((Object)(object)_root != (Object)null)) { _root = new GameObject("FA_LoadHud"); Object.DontDestroyOnLoad((Object)(object)_root); Canvas obj = _root.AddComponent(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 32767; CanvasScaler obj2 = _root.AddComponent(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.screenMatchMode = (ScreenMatchMode)0; obj2.matchWidthOrHeight = 1f; GameObject val = new GameObject("Box"); val.transform.SetParent(_root.transform, false); Image obj3 = val.AddComponent(); ((Graphic)obj3).color = new Color(0f, 0f, 0f, 0.93f); ((Graphic)obj3).raycastTarget = false; RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0.5f, 0f); component.anchorMax = new Vector2(0.5f, 0f); component.pivot = new Vector2(0.5f, 0f); component.sizeDelta = new Vector2(1280f, 0f); component.anchoredPosition = new Vector2(0f, 80f); VerticalLayoutGroup obj4 = val.AddComponent(); ((LayoutGroup)obj4).padding = new RectOffset(28, 28, 16, 16); ((HorizontalOrVerticalLayoutGroup)obj4).spacing = 6f; ((LayoutGroup)obj4).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = false; ContentSizeFitter obj5 = val.AddComponent(); obj5.horizontalFit = (FitMode)0; obj5.verticalFit = (FitMode)2; TMP_FontAsset val2 = FindFont(); _mainLabel = Line(val, val2, 32f, Color.white); _stripLabel = Line(val, val2, 22f, Color.white); _bakeLabel = Line(val, val2, 20f, BakeYellow); ((Component)_bakeLabel).gameObject.SetActive(false); _keyLabel = Line(val, val2, 16f, new Color(0.498f, 0.698f, 1f)); _detailLabel = Line(val, val2, 16f, new Color(0.604f, 0.604f, 0.604f)); PickTick(val2, _stripLabel); if ((Object)(object)_tickSprites != (Object)null) { _stripLabel.spriteAsset = _tickSprites; } ((Component)_keyLabel).gameObject.SetActive(Plugin.Diagnosing); ((Component)_detailLabel).gameObject.SetActive(Plugin.Diagnosing); _root.AddComponent(); _main = string.Empty; _key = string.Empty; _detail = string.Empty; _biomeOrder.Clear(); _biomeTotal.Clear(); _biomeDone.Clear(); _biomeNow = string.Empty; _biomeUnit = string.Empty; _biomeFraction = 0f; _biomeWeight = 1; _activeBiome = string.Empty; _activeUntil = 0f; Phase("load.prepare", "Preparing the mountain"); Plugin.Log.LogInfo((object)("[FinalAscent] Ladeanzeige steht" + (((Object)(object)val2 != (Object)null) ? (" (Schrift '" + ((Object)val2).name + "'") : " (ohne eigene Schrift") + ", Haken: " + _tickHow + ").")); } } private static TMP_Text Line(GameObject parent, TMP_FontAsset font, float size, Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Line"); val.transform.SetParent(parent.transform, false); TextMeshProUGUI val2 = val.AddComponent(); ((TMP_Text)val2).alignment = (TextAlignmentOptions)514; ((TMP_Text)val2).richText = true; ((Graphic)val2).color = color; ((TMP_Text)val2).fontSize = size; ((TMP_Text)val2).textWrappingMode = (TextWrappingModes)1; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; ((Graphic)val2).raycastTarget = false; if ((Object)(object)font != (Object)null) { ((TMP_Text)val2).font = font; if ((Object)(object)FinalAscentUiKit.FontMaterial != (Object)null) { ((TMP_Text)val2).fontSharedMaterial = FinalAscentUiKit.FontMaterial; } } return (TMP_Text)(object)val2; } private static void PickTick(TMP_FontAsset font, TMP_Text sample) { _tick = string.Empty; _tickHow = "keiner"; if ((Object)(object)font != (Object)null) { char[] array = new char[3] { '✓', '✔', '√' }; for (int i = 0; i < array.Length; i++) { char c = array[i]; if (font.HasCharacter(c, true, true)) { _tick = " " + c; _tickHow = "Zeichen aus der Schrift"; return; } } } TMP_SpriteAsset val = BuildTickSprite(); if ((Object)(object)val != (Object)null && (Object)(object)sample != (Object)null) { _tickSprites = val; _tick = " "; _tickHow = "Bild aus dem Spiel"; } } private static TMP_SpriteAsset BuildTickSprite() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown Sprite checkSprite = FinalAscentUiKit.CheckSprite; if ((Object)(object)checkSprite == (Object)null || (Object)(object)checkSprite.texture == (Object)null) { return null; } Shader val = Shader.Find("TextMeshPro/Sprite"); if ((Object)(object)val == (Object)null) { Plugin.Log.LogInfo((object)"[FinalAscent] Kein TMP-Bildschattierer vorhanden - der Haken bleibt weg."); return null; } try { TMP_SpriteAsset obj = ScriptableObject.CreateInstance(); ((Object)obj).name = "FA_Tick"; obj.spriteSheet = (Texture)(object)checkSprite.texture; ((TMP_Asset)obj).material = new Material(val); ((TMP_Asset)obj).material.SetTexture("_MainTex", (Texture)(object)checkSprite.texture); Rect rect = checkSprite.rect; TMP_SpriteGlyph val2 = new TMP_SpriteGlyph { index = 0u, sprite = checkSprite, scale = 1f, glyphRect = new GlyphRect((int)((Rect)(ref rect)).x, (int)((Rect)(ref rect)).y, (int)((Rect)(ref rect)).width, (int)((Rect)(ref rect)).height), metrics = new GlyphMetrics(((Rect)(ref rect)).width, ((Rect)(ref rect)).height, 0f, ((Rect)(ref rect)).height * 0.8f, ((Rect)(ref rect)).width) }; obj.spriteGlyphTable.Add(val2); TMP_SpriteCharacter item = new TMP_SpriteCharacter(0u, val2) { name = "check", scale = 1f }; obj.spriteCharacterTable.Add(item); obj.UpdateLookupTables(); return obj; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Haken liess sich nicht bauen: " + ex.Message)); return null; } } private static TMP_FontAsset FindFont() { if ((Object)(object)FinalAscentUiKit.Font != (Object)null) { return FinalAscentUiKit.Font; } TMP_FontAsset val = null; TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll(); foreach (TMP_FontAsset val2 in array) { if (!((Object)(object)val2 == (Object)null)) { if (((Object)val2).name.IndexOf("Liberation", StringComparison.OrdinalIgnoreCase) < 0) { return val2; } val = val ?? val2; } } return val; } internal static void Phase(string key, string fallback, bool dots = true) { string text = (string.IsNullOrEmpty(key) ? null : FinalAscentText.Get(key)); _main = (string.IsNullOrEmpty(text) ? (fallback ?? string.Empty) : text); _key = key ?? string.Empty; _detail = fallback ?? string.Empty; _dots = dots; } internal static void Detail(string what) { _detail = what ?? string.Empty; } internal static void DetailBiome(string biomeKey, string stepName) { _detail = (string.IsNullOrEmpty(stepName) ? biomeKey : (biomeKey + " / " + stepName)); } internal static void Biomes(List> counted) { _biomeOrder.Clear(); _biomeTotal.Clear(); _biomeDone.Clear(); if (counted == null) { return; } foreach (KeyValuePair item in counted) { if (item.Value > 0 && !_biomeTotal.ContainsKey(item.Key)) { _biomeOrder.Add(item.Key); _biomeTotal[item.Key] = item.Value; _biomeDone[item.Key] = 0; } } } internal static void BiomeBegin(string biome, int weight = 1) { _biomeUnit = biome ?? string.Empty; _biomeFraction = 0f; _biomeWeight = ((weight <= 0) ? 1 : weight); if (!string.IsNullOrEmpty(_biomeUnit) && _biomeDone.ContainsKey(_biomeUnit)) { _biomeNow = _biomeUnit; } } internal static void BiomeProgress(float part) { if (part > _biomeFraction) { _biomeFraction = ((part > 1f) ? 1f : part); } } internal static void BiomeStep(string biome) { int biomeWeight = _biomeWeight; _biomeUnit = string.Empty; _biomeFraction = 0f; _biomeWeight = 1; if (!string.IsNullOrEmpty(biome) && _biomeDone.ContainsKey(biome)) { _biomeDone[biome] += biomeWeight; _biomeNow = biome; } } internal static void BiomeCredit(string biome, int weight) { if (weight > 0 && !string.IsNullOrEmpty(biome) && _biomeDone.ContainsKey(biome)) { _biomeDone[biome] += weight; } } internal static void BiomesFull() { foreach (string item in _biomeOrder) { _biomeDone[item] = _biomeTotal[item]; } _biomeNow = string.Empty; _biomeUnit = string.Empty; _biomeFraction = 0f; _biomeWeight = 1; _activeBiome = string.Empty; } private static void TrackActive() { if (_biomeUnit.Length != 0 && !(_biomeUnit == _activeBiome) && !(Time.realtimeSinceStartup < _activeUntil)) { _activeBiome = _biomeUnit; _activeUntil = Time.realtimeSinceStartup + 0.5f; } } private static string Strip() { if (_biomeOrder.Count == 0) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); foreach (string item in _biomeOrder) { if (stringBuilder.Length > 0) { stringBuilder.Append(" "); } int num = _biomeDone[item]; int num2 = _biomeTotal[item]; string value = FinalAscentText.Get("biome." + item); if (string.IsNullOrEmpty(value)) { value = item; } if (num >= num2) { stringBuilder.Append("").Append(value).Append(_tick) .Append(""); continue; } float num3 = (float)num + ((item == _biomeUnit) ? (_biomeFraction * (float)_biomeWeight) : 0f); int num4 = ((num2 > 0) ? ((int)(num3 * 100f / (float)num2)) : 0); if (num4 > 99) { num4 = 99; } if (item == _activeBiome) { stringBuilder.Append("").Append(value).Append(' ') .Append(num4) .Append("%"); } else if (num > 0) { stringBuilder.Append("").Append(value).Append(' ') .Append(num4) .Append("%"); } else { stringBuilder.Append("").Append(value).Append(""); } } return stringBuilder.ToString(); } internal static void Redraw() { if ((Object)(object)_mainLabel == (Object)null) { return; } TrackActive(); int count = (_dots ? ((int)(Time.realtimeSinceStartup * 2f) % 4) : 0); Set(_mainLabel, _main + new string('.', count)); Set(_stripLabel, Strip()); if ((Object)(object)_bakeLabel != (Object)null) { bool busy = FinalAscentLightBake.Busy; if (((Component)_bakeLabel).gameObject.activeSelf != busy) { ((Component)_bakeLabel).gameObject.SetActive(busy); } if (busy) { int num = (int)(FinalAscentLightBake.Fraction * 100f); if (num > 99) { num = 99; } Set(_bakeLabel, FinalAscentText.Get("load.cpulight") + " " + num + "%"); } } if (Plugin.Diagnosing) { Set(_keyLabel, (_key.Length > 0) ? _key : "-"); Set(_detailLabel, _detail); } } private static void Set(TMP_Text label, string text) { if (!((Object)(object)label == (Object)null) && !(label.text == text)) { label.text = text; } } internal static void Hide() { if (!((Object)(object)_root == (Object)null)) { Object.Destroy((Object)(object)_root); _root = null; _mainLabel = null; _stripLabel = null; _bakeLabel = null; _keyLabel = null; _detailLabel = null; _main = string.Empty; _key = string.Empty; _detail = string.Empty; } } } internal sealed class FinalAscentLoadHudTicker : MonoBehaviour { private void Update() { FinalAscentLoadHud.Redraw(); } } internal static class FinalAscentLoadProbe { private const string Tag = "[FinalAscent]"; private const double BudgetMs = 33.333333333333336; private const int KeepWorst = 12; private static bool _running; private static Stopwatch _piece; private static string _where = "-"; private static long _pieces; private static double _totalMs; private static long _under1; private static long _under17; private static long _under33; private static long _under100; private static long _under500; private static long _over500; private static double _frameAcc; private static long _frames; private static long _framesOver50; private static long _framesOver100; private static long _framesOver250; private static double _worstFrame; private static double _excessMs; private static readonly List> _worst = new List>(); private static readonly Dictionary _byName = new Dictionary(); internal static bool Running => _running; internal static double MsRecorded => _totalMs; internal static void Begin() { _running = Plugin.Diagnosing; if (_running) { _piece = Stopwatch.StartNew(); _where = "Anfang"; _pieces = 0L; _totalMs = 0.0; _under1 = (_under17 = (_under33 = (_under100 = (_under500 = (_over500 = 0L))))); _frameAcc = 0.0; _frames = 0L; _framesOver50 = (_framesOver100 = (_framesOver250 = 0L)); _worstFrame = 0.0; _excessMs = 0.0; _worst.Clear(); _byName.Clear(); } } internal static void Where(string what) { if (_running) { _where = what; } } internal static void Piece() { if (_running && _piece != null) { double totalMilliseconds = _piece.Elapsed.TotalMilliseconds; _piece.Restart(); Record(_where, totalMilliseconds); } } internal static void Piece(string what, double ms) { if (_running) { if (_piece != null) { _piece.Restart(); } Record(what, ms); } } private static void Record(string what, double ms) { _pieces++; _totalMs += ms; if (ms < 1.0) { _under1++; } else if (ms < 16.7) { _under17++; } else if (ms < 33.3) { _under33++; } else if (ms < 100.0) { _under100++; } else if (ms < 500.0) { _under500++; } else { _over500++; } if (ms >= 33.3) { Remember(what, ms); } if (ms >= 100.0) { string key = Family(what); if (!_byName.TryGetValue(key, out var value)) { value = new double[3]; _byName[key] = value; } value[0] += 1.0; value[1] += ms; if (ms > value[2]) { value[2] = ms; } } _frameAcc += ms; if (!(_frameAcc < 33.333333333333336)) { _frames++; if (_frameAcc > _worstFrame) { _worstFrame = _frameAcc; } if (_frameAcc > 250.0) { _framesOver250++; _framesOver100++; _framesOver50++; } else if (_frameAcc > 100.0) { _framesOver100++; _framesOver50++; } else if (_frameAcc > 50.0) { _framesOver50++; } _excessMs += _frameAcc - 33.333333333333336; _frameAcc = 0.0; } } private static string Family(string what) { int num = what.IndexOf("(Clone)", StringComparison.Ordinal); if (num > 0) { what = what.Substring(0, num); } int num2 = what.LastIndexOf(" (", StringComparison.Ordinal); if (num2 > 0 && what.EndsWith(")", StringComparison.Ordinal)) { what = what.Substring(0, num2); } return what.TrimEnd(); } private static void Remember(string what, double ms) { if (_worst.Count < 12 || !(ms <= _worst[_worst.Count - 1].Value)) { _worst.Add(new KeyValuePair(what, ms)); _worst.Sort((KeyValuePair a, KeyValuePair b) => b.Value.CompareTo(a.Value)); if (_worst.Count > 12) { _worst.RemoveAt(_worst.Count - 1); } } } internal static void Report() { if (!_running) { return; } _running = false; _piece = null; if (_pieces == 0L) { Plugin.Log.LogInfo((object)"[FinalAscent] Ladeprobe: nichts gemessen."); return; } Plugin.Log.LogInfo((object)(string.Format("{0} Ladeprobe: {1} unteilbare Arbeitsstuecke in ", "[FinalAscent]", _pieces) + $"{_totalMs / 1000.0:F1}s.")); Plugin.Log.LogInfo((object)(string.Format("{0} Laenge: unter 1ms {1} | 1-17ms {2} | ", "[FinalAscent]", _under1, _under17) + $"17-33ms {_under33} | 33-100ms {_under100} | 100-500ms {_under500} | " + $"ueber 500ms {_over500}")); if (_worst.Count > 0) { Plugin.Log.LogInfo((object)"[FinalAscent] Laengste Einzelstuecke - die sind nicht teilbar:"); foreach (KeyValuePair item in _worst) { Plugin.Log.LogInfo((object)string.Format("{0} {1,7:F0}ms {2}", "[FinalAscent]", item.Value, item.Key)); } } if (_byName.Count > 0) { List> list = new List>(_byName); list.Sort((KeyValuePair a, KeyValuePair b) => b.Value[1].CompareTo(a.Value[1])); Plugin.Log.LogInfo((object)"[FinalAscent] Woher die dicken Brocken kommen (ab 100ms, nach Gesamtzeit):"); for (int num = 0; num < list.Count && num < 10; num++) { KeyValuePair keyValuePair = list[num]; Plugin.Log.LogInfo((object)(string.Format("{0} {1,6:F1}s in {2,4:F0} Stuecken, ", "[FinalAscent]", keyValuePair.Value[1] / 1000.0, keyValuePair.Value[0]) + $"laengstes {keyValuePair.Value[2],6:F0}ms {keyValuePair.Key}")); } } Plugin.Log.LogInfo((object)(string.Format("{0} Mit einem Bild alle {1:F0}ms waeren es {2} Bilder ", "[FinalAscent]", 33.333333333333336, _frames) + $"(im Schnitt {((_frames > 0) ? (_totalMs / (double)_frames) : 0.0):F0}ms je Bild).")); Plugin.Log.LogInfo((object)(string.Format("{0} Davon ueber 50ms: {1}, ueber 100ms: {2}, ", "[FinalAscent]", _framesOver50, _framesOver100) + $"ueber 250ms: {_framesOver250}. Laengstes Bild {_worstFrame:F0}ms.")); Plugin.Log.LogInfo((object)(string.Format("{0} Summe der Ueberschreitungen: {1:F1}s von ", "[FinalAscent]", _excessMs / 1000.0) + $"{_totalMs / 1000.0:F1}s - soviel bliebe als Ruckeln stehen " + $"({((_totalMs > 0.0) ? (_excessMs * 100.0 / _totalMs) : 0.0):F0}%).")); if (_framesOver250 == 0L) { Plugin.Log.LogInfo((object)"[FinalAscent] Urteil: kein Stueck reisst eine Viertelsekunde - ein Bildlauf waere durchgehend fluessig."); } else { Plugin.Log.LogInfo((object)(string.Format("{0} Urteil: {1} Stellen bleiben spuerbar haengen. ", "[FinalAscent]", _framesOver250) + "Auftauen wuerde trotzdem helfen (Fenster reagiert, Bild laeuft), aber an diesen Stellen ruckelt es weiter.")); } } } [HarmonyPatch] internal static class FinalAscentLoadScreenPatch { private const string Tag = "[FinalAscent]"; [HarmonyPatch(typeof(LoadingScreenHandler), "Load")] [HarmonyPrefix] private static void BeforeLoad(ref IEnumerator[] processes) { Append(ref processes); } [HarmonyPatch(typeof(LoadingScreenHandler), "LoadWithoutDisablingQueue")] [HarmonyPrefix] private static void BeforeLoadOpen(ref IEnumerator[] processes) { Append(ref processes); } private static void Append(ref IEnumerator[] processes) { IEnumerator[] obj = processes; IEnumerator[] array = new IEnumerator[((obj != null) ? obj.Length : 0) + 1]; if (processes != null) { processes.CopyTo(array, 0); } array[^1] = WaitForMountain(); processes = array; } private static IEnumerator WaitForMountain() { if (!FinalAscent.Active || (Object)(object)Object.FindFirstObjectByType() == (Object)null) { yield break; } float waited = 0f; while (!FinalAscentBuilder.Building && !FinalAscentBuilder.Ready && waited < 30f) { waited += Time.unscaledDeltaTime; yield return null; } if (!FinalAscentBuilder.Building && !FinalAscentBuilder.Ready) { Plugin.Log.LogInfo((object)"[FinalAscent] Ladebildschirm: kein Bergaufbau in Sicht - es geht weiter."); FinalAscentLoadHud.Hide(); yield break; } Plugin.Log.LogInfo((object)"[FinalAscent] Ladebildschirm wartet auf den Berg."); float held = 0f; while (!FinalAscentBuilder.Ready && held < 600f) { held += Time.unscaledDeltaTime; yield return null; } if (!FinalAscentBuilder.Ready) { Plugin.Log.LogError((object)"[FinalAscent] Der Berg steht nach zehn Minuten immer noch nicht. Der Ladebildschirm geht trotzdem weiter - besser ein kaputter Lauf als ein Spiel, das nie zurueckkommt."); } else { Plugin.Log.LogInfo((object)string.Format("{0} Ladebildschirm gehalten: {1:F1}s auf den Berg gewartet.", "[FinalAscent]", held)); } FinalAscentLoadHud.Phase("load.done", "Done", dots: false); FinalAscentLoadHud.BiomesFull(); yield return (object)new WaitForSecondsRealtime(3f); FinalAscentLoadHud.Hide(); } } internal static class FinalAscentMatch { private const string Tag = "[FinalAscent]"; internal const string RoomKey = "FAp"; private const string KeyPrint = "FAp"; internal static void Publish(SortedDictionary print) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_0090: Expected O, but got Unknown if (!PhotonNetwork.IsMasterClient || !PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null || print == null) { return; } if (!string.IsNullOrEmpty(Read())) { Plugin.Detail("[FinalAscent] Im Raum steht schon ein Abdruck - der bleibt der Massstab."); return; } string text = Pack(print); if (text.Length > 900) { Plugin.Log.LogWarning((object)(string.Format("{0} Abdruck ist mit {1} Zeichen zu lang fuer den Raum - ", "[FinalAscent]", text.Length) + "der Abgleich entfaellt.")); return; } Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"FAp", (object)text); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)(string.Format("{0} Abdruck des Bergs im Raum hinterlegt ({1} Landschaften). ", "[FinalAscent]", print.Count) + "Nachzuegler koennen sich damit vergleichen.")); } internal static void CompareLater(SortedDictionary mine) { if (!PhotonNetwork.IsMasterClient && !((Object)(object)Plugin.Instance == (Object)null) && mine != null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(Wait(new SortedDictionary(mine))); } } private static IEnumerator Wait(SortedDictionary mine) { float until = Time.realtimeSinceStartup + 30f; string packed = null; while (Time.realtimeSinceStartup < until) { packed = Read(); if (!string.IsNullOrEmpty(packed)) { break; } yield return (object)new WaitForSecondsRealtime(1f); } if (string.IsNullOrEmpty(packed)) { Plugin.Log.LogInfo((object)"[FinalAscent] Kein Abdruck des Hosts im Raum - kein Abgleich moeglich. (Der Host laeuft womoeglich mit einer aelteren Fassung.)"); yield break; } Dictionary dictionary = Unpack(packed); List list = new List(); List list2 = new List(); int num = 0; foreach (KeyValuePair item in mine) { if (!dictionary.TryGetValue(item.Key, out var value)) { list.Add(item.Key + ": beim Host nicht vorhanden, hier " + item.Value); } else if (value != item.Value) { string obj = item.Value.Split('/')[0]; string text = value.Split('/')[0]; if (obj == text) { list2.Add(item.Key + ": Host " + value + ", hier " + item.Value); } else { list.Add(item.Key + ": Host " + value + ", hier " + item.Value); } } else { num++; } } foreach (KeyValuePair item2 in dictionary) { if (!mine.ContainsKey(item2.Key)) { list.Add(item2.Key + ": Host " + item2.Value + ", hier gar nicht vorhanden"); } } if (list.Count == 0 && list2.Count == 0) { Plugin.Log.LogInfo((object)(string.Format("{0} ABGLEICH MIT DEM HOST: alle {1} Landschaften stimmen ueberein - ", "[FinalAscent]", num) + "derselbe Berg.")); yield break; } if (list.Count == 0) { Plugin.Log.LogWarning((object)(string.Format("{0} ABGLEICH MIT DEM HOST: praktisch derselbe Berg - {1} Landschaften ", "[FinalAscent]", num) + $"exakt, {list2.Count} mit gleicher Anzahl und anderer Positionspruefsumme " + "(Fliesskomma-Kipps zwischen verschiedenen Rechnern; im Spiel nicht zu sehen):")); { foreach (string item3 in list2) { Plugin.Log.LogWarning((object)("[FinalAscent] " + item3)); } yield break; } } Plugin.Log.LogError((object)(string.Format("{0} ABGLEICH MIT DEM HOST FEHLGESCHLAGEN ({1} stimmen exakt, ", "[FinalAscent]", num) + $"{list2.Count} nur in der Pruefsumme, {list.Count} auch in der Anzahl):")); foreach (string item4 in list) { Plugin.Log.LogError((object)("[FinalAscent] " + item4)); } foreach (string item5 in list2) { Plugin.Log.LogWarning((object)("[FinalAscent] (nur Pruefsumme) " + item5)); } } private static string Read() { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return null; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties == null || !((Dictionary)(object)customProperties).TryGetValue((object)"FAp", out object value)) { return null; } return value as string; } private static string Pack(SortedDictionary print) { List list = new List(print.Count); foreach (KeyValuePair item in print) { string text = item.Value; int num = text.IndexOf('@'); if (num > 0) { text = text.Substring(0, num).Trim(); } list.Add(item.Key + "=" + text); } return string.Join(";", list); } private static Dictionary Unpack(string packed) { Dictionary dictionary = new Dictionary(); string[] array = packed.Split(';'); foreach (string text in array) { int num = text.IndexOf('='); if (num > 0) { dictionary[text.Substring(0, num)] = text.Substring(num + 1); } } return dictionary; } internal static SortedDictionary Trim(SortedDictionary print) { SortedDictionary sortedDictionary = new SortedDictionary(); foreach (KeyValuePair item in print) { string value = item.Value; int num = value.IndexOf('@'); sortedDictionary[item.Key] = ((num > 0) ? value.Substring(0, num).Trim() : value); } return sortedDictionary; } } [HarmonyPatch(typeof(PSM_MatchMaterial), "ModifyObject")] internal static class FinalAscentMatchMaterialProbe { private const string Tag = "[FinalAscent]"; private static readonly Dictionary Seen = new Dictionary(); private static int _total; private static int _withoutRenderer; private static int _withoutCollider; private static void Prefix(SpawnData spawnData) { if (!FinalAscent.Active) { return; } _total++; Collider collider = ((RaycastHit)(ref spawnData.hit)).collider; if ((Object)(object)collider == (Object)null) { _withoutCollider++; return; } Renderer component = ((Component)collider).gameObject.GetComponent(); if ((Object)(object)component == (Object)null) { _withoutRenderer++; return; } Material sharedMaterial = component.sharedMaterial; string key = (((Object)(object)sharedMaterial != (Object)null) ? ((Object)sharedMaterial).name : "(keins)") + " auf " + ((Object)((Component)collider).gameObject).name; Seen.TryGetValue(key, out var value); Seen[key] = value + 1; } internal static void Report() { if (_total == 0) { Plugin.Log.LogInfo((object)"[FinalAscent] PSM_MatchMaterial lief kein einziges Mal."); return; } Plugin.Log.LogInfo((object)(string.Format("{0} PSM_MatchMaterial: {1} Faelle, davon {2} ohne ", "[FinalAscent]", _total, _withoutCollider) + $"Treffer und {_withoutRenderer} ohne Renderer. Was getroffen wurde:")); List> list = new List>(Seen); list.Sort((KeyValuePair a, KeyValuePair b) => b.Value.CompareTo(a.Value)); for (int num = 0; num < list.Count && num < 20; num++) { Plugin.Log.LogInfo((object)string.Format("{0} {1,6}x {2}", "[FinalAscent]", list[num].Value, list[num].Key)); } Seen.Clear(); _total = 0; _withoutRenderer = 0; _withoutCollider = 0; } } [HarmonyPatch(typeof(PSM_ReplaceMaterialWithRayTargetMaterial), "ModifyObject")] internal static class FinalAscentRayTargetMaterialProbe { private const string Tag = "[FinalAscent]"; private static readonly Dictionary Seen = new Dictionary(); private static int _total; private static void Prefix(SpawnData spawnData) { if (FinalAscent.Active) { _total++; Transform transform = ((RaycastHit)(ref spawnData.hit)).transform; if (!((Object)(object)transform == (Object)null)) { MeshRenderer componentInChildren = ((Component)transform).GetComponentInChildren(); Material val = (((Object)(object)componentInChildren != (Object)null) ? ((Renderer)componentInChildren).sharedMaterial : null); string key = (((Object)(object)val != (Object)null) ? ((Object)val).name : "(keins)") + " auf " + ((Object)transform).name; Seen.TryGetValue(key, out var value); Seen[key] = value + 1; } } } internal static void Report() { if (_total != 0) { Plugin.Log.LogInfo((object)(string.Format("{0} PSM_ReplaceMaterialWithRayTargetMaterial: {1} Faelle. ", "[FinalAscent]", _total) + "Was getroffen wurde:")); List> list = new List>(Seen); list.Sort((KeyValuePair a, KeyValuePair b) => b.Value.CompareTo(a.Value)); for (int num = 0; num < list.Count && num < 15; num++) { Plugin.Log.LogInfo((object)string.Format("{0} {1,6}x {2}", "[FinalAscent]", list[num].Value, list[num].Key)); } Seen.Clear(); _total = 0; } } } internal static class FinalAscentMode { private const int LastRegularAscent = 8; private static readonly MethodInfo UpdateAscentMethod = AccessTools.Method(typeof(BoardingPass), "UpdateAscent", (Type[])null, (Type[])null); internal static int HighestOffered() { int num = (((Object)(object)Singleton.Instance != (Object)null) ? Singleton.Instance.GetMaxAscent() : 0); return Mathf.Min(8, num); } internal static void Refresh(BoardingPass pass) { UpdateAscentMethod?.Invoke(pass, null); } internal static bool IsChosen(BoardingPass pass) { if ((Object)(object)pass != (Object)null && pass.ascentIndex == 1337) { return !RunSettings.IsCustomRun; } return false; } } [HarmonyPatch(typeof(BoardingPass), "UpdateAscent")] internal static class FinalAscentBoardingPassPatch { private static bool Prefix(BoardingPass __instance) { if (__instance.ascentIndex != 1337) { return true; } if (RunSettings.IsCustomRun) { __instance.ascentIndex = FinalAscentMode.HighestOffered(); FinalAscentTerrainRandomiser.ComeBack(); return true; } Describe(__instance); return false; } private static void Postfix(BoardingPass __instance) { if (!RunSettings.IsCustomRun && __instance.ascentIndex != 1337 && __instance.ascentIndex >= FinalAscentMode.HighestOffered()) { ((Selectable)__instance.incrementAscentButton).interactable = true; } } private static void Describe(BoardingPass pass) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (FinalAscentText.Changed()) { FinalAscentText.Load(); } pass.ascentTitle.text = FinalAscentText.Get("mode.title"); ((Graphic)pass.ascentTitle).color = FinalAscentUiKit.Accent; pass.ascentDesc.text = FinalAscentText.Get("mode.desc"); pass.reward.gameObject.SetActive(false); ((Component)pass.customOptionsButton).gameObject.SetActive(false); ((Selectable)pass.incrementAscentButton).interactable = false; ((Selectable)pass.decrementAscentButton).interactable = true; FinalAscentTerrainRandomiser.StepAside(); } } [HarmonyPatch(typeof(BoardingPass), "IncrementAscent")] internal static class FinalAscentIncrementPatch { private static bool Prefix(BoardingPass __instance) { if (RunSettings.IsCustomRun || __instance.ascentIndex < FinalAscentMode.HighestOffered()) { return true; } __instance.ascentIndex = 1337; FinalAscentMode.Refresh(__instance); return false; } } [HarmonyPatch(typeof(BoardingPass), "DecrementAscent")] internal static class FinalAscentDecrementPatch { private static bool Prefix(BoardingPass __instance) { if (__instance.ascentIndex != 1337) { return true; } __instance.ascentIndex = FinalAscentMode.HighestOffered(); FinalAscentTerrainRandomiser.ComeBack(); FinalAscentMode.Refresh(__instance); return false; } } [HarmonyPatch(typeof(BoardingPass), "StartGame")] internal static class FinalAscentStartGamePatch { [HarmonyPriority(800)] private static bool Prefix(BoardingPass __instance) { if (!FinalAscentMode.IsChosen(__instance)) { return true; } FinalAscentTerrainRandomiser.StepAside(); if (FinalAscentSetupWindow.Confirmed) { return true; } FinalAscentSetupWindow.Show(__instance); return false; } } internal static class FinalAscentTerrainRandomiser { private const string Tag = "[FinalAscent]"; private static bool _weTurnedItOff; private static bool _looked; private static Type _uiManagerType; private static Type _pluginType; private static void LookOnce() { if (!_looked) { _looked = true; _uiManagerType = AccessTools.TypeByName("TerrainRandomiser.RandomiserUIManager"); _pluginType = AccessTools.TypeByName("TerrainRandomiser.Plugin"); Plugin.Log.LogInfo((object)((_pluginType != null) ? "[FinalAscent] TerrainRandomiser gefunden - wird bei Final Ascent beiseitegelegt." : "[FinalAscent] Kein TerrainRandomiser installiert - nichts beiseitezulegen.")); } } internal static void StepAside() { LookOnce(); if (!(_pluginType == null) && !_weTurnedItOff) { if (!Read(out var enabled)) { Plugin.Log.LogWarning((object)"[FinalAscent] TerrainRandomiser ist da, aber sein Schalter war nicht zu lesen - er koennte am selben Berg mitdrehen."); } else if (!enabled) { Plugin.Log.LogInfo((object)"[FinalAscent] TerrainRandomiser war ohnehin aus."); _weTurnedItOff = false; } else if (Write(value: false)) { _weTurnedItOff = true; Plugin.Log.LogInfo((object)"[FinalAscent] TerrainRandomiser war an und ist jetzt aus - beide bauen denselben Berg um, und zwei Umbauten vertragen sich nicht. Beim Wechsel auf einen anderen Modus geht er wieder an."); } } } internal static void ComeBack() { if (_weTurnedItOff) { if (Write(value: true)) { Plugin.Log.LogInfo((object)"[FinalAscent] TerrainRandomiser wieder eingeschaltet."); } _weTurnedItOff = false; } } private static object Settings() { object obj = AccessTools.Field(_pluginType, "Instance")?.GetValue(null); if (obj == null) { return null; } return AccessTools.Field(_pluginType, "mapSettings")?.GetValue(obj); } private static bool Read(out bool enabled) { enabled = false; object obj = Settings(); if (obj == null) { return false; } FieldInfo fieldInfo = AccessTools.Field(obj.GetType(), "enableRandomiser"); if (fieldInfo == null) { return false; } enabled = (bool)fieldInfo.GetValue(obj); return true; } private static bool Write(bool value) { bool result = false; if (_uiManagerType != null) { Object[] array = Object.FindObjectsByType(_uiManagerType, (FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Object obj in array) { object obj2 = AccessTools.Field(_uiManagerType, "enableRandomiserToggle")?.GetValue(obj); PropertyInfo propertyInfo = obj2?.GetType().GetProperty("value"); if (propertyInfo != null) { propertyInfo.SetValue(obj2, value); result = true; } } } object obj3 = Settings(); FieldInfo fieldInfo = ((obj3 != null) ? AccessTools.Field(obj3.GetType(), "enableRandomiser") : null); if (fieldInfo != null) { fieldInfo.SetValue(obj3, value); result = true; } return result; } } [HarmonyPatch(typeof(Looker), "Start")] internal static class FinalAscentNoLookers { private const string Tag = "[FinalAscent]"; private static int _silenced; private static void Postfix(Looker __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.guy == (Object)null)) { ((Component)__instance).gameObject.SetActive(false); _silenced++; if (_silenced == 1) { Plugin.Log.LogInfo((object)"[FinalAscent] Beobachter werden abgeschaltet - Stein und Pfadfinder, so wie es RPCA_DisableLooker auch tut."); } } } internal static void SilenceAll() { int num = 0; Looker[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Looker val in array) { if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(false); num++; } } Plugin.Log.LogInfo((object)(string.Format("{0} Beobachter still: {1} Steine nachtraeglich abgeraeumt ", "[FinalAscent]", num) + $"({_silenced} liefen schon ueber den Patch).")); } } internal static class FinalAscentPaint { private const string Tag = "[FinalAscent]"; private static readonly Dictionary Before = new Dictionary(); private static readonly List>>> Changed = new List>>>(); private static Dictionary _shelf; private static int _painted; private static int _missing; private static readonly HashSet Unknown = new HashSet(); internal static void Reset() { Before.Clear(); Changed.Clear(); _shelf = null; } internal static void Snapshot() { Before.Clear(); Changed.Clear(); MeshRenderer[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (MeshRenderer val in array) { if (!((Object)(object)val == (Object)null)) { Before[(Renderer)(object)val] = ((Renderer)val).sharedMaterials; } } Plugin.Detail(string.Format("{0} Anstrich: {1} Renderer vor den Schritten fotografiert.", "[FinalAscent]", Before.Count)); } private static Dictionary> PrefabPaint() { Dictionary> dictionary = new Dictionary>(); PropSpawner[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (PropSpawner val in array) { if ((Object)(object)val == (Object)null || val.props == null) { continue; } GameObject[] props = val.props; foreach (GameObject val2 in props) { if ((Object)(object)val2 == (Object)null || dictionary.ContainsKey(((Object)val2).name)) { continue; } HashSet hashSet = new HashSet(); Renderer[] componentsInChildren = val2.GetComponentsInChildren(true); foreach (Renderer val3 in componentsInChildren) { if ((Object)(object)val3 == (Object)null) { continue; } Material[] sharedMaterials = val3.sharedMaterials; foreach (Material val4 in sharedMaterials) { if ((Object)(object)val4 != (Object)null) { hashSet.Add(Bare(val4)); } } } dictionary[((Object)val2).name] = hashSet; } } return dictionary; } private static string CloneRootName(Transform leaf) { Transform val = leaf; while ((Object)(object)val != (Object)null) { if (((Object)val).name.EndsWith("(Clone)")) { return ((Object)val).name.Substring(0, ((Object)val).name.Length - 7); } val = val.parent; } return null; } internal static void Collect() { Changed.Clear(); if (Before.Count == 0) { return; } Dictionary> dictionary = PrefabPaint(); int num = 0; int num2 = 0; MeshRenderer[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (MeshRenderer val in array) { if ((Object)(object)val == (Object)null || Before.ContainsKey((Renderer)(object)val)) { continue; } string text = CloneRootName(((Component)val).transform); if (text == null || !dictionary.TryGetValue(text, out var value) || value.Count == 0) { continue; } Material[] sharedMaterials = ((Renderer)val).sharedMaterials; List> list = null; for (int j = 0; j < sharedMaterials.Length; j++) { if ((Object)(object)sharedMaterials[j] == (Object)null) { continue; } string text2 = Bare(sharedMaterials[j]); if (!value.Contains(text2) && text2.IndexOf("Colorblind", StringComparison.OrdinalIgnoreCase) < 0) { if (list == null) { list = new List>(2); } list.Add(new KeyValuePair(j, text2)); num++; } } if (list != null) { num2++; Changed.Add(new KeyValuePair>>(FinalAscentDelivery.ScenePathOf(((Component)val).transform), list)); } } Plugin.Log.LogInfo((object)(string.Format("{0} Anstrich an Requisiten: {1} Renderer tragen ein Material, ", "[FinalAscent]", num2) + $"das ihre Vorlage nicht kennt ({dictionary.Count} Vorlagen geprueft).")); foreach (KeyValuePair item in Before) { Renderer key = item.Key; if ((Object)(object)key == (Object)null) { continue; } Material[] value2 = item.Value; Material[] sharedMaterials2 = key.sharedMaterials; List> list2 = null; int num3 = Mathf.Min((value2 != null) ? value2.Length : 0, (sharedMaterials2 != null) ? sharedMaterials2.Length : 0); for (int k = 0; k < num3; k++) { if (!((Object)(object)value2[k] == (Object)(object)sharedMaterials2[k]) && !((Object)(object)sharedMaterials2[k] == (Object)null) && ((Object)sharedMaterials2[k]).name.IndexOf("Colorblind", StringComparison.OrdinalIgnoreCase) < 0 && (!((Object)(object)value2[k] != (Object)null) || ((Object)value2[k]).name.IndexOf("Colorblind", StringComparison.OrdinalIgnoreCase) < 0) && !(Bare(value2[k]) == Bare(sharedMaterials2[k]))) { if (list2 == null) { list2 = new List>(2); } list2.Add(new KeyValuePair(k, Bare(sharedMaterials2[k]))); num++; } } if (list2 != null) { Changed.Add(new KeyValuePair>>(FinalAscentDelivery.ScenePathOf(((Component)key).transform), list2)); } } Before.Clear(); Plugin.Log.LogInfo((object)(string.Format("{0} Anstrich der Fassungen: {1} Renderer mit {2} ", "[FinalAscent]", Changed.Count, num) + "geaenderten Materialien - die reisen ab jetzt im Inselpaket mit. Ohne sie behaelt der Gast die Standardfarben, weil die Material-Schritte nur beim Host laufen.")); } internal static int Pack(StringBuilder text) { foreach (KeyValuePair>> item in Changed) { text.Append('%').Append(item.Key); foreach (KeyValuePair item2 in item.Value) { text.Append('|').Append(item2.Key).Append(':') .Append(Safe(item2.Value)); } text.Append('\n'); } return Changed.Count; } private static string Bare(Material one) { if (!((Object)(object)one == (Object)null)) { return ((Object)one).name.Replace(" (Instance)", string.Empty); } return "-"; } private static string Safe(string name) { if (string.IsNullOrEmpty(name)) { return "-"; } return name.Replace('|', '_').Replace(':', '_').Replace('\n', ' '); } internal static void ProbeVariantPrefabs() { string[] array = new string[5] { "Jungle_Willow_Big", "Jungle_PalmTree_Crook", "berrybush Variant", "Jungle_Thorns", "RockFinal" }; Plugin.Log.LogWarning((object)("[FinalAscent] VORLAGEN-PROBE (Rolle: " + (PhotonNetwork.IsMasterClient ? "HOST" : "GAST") + ")")); PropSpawner[] array2 = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (PropSpawner val in array2) { if ((Object)(object)val == (Object)null || val.props == null) { continue; } GameObject[] props = val.props; foreach (GameObject val2 in props) { if ((Object)(object)val2 == (Object)null) { continue; } bool flag = false; string[] array3 = array; foreach (string text in array3) { if (((Object)val2).name == text) { flag = true; break; } } if (flag) { string text2 = "-"; Renderer componentInChildren = val2.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.sharedMaterial != (Object)null) { text2 = Bare(componentInChildren.sharedMaterial); } Plugin.Log.LogWarning((object)("[FinalAscent] '" + ((Object)val2).name + "' -> Material '" + text2 + "', Spawner " + FinalAscentDelivery.ScenePathOf(((Component)val).transform))); } } } } internal static void BeginApply() { _painted = 0; _missing = 0; Unknown.Clear(); _shelf = null; } internal static void ApplyLine(string line) { string[] array = line.Split('|'); if (array.Length < 2) { return; } Transform val = FinalAscentDelivery.FindByPathPublic(array[0]); if ((Object)(object)val == (Object)null) { _missing++; return; } Renderer component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null) { _missing++; return; } Material[] sharedMaterials = component.sharedMaterials; bool flag = false; for (int i = 1; i < array.Length; i++) { int num = array[i].IndexOf(':'); if (num > 0 && int.TryParse(array[i].Substring(0, num), out var result) && result >= 0 && result < sharedMaterials.Length) { string text = array[i].Substring(num + 1); Material val2 = Resolve(text); if ((Object)(object)val2 == (Object)null) { Unknown.Add(text); } else if ((Object)(object)sharedMaterials[result] != (Object)(object)val2) { sharedMaterials[result] = val2; flag = true; } } } if (flag) { component.sharedMaterials = sharedMaterials; _painted++; } } internal static void EndApply(int lines) { if (lines != 0) { Plugin.Log.LogInfo((object)(string.Format("{0} Anstrich aus dem Image: {1} von {2} Renderern ", "[FinalAscent]", _painted, lines) + $"umgefaerbt, {_missing} nicht gefunden" + ((Unknown.Count > 0) ? string.Format(", {0} unbekannte Materialien ({1}).", Unknown.Count, string.Join(", ", new List(Unknown).ToArray(), 0, Mathf.Min(4, Unknown.Count))) : "."))); if (Unknown.Count > 0) { Plugin.Log.LogWarning((object)"[FinalAscent] Unbekannte Materialien heissen: der Host hat etwas zugewiesen, das in dieser Szene nirgends vorkommt. Dann fehlt dem Verzeichnis eine Quelle - nachzusehen in FinalAscentPaint.Shelf()."); } } } private static Material Resolve(string name) { if (_shelf == null) { _shelf = Shelf(); } if (_shelf.TryGetValue(name, out var value)) { return value; } if (!_shelf.TryGetValue(name + " (Instance)", out var value2)) { return null; } return value2; } private static Dictionary Shelf() { Dictionary dictionary = new Dictionary(); int num = 0; ChildMaterialSwapper[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); Material[] mats; foreach (ChildMaterialSwapper val in array) { if ((Object)(object)val == (Object)null || val.themes == null) { continue; } foreach (ThemeWithRarity theme in val.themes) { if (theme == null || theme.mats == null) { continue; } num++; mats = theme.mats; foreach (Material val2 in mats) { if ((Object)(object)val2 != (Object)null && !dictionary.ContainsKey(((Object)val2).name)) { dictionary[((Object)val2).name] = val2; } } } } int num2 = 0; RockMaterialSwapper[] array2 = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (RockMaterialSwapper val3 in array2) { if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3.mat == (Object)null)) { num2++; if (!dictionary.ContainsKey(((Object)val3.mat).name)) { dictionary[((Object)val3.mat).name] = val3.mat; } string key = Bare(val3.mat); if (!dictionary.ContainsKey(key)) { dictionary[key] = val3.mat; } } } int num3 = 0; MeshRenderer[] array3 = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (MeshRenderer val4 in array3) { if ((Object)(object)val4 == (Object)null) { continue; } mats = ((Renderer)val4).sharedMaterials; foreach (Material val5 in mats) { if (!((Object)(object)val5 == (Object)null)) { if (!dictionary.ContainsKey(((Object)val5).name)) { dictionary[((Object)val5).name] = val5; num3++; } string key2 = Bare(val5); if (!dictionary.ContainsKey(key2)) { dictionary[key2] = val5; } } } } int num4 = 0; mats = Resources.FindObjectsOfTypeAll(); foreach (Material val6 in mats) { if (!((Object)(object)val6 == (Object)null)) { string key3 = Bare(val6); if (!dictionary.ContainsKey(((Object)val6).name)) { dictionary[((Object)val6).name] = val6; num4++; } if (!dictionary.ContainsKey(key3)) { dictionary[key3] = val6; } } } Plugin.Detail(string.Format("{0} Materialverzeichnis: {1} Namen ({2} Themen ", "[FinalAscent]", dictionary.Count, num) + $"durchgesehen, {num2} Gesteinsfaerber, {num3} aus verbauten " + $"Renderern, {num4} weitere aus dem Speicher)."); return dictionary; } } internal sealed class FinalAscentPetrifySun : MonoBehaviour { internal float rate = 2f; internal float amount = 0.05f; private const float Reach = 1000f; private float counter; private bool _told; private static FinalAscentPetrifySun _instance; 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_PetrifySun"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } if (!((Object)(object)_instance == (Object)null)) { _instance.counter = 0f; _instance._told = false; } } private void Update() { //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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_008c: Unknown result type (might be due to invalid IL or missing references) if (!FinalAscentPetrifySunSky.Wanted && FinalAscentPetrifySunSky.Lift <= 0f) { return; } Character localCharacter = Character.localCharacter; DayNightManager instance = DayNightManager.instance; if ((Object)(object)localCharacter == (Object)null || (Object)(object)instance == (Object)null || (Object)(object)instance.sun == (Object)null || instance.sun.intensity < 5f) { return; } Transform transform = ((Component)instance.sun).transform; RaycastHit val = HelperFunctions.LineCheck(localCharacter.Center + transform.forward * -1000f, localCharacter.Center, (LayerType)0, 0f, (QueryTriggerInteraction)1); if ((Object)(object)((RaycastHit)(ref val)).transform != (Object)null && (Object)(object)((RaycastHit)(ref val)).transform.root != (Object)(object)((Component)localCharacter).transform.root) { return; } counter += Time.deltaTime; if (counter > rate) { counter = 0f; localCharacter.refs.afflictions.AddStatus((STATUSTYPE)13, amount, false, true, true, false); if (!_told) { _told = true; Plugin.Log.LogInfo((object)($"[FinalAscent] Versteinernde Sonne wirkt: {amount * 100f:0} " + $"Punkte alle {rate:0.#}s, Tageszeit {instance.timeOfDay:0.0}, " + $"Sonnenstaerke {instance.sun.intensity:0.0}.")); } } } } [HarmonyPatch(typeof(DayNightManager), "UpdateCycle")] internal static class FinalAscentPetrifySunSky { private const float Blazing = 6f; private const float FadeSeconds = 6f; internal static bool Wanted; internal static float Lift; private static readonly Color Stone = new Color(0.6f, 0.32f, 0.95f, 1f); private static readonly Color SkyHigh = new Color(0.22f, 0.1f, 0.34f, 1f); private static readonly Color SkyMid = new Color(0.34f, 0.16f, 0.46f, 1f); private static readonly Color SkyLow = new Color(0.46f, 0.26f, 0.56f, 1f); private static readonly int TopKey = Shader.PropertyToID("SkyTopColor"); private static readonly int MidKey = Shader.PropertyToID("SkyMidColor"); private static readonly int LowKey = Shader.PropertyToID("SkyBottomColor"); private static void Prefix(DayNightManager __instance) { bool flag = Wanted && __instance.isDay >= 0.5f; Lift = Mathf.MoveTowards(Lift, flag ? 1f : 0f, Time.deltaTime / 6f); } private static void Postfix(DayNightManager __instance) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (!(Lift <= 0f) && !((Object)(object)__instance.sun == (Object)null)) { float num = Mathf.Lerp(__instance.sun.intensity, 6f, Lift); if (num > __instance.sun.intensity) { __instance.sun.intensity = num; } __instance.sun.color = Color.Lerp(__instance.sun.color, Stone, Lift); if ((Object)(object)__instance.moon != (Object)null) { __instance.moon.color = Color.Lerp(__instance.moon.color, Stone, Lift); } Shader.SetGlobalColor(TopKey, Color.Lerp(Shader.GetGlobalColor(TopKey), SkyHigh, Lift)); Shader.SetGlobalColor(MidKey, Color.Lerp(Shader.GetGlobalColor(MidKey), SkyMid, Lift)); Shader.SetGlobalColor(LowKey, Color.Lerp(Shader.GetGlobalColor(LowKey), SkyLow, Lift)); } } } internal static class FinalAscentPointer { private const string Tag = "[FinalAscent]"; private static Vector3 eyeAt; private static float eyeFov = 70f; internal static void Look() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) Camera val = Camera.main; if ((Object)(object)val == (Object)null) { Camera[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (Camera val2 in array) { if ((Object)(object)val2 != (Object)null && ((Behaviour)val2).enabled) { val = val2; break; } } } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[FinalAscent] Keine Kamera gefunden - nichts anzuvisieren."); return; } Vector3 position = ((Component)val).transform.position; Vector3 forward = ((Component)val).transform.forward; FogReport(); RaycastHit[] array2 = Physics.RaycastAll(position, forward, 800f, -1, (QueryTriggerInteraction)1); if (array2.Length == 0) { Plugin.Log.LogInfo((object)(string.Format("{0} Blickstrahl von ({1:F0} / {2:F0} / {3:F0}) ", "[FinalAscent]", position.x, position.y, position.z) + "trifft in 800 Metern nichts.")); return; } Array.Sort(array2, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); Plugin.Log.LogWarning((object)(string.Format("{0} BLICKSTRAHL von ({1:F0} / {2:F0} / {3:F0}): ", "[FinalAscent]", position.x, position.y, position.z) + $"{array2.Length} Treffer, die naechsten drei:")); for (int num = 0; num < array2.Length && num < 3; num++) { Describe(array2[num], num); } RaycastHit[] array3 = Physics.RaycastAll(position, forward, 800f, -1, (QueryTriggerInteraction)2); int num2 = 0; RaycastHit[] array4 = array3; for (int i = 0; i < array4.Length; i++) { RaycastHit val3 = array4[i]; if ((Object)(object)((RaycastHit)(ref val3)).collider != (Object)null && ((RaycastHit)(ref val3)).collider.isTrigger) { num2++; if (num2 <= 3) { Plugin.Log.LogWarning((object)(string.Format("{0} [T] DURCHLAESSIG in {1:F1}m: ", "[FinalAscent]", ((RaycastHit)(ref val3)).distance) + PathOf(((Component)((RaycastHit)(ref val3)).collider).transform))); } } } if (num2 > 3) { Plugin.Log.LogWarning((object)string.Format("{0} [T] ... und {1} weitere durchlaessige.", "[FinalAscent]", num2 - 3)); } DrawnAround(val, ((RaycastHit)(ref array2[0])).point); HardAround(((RaycastHit)(ref array2[0])).point); } private static void DrawnAround(Camera eye, Vector3 spot) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) eyeAt = ((Component)eye).transform.position; eyeFov = eye.fieldOfView; try { List list = new List(256); list.Add("# Was wird rund um den Trefferpunkt GEZEICHNET?"); list.Add("# Spalten: abstand;pfad;enabled;isVisible;ebene;lod(an|aus/stufen/groesse/Stufe=blickunabhaengig gewaehlt);mesh(ecken);material;bounds-mitte;bounds-groesse;transform-pos"); list.Add("# ACHTUNG: 'isVisible' haengt an Standort UND Blickrichtung und taugt nur zum Vergleich, wenn beide gleich schauen. 'Stufe' haengt nur am Abstand und ist immer vergleichbar; 'Stufe-' hiesse: diese Gruppe zeichnet gar nichts."); list.Add("# Auge: " + Fmt(((Component)eye).transform.position) + " Blick " + Fmt(((Component)eye).transform.forward)); list.Add("# Treffer: " + Fmt(spot)); list.Add("# Kamera: Maske 0x" + eye.cullingMask.ToString("X8") + ", Sichtweite " + eye.farClipPlane.ToString("F0", CultureInfo.InvariantCulture) + ", Sichtfeld " + eye.fieldOfView.ToString("F1", CultureInfo.InvariantCulture)); List> list2 = new List>(256); Renderer[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null)) { Transform transform = ((Component)val).transform; float num = Vector3.Distance(transform.position, spot); if (!(num > 30f)) { list2.Add(new KeyValuePair(num, Row(num, val, transform))); } } } list2.Sort((KeyValuePair a, KeyValuePair b) => a.Key.CompareTo(b.Key)); foreach (KeyValuePair item in list2) { list.Add(item.Value); } Character localCharacter = Character.localCharacter; string text = (((Object)(object)localCharacter != (Object)null) ? (localCharacter.Center.y.ToString("F0", CultureInfo.InvariantCulture) + "m") : "unbekannt"); string text2 = "TrueFinalAscent.Blick." + text + ".txt"; File.WriteAllLines(FinalAscentStore.Note(text2), list); int num2 = 0; foreach (KeyValuePair item2 in list2) { if (item2.Value.Contains(";ja;ja;")) { num2++; } } Plugin.Log.LogWarning((object)("[FinalAscent] GEZEICHNET im Umkreis von " + 30f.ToString("F0") + "m: " + list2.Count + " Renderer, davon " + num2 + " wirklich im Bild und " + (list2.Count - num2) + " nicht (" + text2 + ").")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Zeichen-Bericht misslungen: " + ex.Message)); } } private static void HardAround(Vector3 spot) { //IL_0032: 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) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) try { List list = new List(256); list.Add("# Was ist rund um den Trefferpunkt HART - und sieht man es?"); list.Add("# Spalten: abstand;pfad;aktiv;an;durchlaessig;ebene;gestalt;zeichnet;mitte;groesse"); list.Add("# 'durchlaessig=ja' meldet nur und haelt niemanden auf. 'zeichnet=nichts' heisst: an diesem Objekt und darunter ist kein eingeschalteter Renderer. Beides zusammen - fest und nichts gezeichnet - ist eine unsichtbare Wand."); list.Add("# Treffer: " + Fmt(spot)); List> list2 = new List>(256); Collider[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Collider val in array) { if (!((Object)(object)val == (Object)null)) { Transform transform = ((Component)val).transform; Vector3 val2; try { val2 = ((val.enabled && ((Component)val).gameObject.activeInHierarchy) ? val.ClosestPointOnBounds(spot) : transform.position); } catch { val2 = transform.position; } float num = Vector3.Distance(val2, spot); if (!(num > 30f)) { list2.Add(new KeyValuePair(num, HardRow(num, val, transform))); } } } list2.Sort((KeyValuePair a, KeyValuePair b) => a.Key.CompareTo(b.Key)); foreach (KeyValuePair item in list2) { list.Add(item.Value); } Character localCharacter = Character.localCharacter; string text = (((Object)(object)localCharacter != (Object)null) ? (localCharacter.Center.y.ToString("F0", CultureInfo.InvariantCulture) + "m") : "unbekannt"); string text2 = "TrueFinalAscent.Hart." + text + ".txt"; File.WriteAllLines(FinalAscentStore.Note(text2), list); int num2 = 0; foreach (KeyValuePair item2 in list2) { if (IsWall(item2.Value)) { num2++; if (num2 <= 3) { Plugin.Log.LogWarning((object)("[FinalAscent] UNSICHTBARE WAND in " + item2.Key.ToString("F1", CultureInfo.InvariantCulture) + "m: " + item2.Value)); } } } Plugin.Log.LogWarning((object)("[FinalAscent] HART im Umkreis von " + 30f.ToString("F0") + "m: " + list2.Count + " Kollider, davon " + num2 + " fest und selbst unsichtbar (" + text2 + ").")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Hart-Bericht misslungen: " + ex.Message)); } } private static bool IsWall(string row) { string[] array = row.Split(';'); if (array.Length > 7 && array[2] == "ja" && array[3] == "ja" && array[4] == "nein") { return array[7].StartsWith("selbst=0", StringComparison.Ordinal); } return false; } private static string HardRow(float away, Collider one, Transform t) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) Vector3 v = Vector3.zero; Vector3 v2 = Vector3.zero; bool flag = false; try { if (one.enabled && ((Component)one).gameObject.activeInHierarchy) { Bounds bounds = one.bounds; v = ((Bounds)(ref bounds)).center; v2 = ((Bounds)(ref bounds)).size; flag = true; } } catch { flag = false; } return away.ToString("F1", CultureInfo.InvariantCulture) + ";" + PathOf(t) + ";" + (((Component)one).gameObject.activeInHierarchy ? "ja" : "nein") + ";" + (one.enabled ? "ja" : "nein") + ";" + (one.isTrigger ? "ja" : "nein") + ";" + Safe(LayerMask.LayerToName(((Component)one).gameObject.layer)) + ";" + Safe(ShapeOfCollider(one)) + ";" + Safe(DrawnBy(t)) + ";" + (flag ? Fmt(v) : "-") + ";" + (flag ? Fmt(v2) : "-"); } private static string ShapeOfCollider(Collider one) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) try { MeshCollider val = (MeshCollider)(object)((one is MeshCollider) ? one : null); if (val != null) { Mesh sharedMesh = val.sharedMesh; return "Mesh:" + (((Object)(object)sharedMesh == (Object)null) ? "LEER" : (((Object)sharedMesh).name + "/" + sharedMesh.vertexCount)) + (val.convex ? "/konvex" : ""); } BoxCollider val2 = (BoxCollider)(object)((one is BoxCollider) ? one : null); if (val2 != null) { return "Box:" + Fmt(val2.size); } SphereCollider val3 = (SphereCollider)(object)((one is SphereCollider) ? one : null); if (val3 != null) { return "Kugel:" + val3.radius.ToString("F2", CultureInfo.InvariantCulture); } CapsuleCollider val4 = (CapsuleCollider)(object)((one is CapsuleCollider) ? one : null); if (val4 != null) { return "Kapsel:" + val4.radius.ToString("F2", CultureInfo.InvariantCulture) + "/" + val4.height.ToString("F2", CultureInfo.InvariantCulture); } return ((object)one).GetType().Name; } catch { return "unlesbar"; } } private static string DrawnBy(Transform t) { try { int num = Count(t); int num2 = Count(((Object)(object)t.parent != (Object)null) ? t.parent : t) - num; return "selbst=" + num + "/umfeld=" + ((num2 >= 0) ? num2 : 0); } catch { return "unlesbar"; } } private static int Count(Transform where) { int num = 0; Renderer[] componentsInChildren = ((Component)where).GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.enabled && ((Component)val).gameObject.activeInHierarchy) { num++; } } return num; } private static string LevelFor(LODGroup group, Vector3 from, float fov) { //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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) try { LOD[] lODs = group.GetLODs(); if (lODs == null || lODs.Length == 0) { return "?"; } Transform transform = ((Component)group).transform; Vector3 val = transform.TransformPoint(group.localReferencePoint); float num = Mathf.Max(transform.lossyScale.x, Mathf.Max(transform.lossyScale.y, transform.lossyScale.z)) * group.size; float num2 = Vector3.Distance(from, val); if (num2 < 0.001f) { return "0"; } float num3 = num / (num2 * 2f * Mathf.Tan(fov * 0.5f * (MathF.PI / 180f))); for (int i = 0; i < lODs.Length; i++) { if (num3 >= lODs[i].screenRelativeTransitionHeight) { return i.ToString(CultureInfo.InvariantCulture); } } return "-"; } catch { return "?"; } } private static string Row(float away, Renderer one, Transform t) { //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) string name = "-"; MeshFilter component = ((Component)one).GetComponent(); if ((Object)(object)component != (Object)null) { name = (((Object)(object)component.sharedMesh != (Object)null) ? (((Object)component.sharedMesh).name + "(" + component.sharedMesh.vertexCount + ")") : "LEER"); } Material sharedMaterial = one.sharedMaterial; string text = "-"; LODGroup componentInParent = ((Component)one).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null) { text = (componentInParent.enabled ? "an" : "aus") + "/" + componentInParent.lodCount + "/" + componentInParent.size.ToString("F1", CultureInfo.InvariantCulture) + "/Stufe" + LevelFor(componentInParent, eyeAt, eyeFov); } Bounds val = default(Bounds); bool flag = false; try { val = one.bounds; flag = true; } catch { } return away.ToString("F1", CultureInfo.InvariantCulture) + ";" + PathOf(t) + ";" + (one.enabled ? "ja" : "nein") + ";" + (one.isVisible ? "ja" : "nein") + ";" + LayerMask.LayerToName(((Component)t).gameObject.layer) + ";" + text + ";" + Safe(name) + ";" + Safe(((Object)(object)sharedMaterial != (Object)null) ? ((Object)sharedMaterial).name : "-") + ";" + (flag ? Fmt(((Bounds)(ref val)).center) : "-") + ";" + (flag ? Fmt(((Bounds)(ref val)).size) : "-") + ";" + Fmt(t.position); } private static string Fmt(Vector3 v) { return v.x.ToString("F2", CultureInfo.InvariantCulture) + "," + v.y.ToString("F2", CultureInfo.InvariantCulture) + "," + v.z.ToString("F2", CultureInfo.InvariantCulture); } private static string Safe(string name) { if (!string.IsNullOrEmpty(name)) { return name.Replace(';', '_'); } return "-"; } private static void Describe(RaycastHit hit, int rank) { //IL_0062: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((RaycastHit)(ref hit)).collider == (Object)null) { return; } Transform transform = ((Component)((RaycastHit)(ref hit)).collider).transform; Plugin.Log.LogWarning((object)(string.Format("{0} [{1}] '{2}' in {3:F1}m bei ", "[FinalAscent]", rank, ((Object)transform).name, ((RaycastHit)(ref hit)).distance) + $"({((RaycastHit)(ref hit)).point.x:F1} / {((RaycastHit)(ref hit)).point.y:F1} / {((RaycastHit)(ref hit)).point.z:F1})")); Plugin.Log.LogWarning((object)("[FinalAscent] Pfad: " + PathOf(transform))); Renderer val = ((Component)transform).GetComponent() ?? ((Component)transform).GetComponentInChildren(true) ?? ((Component)transform).GetComponentInParent(); if ((Object)(object)val != (Object)null) { StringBuilder stringBuilder = new StringBuilder(); Material[] sharedMaterials = val.sharedMaterials; foreach (Material val2 in sharedMaterials) { if (stringBuilder.Length > 0) { stringBuilder.Append(", "); } stringBuilder.Append(((Object)(object)val2 != (Object)null) ? ((Object)val2).name : "(keins)"); } Plugin.Log.LogWarning((object)string.Format("{0} Material: {1} (an '{2}')", "[FinalAscent]", stringBuilder, ((Object)((Component)val).gameObject).name)); } Campfire componentInParent = ((Component)transform).GetComponentInParent(true); if ((Object)(object)componentInParent != (Object)null) { PhotonView component = ((Component)componentInParent).GetComponent(); Plugin.Log.LogWarning((object)(string.Format("{0} LAGERFEUER '{1}': Zustand {2}, ", "[FinalAscent]", ((Object)componentInParent).name, componentInParent.state) + $"Rufnummer {(((Object)(object)component != (Object)null) ? component.ViewID : 0)}, " + (((Component)componentInParent).gameObject.activeInHierarchy ? "in der Welt" : "AUS") + ".")); } Biome componentInParent2 = ((Component)transform).GetComponentInParent(true); BiomeVariant componentInParent3 = ((Component)transform).GetComponentInParent(true); VariantObject componentInParent4 = ((Component)transform).GetComponentInParent(true); Plugin.Log.LogWarning((object)("[FinalAscent] Biom: " + (((Object)(object)componentInParent2 != (Object)null) ? ((object)Unsafe.As(ref componentInParent2.biomeType)/*cast due to .constrained prefix*/).ToString() : "keins") + ", Fassung: " + (((Object)(object)componentInParent3 != (Object)null) ? ((Object)componentInParent3).name : (((Object)(object)componentInParent4 != (Object)null) ? ((Object)componentInParent4).name : "keine")))); Transform val3 = transform; while ((Object)(object)val3 != (Object)null) { if (((Object)val3).name.IndexOf("VOID", StringComparison.OrdinalIgnoreCase) >= 0) { Plugin.Log.LogWarning((object)("[FinalAscent] ES IST DAS NICHTS - haengt unter '" + ((Object)val3).name + "'.")); break; } val3 = val3.parent; } } private static void FogReport() { //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) //IL_0082: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) try { FogCutoutHandler val = Object.FindFirstObjectByType(); if ((Object)(object)val != (Object)null) { int num = ((val.cutoutZones != null) ? val.cutoutZones.Length : 0); Vector4 globalVector = Shader.GetGlobalVector("FogCutoutPosition"); Plugin.Log.LogWarning((object)(string.Format("{0} NEBEL Aufdeck-Kette: Index {1} von {2}, ", "[FinalAscent]", val.index, num) + string.Format("Amount {0:F2}, ", Shader.GetGlobalFloat("FogCutoutAmount")) + $"Position ({globalVector.x:F0} / {globalVector.y:F0} / {globalVector.z:F0}), " + string.Format("Min {0:F0} / ", Shader.GetGlobalFloat("FogCutoutMin")) + string.Format("Max {0:F0}", Shader.GetGlobalFloat("FogCutoutMax")))); if (val.cutoutZones != null) { for (int i = 0; i < val.cutoutZones.Length; i++) { FogCutoutZone val2 = val.cutoutZones[i]; if ((Object)(object)val2 == (Object)null) { Plugin.Log.LogWarning((object)string.Format("{0} Zone {1}: TOT", "[FinalAscent]", i)); continue; } Plugin.Log.LogWarning((object)(string.Format("{0} Zone {1}: '{2}' bei z={3:F0}", "[FinalAscent]", i, ((Object)val2).name, ((Component)val2).transform.position.z) + ((i == val.index - 1) ? " <- aktuell" : ""))); } } } else { Plugin.Log.LogWarning((object)"[FinalAscent] NEBEL Aufdeck-Kette: kein FogCutoutHandler."); } SpecialDayManager instance = SpecialDayManager.instance; if (!((Object)(object)instance != (Object)null) || instance.zones == null) { return; } int num2 = 0; string arg = "keiner"; SpecialDayZone[] zones = instance.zones; foreach (SpecialDayZone val3 in zones) { if ((Object)(object)val3 == (Object)null) { num2++; } else if ((Object)(object)Character.observedCharacter != (Object)null && val3.ObservedCharWithinBounds()) { arg = ((Object)val3).name; } } float num3 = (((Object)(object)AmbienceManager.instance != (Object)null) ? AmbienceManager.instance.maxFog : (-1f)); Plugin.Log.LogWarning((object)(string.Format("{0} NEBEL Atmosphaere: {1} Zonen ({2} tot), ", "[FinalAscent]", instance.zones.Length, num2) + $"Spieler in Zone '{arg}', maxFog {num3:F0}.")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Nebel-Steckbrief unvollstaendig: " + ex.Message)); } } private static string PathOf(Transform leaf) { StringBuilder stringBuilder = new StringBuilder(((Object)leaf).name); Transform parent = leaf.parent; while ((Object)(object)parent != (Object)null) { stringBuilder.Insert(0, '/').Insert(0, ((Object)parent).name); parent = parent.parent; } return stringBuilder.ToString(); } } internal sealed class FinalAscentQuake : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const float Seconds = 5f; private const float Warn = 6f; private const float WarnShake = 4.5f; private const float WarnPace = 8f; private const float WarnTick = 0.25f; private const float WarnVolume = 0.4f; private const float Rumble = 15f; private const float RumblePace = 13f; private const float Jolt = 34f; private const float JoltSeconds = 0.4f; private const float JoltPace = 22f; private const float HipShove = 1200f; private const float HipLift = 900f; private const float FootShove = 350f; private const float HeadShove = 350f; private const float WarnPitch = 1f; private const float QuakePitch = 0.7f; private const float BangPitch = 1.5f; private const float BangVolume = 1f; private const float BangHold = 0.35f; private const float BangFade = 2f; private const float CalmLeast = 20f; private const float CalmMost = 40f; private const float Volume = 1f; private float _wait; private float _warnLeft; private float _warnFull; private float _warnClock; private float _quakeFor; private float _left; private float _full; private int _seed; private float _bangLeft; private AudioSource _voice; private AudioSource _bang; private static FinalAscentQuake _instance; private static AudioClip _clip; private static bool _searched; private bool _on; private static readonly string[] Wishes = new string[3] { "Au_Earth_Rumble", "Au_RumbleLoop", "Rumble" }; private static void Wake() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("FA_Quake"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } } internal static void Run(bool on) { if (on) { Wake(); } if (!((Object)(object)_instance == (Object)null)) { _instance._on = on; if (on) { _instance._wait = 1f; } else { _instance.Hush(); } } } private void Update() { Boom(); if (_warnLeft > 0f) { Coming(); } else { Fade(); } if (!_on || !PhotonNetwork.IsMasterClient) { return; } _wait -= Time.deltaTime; if (!(_wait > 0f)) { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || localCharacter.refs == null || (Object)(object)localCharacter.refs.view == (Object)null) { _wait = 1f; return; } _wait = 11f + Random.Range(20f, 40f); localCharacter.refs.view.RPC("RPC_FinalAscentQuake", (RpcTarget)0, new object[3] { 6f, 5f, Random.Range(int.MinValue, int.MaxValue) }); } } internal static void Strike(float warn, float seconds, int seed) { Wake(); if (!((Object)(object)_instance == (Object)null)) { _instance.Herald(warn, seconds, seed); } } private void Herald(float warn, float seconds, int seed) { _seed = seed; _quakeFor = Mathf.Max(seconds, 0.1f); _warnFull = Mathf.Max(warn, 0f); _warnLeft = _warnFull; _warnClock = 0f; _left = 0f; Roar(_warnFull + _quakeFor); if (_warnLeft <= 0f) { Burst(); } } private void Coming() { _warnLeft -= Time.deltaTime; float num = 1f - Mathf.Clamp01(_warnLeft / _warnFull); if ((Object)(object)_voice != (Object)null) { _voice.volume = 0.4f * num; } _warnClock -= Time.deltaTime; if (_warnClock <= 0f) { _warnClock = 0.25f; GamefeelHandler instance = GamefeelHandler.instance; if ((Object)(object)instance != (Object)null) { instance.AddPerlinShake(4.5f * num, 0.4f, 8f); } } if (_warnLeft <= 0f) { Burst(); } } private void Burst() { _warnLeft = 0f; _full = Mathf.Max(_quakeFor, 0.1f); _left = _full; GamefeelHandler instance = GamefeelHandler.instance; if ((Object)(object)instance != (Object)null) { instance.AddPerlinShake(34f, 0.4f, 22f); instance.AddPerlinShake(15f, _full, 13f); } if ((Object)(object)_voice != (Object)null) { _voice.pitch = 0.7f; _voice.volume = 1f; } Bang(); Floor(_full); ((MonoBehaviour)this).StartCoroutine(Thrown()); Empty(); } private IEnumerator Thrown() { yield return (object)new WaitForFixedUpdate(); Toss(); } private void Bang() { AudioClip val = Clip(); if (!((Object)(object)val == (Object)null)) { if ((Object)(object)_bang == (Object)null) { _bang = ((Component)this).gameObject.AddComponent(); _bang.spatialBlend = 0f; _bang.loop = false; _bang.outputAudioMixerGroup = FinalAscentLarder.Bus(); } _bang.clip = val; _bang.pitch = 1.5f; _bang.volume = 1f; _bang.time = 0f; _bang.Play(); _bangLeft = 2.35f; } } private void Boom() { if (_bangLeft <= 0f) { return; } _bangLeft -= Time.deltaTime; if (!((Object)(object)_bang == (Object)null)) { if (_bangLeft <= 0f) { _bang.Stop(); } else { _bang.volume = 1f * Mathf.Clamp01(_bangLeft / 2f); } } } private void Toss() { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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_013c: Unknown result type (might be due to invalid IL or missing references) List allPlayerCharacters = PlayerHandler.GetAllPlayerCharacters(); Vector3 val2 = default(Vector3); 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.refs != null && !((Object)(object)val.refs.ragdoll == (Object)null)) { int id = (((Object)(object)val.refs.view != (Object)null) ? val.refs.view.ViewID : ((Object)val).GetInstanceID()); float num = Spin(_seed, id); ((Vector3)(ref val2))..ctor(Mathf.Cos(num), 0f, Mathf.Sin(num)); Push(val, (BodypartType)0, val2 * 1200f + Vector3.up * 900f); Push(val, (BodypartType)13, (val2 + Vector3.up * 0.5f) * 350f); Push(val, (BodypartType)16, (val2 + Vector3.up * 0.5f) * 350f); Push(val, (BodypartType)4, -val2 * 350f); } } } private static void Push(Character who, BodypartType part, Vector3 force) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (who.refs.ragdoll.partDict.TryGetValue(part, out var value) && !((Object)(object)value == (Object)null) && !((Object)(object)value.Rig == (Object)null)) { value.Rig.AddForce(force, (ForceMode)1); } } private static float Spin(int seed, int id) { int num = seed * 486187739 + id; int num2 = (num ^ (num >> 13)) * 1274126177; return (float)((num2 ^ (num2 >> 16)) & 0xFFFFFF) / 16777216f * MathF.PI * 2f; } private static void Floor(float seconds) { List allPlayerCharacters = PlayerHandler.GetAllPlayerCharacters(); 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.RPCA_Fall(seconds, 0f); } } } private static void Empty() { //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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || localCharacter.refs == null || (Object)(object)localCharacter.refs.view == (Object)null || (Object)(object)localCharacter.refs.items == (Object)null || (Object)(object)localCharacter.player == (Object)null || !localCharacter.refs.view.IsMine || localCharacter.data.dead || localCharacter.data.fullyPassedOut) { return; } Optionable currentSelectedSlot = localCharacter.refs.items.currentSelectedSlot; if (currentSelectedSlot.IsSome && !((Object)(object)localCharacter.data.currentItem == (Object)null)) { ItemSlot itemSlot = localCharacter.player.GetItemSlot(currentSelectedSlot.Value); if (itemSlot != null && (!((Object)(object)itemSlot.prefab != (Object)null) || itemSlot.prefab.UIData.canDrop)) { localCharacter.refs.view.RPC("DropItemRpc", (RpcTarget)0, new object[7] { 0f, currentSelectedSlot.Value, ((Component)localCharacter.data.currentItem).transform.position, Vector3.zero, ((Component)localCharacter.data.currentItem).transform.rotation, itemSlot.data, false }); localCharacter.refs.items.EquipSlot(Optionable.None); } } } private void Roar(float total) { AudioClip val = Clip(); if (!((Object)(object)val == (Object)null)) { if ((Object)(object)_voice == (Object)null) { _voice = ((Component)this).gameObject.AddComponent(); _voice.spatialBlend = 0f; _voice.outputAudioMixerGroup = FinalAscentLarder.Bus(); } _voice.clip = val; _voice.loop = val.length < total; _voice.pitch = 1f; _voice.volume = 0f; _voice.time = 0f; _voice.Play(); } } private void Fade() { if (_left <= 0f) { return; } _left -= Time.deltaTime; if (!((Object)(object)_voice == (Object)null)) { if (_left <= 0f) { _voice.Stop(); } else { _voice.volume = 1f * (_left / _full); } } } private void Hush() { _left = 0f; _warnLeft = 0f; _bangLeft = 0f; if ((Object)(object)_voice != (Object)null && _voice.isPlaying) { _voice.Stop(); } if ((Object)(object)_bang != (Object)null && _bang.isPlaying) { _bang.Stop(); } } private static AudioClip Clip() { if ((Object)(object)_clip != (Object)null || _searched) { return _clip; } _searched = true; for (int i = 0; i < Wishes.Length; i++) { _clip = FinalAscentLarder.Sound(Wishes[i]); if ((Object)(object)_clip != (Object)null) { Plugin.Log.LogInfo((object)(string.Format("{0} Erdbeben: Grollen '{1}' ({2:0.0}s) ", "[FinalAscent]", ((Object)_clip).name, _clip.length) + "uebernommen.")); return _clip; } } Plugin.Log.LogWarning((object)"[FinalAscent] Erdbeben: kein Grollen gefunden - es bebt stumm."); return null; } } public class FinalAscentQuakeSync : MonoBehaviour { [PunRPC] public void RPC_FinalAscentQuake(float warn, float seconds, int seed) { FinalAscentQuake.Strike(warn, seconds, seed); } } [HarmonyPatch(typeof(Character), "Awake")] internal static class FinalAscentQuakeAttach { private static void Postfix(Character __instance) { PhotonView componentInParent = ((Component)__instance).GetComponentInParent(); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)((Component)componentInParent).GetComponent() != (Object)null)) { ((Component)componentInParent).gameObject.AddComponent(); componentInParent.RefreshRpcMonoBehaviourCache(); } } } [HarmonyPatch(typeof(DayNightManager), "UpdateCycle")] internal static class FinalAscentRainMood { private static readonly int SkyTop = Shader.PropertyToID("SkyTopColor"); private static readonly int SkyMid = Shader.PropertyToID("SkyMidColor"); private static readonly int SkyLow = Shader.PropertyToID("SkyBottomColor"); private static float _lastTold; private const float Rest = 0.08f; private const float Shade = 0.55f; private const float ColourTaken = 0.85f; private static void Postfix(DayNightManager __instance) { //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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_004e: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) float moodStrength = FinalAscentWindStorm.MoodStrength; if (moodStrength <= 0f) { FinalAscentSkyBodies.Fade(__instance, 0f); return; } Color globalColor = Shader.GetGlobalColor(SkyTop); Color globalColor2 = Shader.GetGlobalColor(SkyMid); Color globalColor3 = Shader.GetGlobalColor(SkyLow); Color val = Deck(globalColor, globalColor2, globalColor3); Shader.SetGlobalColor(SkyTop, Color.Lerp(globalColor, val, moodStrength)); Shader.SetGlobalColor(SkyMid, Color.Lerp(globalColor2, val, moodStrength)); Shader.SetGlobalColor(SkyLow, Color.Lerp(globalColor3, val, moodStrength)); Dim(__instance.sun, moodStrength); Dim(__instance.moon, moodStrength); FinalAscentSkyBodies.Fade(__instance, moodStrength); if (!(Time.unscaledTime - _lastTold < 2f)) { _lastTold = Time.unscaledTime; Plugin.Log.LogInfo((object)($"[FinalAscent] Regenstimmung: Staerke {moodStrength:0.00} | Tagesanteil " + $"{Mathf.Clamp01(__instance.dayNightBlend):0.00} | Uhr " + $"{__instance.timeOfDay:0.0} | Decke {val} | Sonne " + $"{(((Object)(object)__instance.sun != (Object)null) ? __instance.sun.intensity : (-1f)):0.000} | Mond " + $"{(((Object)(object)__instance.moon != (Object)null) ? __instance.moon.intensity : (-1f)):0.000} | " + $"Spritzer {FinalAscentRainVisual.SplashCount} | Schrittrufe " + $"{FinalAscentRainSteps.Entered}, gespielt {FinalAscentRainSteps.Played}" + ((FinalAscentRainSteps.Why != null) ? (", zuletzt abgebrochen: " + FinalAscentRainSteps.Why) : "") + ".")); } } private static Color Deck(Color top, Color mid, Color low) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Min(((Color)(ref top)).grayscale, Mathf.Min(((Color)(ref mid)).grayscale, ((Color)(ref low)).grayscale)) * 0.55f; return new Color(num * 0.94f, num * 0.97f, num * 1.1f, top.a); } private static void Dim(Light light, float rain) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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 (!((Object)(object)light == (Object)null)) { light.intensity *= Mathf.Lerp(1f, 0.08f, rain); Color color = light.color; float grayscale = ((Color)(ref color)).grayscale; color = light.color; float grayscale2 = ((Color)(ref color)).grayscale; color = light.color; Color val = default(Color); ((Color)(ref val))..ctor(grayscale, grayscale2, ((Color)(ref color)).grayscale, light.color.a); light.color = Color.Lerp(light.color, val, 0.85f * rain); } } } [HarmonyPatch(typeof(CharacterAfflictions), "AddStatus", new Type[] { typeof(STATUSTYPE), typeof(float), typeof(bool), typeof(bool), typeof(bool), typeof(bool) })] internal static class FinalAscentRainCool { private const float Damped = 0.5f; private static void Prefix(CharacterAfflictions __instance, STATUSTYPE statusType, ref float amount) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)statusType == 8 && !(amount <= 0f) && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.character == (Object)null) && FinalAscentWindStorm.InRain(__instance.character)) { amount *= 0.5f; } } } [HarmonyPatch(typeof(StormAudio), "Update")] internal static class FinalAscentRainVolume { private static void Postfix(StormAudio __instance) { float rainStrength = FinalAscentWindStorm.RainStrength; if (!(rainStrength <= 0f) && !(rainStrength >= 1f)) { if ((Object)(object)__instance.loopRainHeavy != (Object)null) { AudioLoop loopRainHeavy = __instance.loopRainHeavy; loopRainHeavy.volume *= rainStrength; } if ((Object)(object)__instance.loopRainSoft != (Object)null) { AudioLoop loopRainSoft = __instance.loopRainSoft; loopRainSoft.volume *= rainStrength; } } } } [HarmonyPatch(typeof(FootStepPlayer), "PlayStep")] internal static class FinalAscentRainSteps { private const float Softness = 0.2f; private const float PitchSpread = 0.08f; internal static int Played; internal static int Entered; internal static string Why; private static readonly Dictionary Speakers = new Dictionary(); private static AudioSource SpeakerFor(FootStepPlayer step) { if ((Object)(object)step.audioSourceOverride != (Object)null) { return step.audioSourceOverride; } if (Speakers.TryGetValue(step, out var value) && (Object)(object)value != (Object)null) { return value; } try { AudioSource val = ((Component)step).gameObject.AddComponent(); val.playOnAwake = false; val.spatialBlend = 1f; val.rolloffMode = (AudioRolloffMode)0; val.minDistance = 1.5f; val.maxDistance = 28f; val.outputAudioMixerGroup = FinalAscentLarder.Bus(); Speakers[step] = val; Plugin.Log.LogInfo((object)"[FinalAscent] Eigene Tonquelle fuer nasse Schritte angelegt - der Schrittspieler hatte keine."); return val; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Tonquelle fuer nasse Schritte nicht baubar: " + ex.Message)); return null; } } private static void Postfix(FootStepPlayer __instance) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) Entered++; float rainStrength = FinalAscentWindStorm.RainStrength; if (rainStrength <= 0.05f) { Why = "kein Regen"; return; } if ((Object)(object)__instance.surfaceLookup == (Object)null) { Why = "kein Klangregal"; return; } SFX_Instance[] water = __instance.surfaceLookup.water; if (water == null || water.Length == 0) { Why = "kein Wasserklang im Regal"; return; } Character componentInParent = ((Component)__instance).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null) { Why = "kein Charakter darueber"; return; } if (componentInParent.data.isInWater) { Why = "steht ohnehin im Wasser"; return; } if (componentInParent.data.sinceGrounded > 0.2f) { Why = "in der Luft"; return; } if (FinalAscentWeather.Exposure(componentInParent.Center) <= 0f) { Why = "steht geschuetzt"; return; } Why = null; SFX_Instance val = water[Random.Range(0, water.Length)]; AudioClip val2 = (((Object)(object)val != (Object)null) ? val.GetClip() : null); if ((Object)(object)val2 == (Object)null) { Why = "kein Klang im Wasserregal"; return; } AudioSource val3 = SpeakerFor(__instance); if ((Object)(object)val3 == (Object)null) { Why = "keine Tonquelle baubar"; return; } val3.pitch = 1f + Random.Range(-0.08f, 0.08f); val3.PlayOneShot(val2, 0.2f * rainStrength); Played++; } } internal sealed class FinalAscentRainVisual : MonoBehaviour { private const float Ceiling = 16f; private const float Spread = 34f; private const float FullRate = 700f; private const float FallSpeed = 26f; private const float Slant = 5f; private const float SplashLife = 0.28f; internal static int SplashCount; private ParticleSystem _drops; private ParticleSystemRenderer _rend; private ParticleSystem _splash; private float _lastTold; internal static FinalAscentRainVisual Make() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown GameObject val = new GameObject("FA_RainVisual"); Object.DontDestroyOnLoad((Object)val); FinalAscentRainVisual finalAscentRainVisual = val.AddComponent(); finalAscentRainVisual.Build(); return finalAscentRainVisual; } private void Build() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) _drops = ((Component)this).gameObject.AddComponent(); _rend = ((Component)this).GetComponent(); _drops.Stop(true, (ParticleSystemStopBehavior)0); MainModule main = _drops.main; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.4f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.1f); ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.78f, 0.86f, 0.96f, 0.36f)); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).maxParticles = 3000; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).playOnAwake = false; ShapeModule shape = _drops.shape; ((ShapeModule)(ref shape)).enabled = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)5; ((ShapeModule)(ref shape)).scale = new Vector3(34f, 0.5f, 34f); ((ShapeModule)(ref shape)).position = new Vector3(0f, 16f, 0f); EmissionModule emission = _drops.emission; ((EmissionModule)(ref emission)).enabled = true; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); VelocityOverLifetimeModule velocityOverLifetime = _drops.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space = (ParticleSystemSimulationSpace)1; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y = new MinMaxCurve(-26f); _rend.renderMode = (ParticleSystemRenderMode)1; _rend.velocityScale = 0.14f; _rend.lengthScale = 2f; _rend.alignment = (ParticleSystemRenderSpace)0; ((Renderer)_rend).sharedMaterial = Borrow(out var from, new string[1] { "DropletParticle" }); ((Renderer)_rend).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)_rend).receiveShadows = false; BuildSplash(); _drops.Play(); ManualLogSource log = Plugin.Log; string[] obj = new string[6] { "[FinalAscent] Regenwerk gebaut: Material von ", from, ((Object)(object)((Renderer)_rend).sharedMaterial != (Object)null) ? (" ('" + ((Object)((Renderer)_rend).sharedMaterial).name + "')") : "", ", ", null, null }; MinMaxCurve startSize = ((MainModule)(ref main)).startSize; obj[4] = $"Tropfen {((MinMaxCurve)(ref startSize)).constant:0.###} breit, Fallgeschwindigkeit "; obj[5] = $"{26f:0.#}, bis zu {700f:0} je Sekunde."; log.LogInfo((object)string.Concat(obj)); } private void BuildSplash() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Splash"); val.transform.SetParent(((Component)this).transform, false); _splash = val.AddComponent(); ParticleSystemRenderer component = val.GetComponent(); _splash.Stop(true, (ParticleSystemStopBehavior)0); MainModule main = _splash.main; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.28f); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.7f, 2.2f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.07f, 0.15f); ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.88f, 0.94f, 1f, 0.9f)); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(1.4f); ((MainModule)(ref main)).maxParticles = 600; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).playOnAwake = false; ShapeModule shape = _splash.shape; ((ShapeModule)(ref shape)).enabled = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4; ((ShapeModule)(ref shape)).angle = 42f; ((ShapeModule)(ref shape)).radius = 0.02f; EmissionModule emission = _splash.emission; ((EmissionModule)(ref emission)).enabled = true; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); ((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1] { new Burst(0f, (short)2, (short)3) }); SizeOverLifetimeModule sizeOverLifetime = _splash.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, AnimationCurve.EaseInOut(0f, 1f, 1f, 0f)); component.renderMode = (ParticleSystemRenderMode)0; ((Renderer)component).sharedMaterial = ((Renderer)_rend).sharedMaterial; ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component).receiveShadows = false; CollisionModule collision = _drops.collision; ((CollisionModule)(ref collision)).enabled = true; ((CollisionModule)(ref collision)).type = (ParticleSystemCollisionType)1; ((CollisionModule)(ref collision)).mode = (ParticleSystemCollisionMode)0; ((CollisionModule)(ref collision)).quality = (ParticleSystemCollisionQuality)0; ((CollisionModule)(ref collision)).collidesWith = HelperFunctions.GetMask((LayerType)1); ((CollisionModule)(ref collision)).lifetimeLoss = MinMaxCurve.op_Implicit(1f); ((CollisionModule)(ref collision)).bounce = MinMaxCurve.op_Implicit(0f); ((CollisionModule)(ref collision)).dampen = MinMaxCurve.op_Implicit(1f); ((CollisionModule)(ref collision)).sendCollisionMessages = false; SubEmittersModule subEmitters = _drops.subEmitters; ((SubEmittersModule)(ref subEmitters)).enabled = true; ((SubEmittersModule)(ref subEmitters)).AddSubEmitter(_splash, (ParticleSystemSubEmitterType)1, (ParticleSystemSubEmitterProperties)0); } internal static Material Borrow(out string from, string[] wishes) { if (wishes != null) { foreach (string text in wishes) { Material val = Named(text); if ((Object)(object)val != (Object)null) { from = "Bestand '" + text + "'"; return val; } } } return BorrowMaterial(out from); } internal static Material Borrow(out string from) { return BorrowMaterial(out from); } private static Material Named(string wish) { return FinalAscentLarder.ByName(wish); } private static Material BorrowMaterial(out string from) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Expected O, but got Unknown Material val = null; string text = ""; int num = -1; StormVisual[] array = Resources.FindObjectsOfTypeAll(); Scene scene; foreach (StormVisual val2 in array) { if ((Object)(object)val2 == (Object)null) { continue; } scene = ((Component)val2).gameObject.scene; if (!((Scene)(ref scene)).IsValid() || val2.part == null) { continue; } ParticleSystem[] part = val2.part; for (int j = 0; j < part.Length; j++) { Material val3 = MaterialOf(part[j]); if (!((Object)(object)val3 == (Object)null)) { string text2 = ((Object)val3).name.ToLowerInvariant(); int num2 = 1; if (text2.Contains("wind")) { num2 = 3; } else if (text2.Contains("rain")) { num2 = 2; } else if (text2.Contains("snow")) { num2 = 0; } if (num2 > num) { num = num2; val = val3; text = "Sturm '" + ((Object)val2).name + "'"; } } } } if ((Object)(object)val != (Object)null) { from = text; return val; } ParticleSystemRenderer[] array2 = Resources.FindObjectsOfTypeAll(); foreach (ParticleSystemRenderer val4 in array2) { if (!((Object)(object)val4 == (Object)null)) { scene = ((Component)val4).gameObject.scene; if (((Scene)(ref scene)).IsValid() && !((Object)(object)((Renderer)val4).sharedMaterial == (Object)null) && !((Object)(object)((Renderer)val4).sharedMaterial.shader == (Object)null)) { from = "Teilchen '" + ((Object)val4).name + "'"; return ((Renderer)val4).sharedMaterial; } } } string[] array3 = new string[4] { "Sprites/Default", "Particles/Standard Unlit", "Legacy Shaders/Particles/Alpha Blended", "Unlit/Transparent" }; foreach (string text3 in array3) { Shader val5 = Shader.Find(text3); if ((Object)(object)val5 != (Object)null) { from = "eigenes Material (" + text3 + ")"; return new Material(val5); } } from = "KEINES"; return null; } private static Material MaterialOf(ParticleSystem part) { if ((Object)(object)part == (Object)null) { return null; } ParticleSystemRenderer component = ((Component)part).GetComponent(); if (!((Object)(object)component != (Object)null)) { return null; } return ((Renderer)component).sharedMaterial; } internal void Show(Vector3 where, Vector3 wind, float strength) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_drops == (Object)null)) { ((Component)this).transform.position = where; SplashCount = (((Object)(object)_splash != (Object)null) ? _splash.particleCount : (-1)); if (Time.unscaledTime - _lastTold >= 2f) { _lastTold = Time.unscaledTime; Plugin.Log.LogInfo((object)($"[FinalAscent] Regenwerk: {_drops.particleCount} Tropfen leben, " + $"Rate {700f * Mathf.Clamp01(strength):0}, Werkstoff " + (((Object)(object)((Renderer)_rend).sharedMaterial != (Object)null) ? ((Object)((Renderer)_rend).sharedMaterial).name : "keiner") + ", sichtbar " + (((Renderer)_rend).isVisible ? "ja" : "nein") + ", Stelle " + $"{((Component)this).transform.position}.")); } EmissionModule emission = _drops.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(700f * Mathf.Clamp01(strength)); VelocityOverLifetimeModule velocityOverLifetime = _drops.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = new MinMaxCurve(wind.x * 5f * Mathf.Clamp01(strength)); ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).z = new MinMaxCurve(wind.z * 5f * Mathf.Clamp01(strength)); } } } internal static class FinalAscentRayBatch { private const string Tag = "[FinalAscent]"; private const int BatchSize = 256; private static PropSpawner_Line _owner; private static readonly Queue _ready = new Queue(); private static int _spawners; private static int _rounds; private static int _served; private static readonly Stopwatch _casting = new Stopwatch(); internal static void Reset() { _owner = null; _ready.Clear(); _spawners = 0; _rounds = 0; _served = 0; _casting.Reset(); } internal static void Begin(LevelGenStep step) { _ready.Clear(); _owner = (PropSpawner_Line)(object)((step is PropSpawner_Line) ? step : null); if ((Object)(object)_owner != (Object)null) { _spawners++; } } internal static void End() { _owner = null; _ready.Clear(); } internal static void Report() { if (_spawners != 0) { Plugin.Log.LogInfo((object)(string.Format("{0} {1} Linien-Spawner im Voraus vermessen: {2} Runden, ", "[FinalAscent]", _spawners, _rounds) + $"{_served} Strahlen in {_casting.Elapsed.TotalSeconds:F1}s - " + "keiner davon sah die Ladung der eigenen Runde.")); } } internal static bool Serve(PropSpawner_Line line, out SpawnData data) { data = null; if ((Object)(object)line == (Object)null || (Object)(object)line != (Object)(object)_owner) { return false; } if (_ready.Count == 0) { _casting.Start(); for (int i = 0; i < 256; i++) { _ready.Enqueue(Cast(line)); } _casting.Stop(); _rounds++; } data = _ready.Dequeue(); _served++; return true; } private static SpawnData Cast(PropSpawner_Line line) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown Transform transform = ((Component)line).transform; Vector3 val = transform.position + transform.up * Mathf.Lerp(-0.5f, 0.5f, Random.value) * line.height; Vector3 val2 = Vector3.ProjectOnPlane(Random.onUnitSphere, transform.up); Vector3 normalized = ((Vector3)(ref val2)).normalized; normalized += new Vector3(Random.Range(0f - line.RayWiggle, line.RayWiggle), Random.Range(0f - line.RayWiggle, line.RayWiggle), Random.Range(0f - line.RayWiggle, line.RayWiggle)); if (!line.rayCastSpawn) { return new SpawnData { pos = val, normal = normalized, rayDir = normalized, hit = default(RaycastHit), spawnerTransform = transform }; } float num = ((Random.Range(0f, 1f) > line.castDirectionBias) ? (-1f) : 1f); RaycastHit hit = HelperFunctions.LineCheck(val + normalized * line.coreWidth, val + normalized * ((PropSpawner)line).rayLength * num, ((PropSpawner)line).layerType, 0f, (QueryTriggerInteraction)1); if (!Object.op_Implicit((Object)(object)((RaycastHit)(ref hit)).transform)) { return null; } return new SpawnData { pos = ((RaycastHit)(ref hit)).point, normal = ((RaycastHit)(ref hit)).normal, rayDir = normalized, hit = hit, spawnerTransform = transform }; } } [HarmonyPatch(typeof(PropSpawner_Line), "GetRandomPoint")] internal static class FinalAscentLineRayPatch { private static bool Prefix(PropSpawner_Line __instance, ref SpawnData __result) { if (!FinalAscent.Active) { return true; } return !FinalAscentRayBatch.Serve(__instance, out __result); } } [HarmonyPatch(typeof(EndScreen), "TimelineRoutine")] internal static class FinalAscentReportDumpPatch { private const string Tag = "[FinalAscent]"; private static void Prefix(List allCharacters) { if (!FinalAscent.Active || !Plugin.Diagnosing) { return; } Plugin.Log.LogInfo((object)(string.Format("{0} Endscreen: Modus aktiv={1}, ", "[FinalAscent]", FinalAscent.Active) + $"Gipfel={FinalAscentHeights.Summit:F0}, Obergrenze={FinalAscentHeights.Cap:F0} " + "(Vanilla waeren 1200 und 1300).")); if (allCharacters == null) { Plugin.Log.LogWarning((object)"[FinalAscent] Endscreen: keine Figuren uebergeben."); return; } foreach (Character allCharacter in allCharacters) { if (!((Object)(object)allCharacter == (Object)null) && allCharacter.refs != null && !((Object)(object)allCharacter.refs.stats == (Object)null)) { Dump(allCharacter); } } } private static void Dump(Character character) { //IL_004c: 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_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) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0263: 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_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) List timelineInfo = character.refs.stats.timelineInfo; if (timelineInfo == null || timelineInfo.Count == 0) { Plugin.Log.LogWarning((object)("[FinalAscent] Endscreen: '" + character.characterName + "' hat keinen Verlauf.")); return; } float num = 0f; int num2 = 0; TimelineInfo val; for (int i = 0; i < timelineInfo.Count; i++) { val = timelineInfo[i]; if (((TimelineInfo)(ref val)).height > num) { val = timelineInfo[i]; num = ((TimelineInfo)(ref val)).height; } val = timelineInfo[i]; if ((int)((TimelineInfo)(ref val)).Note != 0) { num2++; } } ManualLogSource log = Plugin.Log; string text = string.Format("{0} Endscreen '{1}': {2} Eintraege, ", "[FinalAscent]", character.characterName, timelineInfo.Count); object arg = num; val = timelineInfo[0]; string text2 = $"hoechster Punkt {arg:F0}, erster bei t={((TimelineInfo)(ref val)).time:F0}, "; val = timelineInfo[timelineInfo.Count - 1]; object arg2 = ((TimelineInfo)(ref val)).time; val = timelineInfo[timelineInfo.Count - 1]; log.LogInfo((object)(text + text2 + $"letzter bei t={arg2:F0} auf {((TimelineInfo)(ref val)).height:F0}, " + $"{num2} Marken.")); val = timelineInfo[0]; float time = ((TimelineInfo)(ref val)).time; val = timelineInfo[timelineInfo.Count - 1]; float num3 = ((TimelineInfo)(ref val)).time - time; if (num3 <= 0f) { num3 = 1f; } int num4 = ((timelineInfo.Count <= 120) ? 1 : (timelineInfo.Count / 120)); for (int j = 0; j < timelineInfo.Count; j += num4) { val = timelineInfo[j]; float num5 = Mathf.Clamp01((((TimelineInfo)(ref val)).time - time) / num3); val = timelineInfo[j]; float num6 = Mathf.Clamp(((TimelineInfo)(ref val)).height / FinalAscentHeights.Summit, -1.5f, 1f); ManualLogSource log2 = Plugin.Log; object[] obj = new object[4] { "[FinalAscent]", j, null, null }; val = timelineInfo[j]; obj[2] = ((TimelineInfo)(ref val)).time; val = timelineInfo[j]; obj[3] = ((TimelineInfo)(ref val)).height; string text3 = string.Format("{0} [{1,3}] t={2,6:F0}s h={3,6:F0} ", obj); string text4 = $"x={num5:F3} y={num6:F3} {timelineInfo[j].biome}"; val = timelineInfo[j]; object obj2; if ((int)((TimelineInfo)(ref val)).Note == 0) { obj2 = ""; } else { val = timelineInfo[j]; obj2 = " <" + ((object)((TimelineInfo)(ref val)).Note/*cast due to .constrained prefix*/).ToString() + ">"; } log2.LogInfo((object)(text3 + text4 + (string?)obj2)); } foreach (TimelineInfo item in timelineInfo) { TimelineInfo current = item; if ((int)((TimelineInfo)(ref current)).Note != 0) { Plugin.Log.LogInfo((object)(string.Format("{0} Marke '{1}' bei t={2:F0} ", "[FinalAscent]", ((TimelineInfo)(ref current)).Note, ((TimelineInfo)(ref current)).time) + $"auf {((TimelineInfo)(ref current)).height:F0} ({current.biome}).")); } } } } [HarmonyPatch(typeof(RespawnChest), "SpawnItems")] internal static class FinalAscentRevivePatch { private const string Tag = "[FinalAscent]"; private static readonly HashSet Hooked = new HashSet(); private static void Prefix(RespawnChest __instance) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!FinalAscent.Active || (Object)(object)__instance == (Object)null || (Object)(object)Singleton.Instance == (Object)null || (int)MapHandler.CurrentSegmentNumber <= 3) { return; } Segment currentSegmentNumber = MapHandler.CurrentSegmentNumber; __instance.SegmentNumber = currentSegmentNumber; if (Hooked.Add(__instance)) { __instance.ReviveUsed += delegate(RespawnChest statue) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected I4, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) AccessTools.Field(typeof(MapHandler), "_lastRevivedSegment")?.SetValue(Singleton.Instance, (int)statue.SegmentNumber); Plugin.Log.LogInfo((object)(string.Format("{0} An '{1}' wiederbelebt - Etappe {2} ", "[FinalAscent]", ((Object)statue).name, statue.SegmentNumber) + "verbucht. Ohne uns stuende hier 'Beach'.")); }; } } } internal static class FinalAscentRises { private const string Tag = "[FinalAscent]"; internal static void Recalibrate() { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) LavaRising[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); if (array.Length == 0) { Plugin.Log.LogInfo((object)"[FinalAscent] Keine aufsteigenden Gefahren in der Szene."); return; } LavaRising[] array2 = array; foreach (LavaRising val in array2) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.lava == (Object)null)) { float num = (float)(AccessTools.Field(typeof(LavaRising), "startHeight")?.GetValue(val) ?? ((object)0f)); float y = ((Component)val.lava).transform.position.y; AccessTools.Field(typeof(LavaRising), "startHeight")?.SetValue(val, y); float num2 = (((Object)(object)val.topTransform != (Object)null) ? val.topTransform.position.y : float.NaN); string arg = (((Object)(object)val.heightMinimumTransform != (Object)null) ? $"ab y={val.heightMinimumTransform.position.y:F0}" : "sofort (keine Hoehenschwelle)"); Plugin.Detail(string.Format("{0} {1} '{2}' in Etappe {3}: ", "[FinalAscent]", val.risingFieldType, ((Object)val).name, val.requiredSegment) + $"faehrt von {y:F0} nach {num2:F0} in {val.travelTime:F0}s, " + $"Vorlauf {val.initialWaitTime:F0}s, loest aus {arg}" + ((Mathf.Abs(num - y) > 1f) ? $" - Starthoehe war {num:F0}, neu genommen." : ".")); } } } } internal static class FinalAscentRiseSound { private const string Tag = "[FinalAscent]"; private static readonly Dictionary Detached = new Dictionary(); private static readonly HashSet Explained = new HashSet(); internal static void Remember(GameObject sound, GameObject banner) { if (!((Object)(object)sound == (Object)null) && !((Object)(object)banner == (Object)null) && !((Object)(object)sound.GetComponentInChildren(true) == (Object)null)) { Detached[sound] = banner; } } internal static void Replay(GameObject banner) { if ((Object)(object)banner == (Object)null) { return; } int num = 0; foreach (KeyValuePair item in Detached) { if ((Object)(object)item.Value != (Object)(object)banner || (Object)(object)item.Key == (Object)null) { continue; } AudioSource[] componentsInChildren = item.Key.GetComponentsInChildren(true); foreach (AudioSource val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.clip == (Object)null)) { ((Component)val).gameObject.SetActive(true); val.Stop(); val.Play(); num++; } } } if (num > 0 && Explained.Add(banner)) { Plugin.Log.LogInfo((object)("[FinalAscent] Ansage '" + ((Object)banner).name + "': Ton haengt seit dem ersten Mal nicht mehr am " + $"Banner (NoParent) - wird ab jetzt bei jedem Mal angespielt ({num} Quelle(n)).")); } } } [HarmonyPatch(typeof(NoParent), "Start")] internal static class FinalAscentNoParentPatch { private static void Prefix(NoParent __instance) { Transform parent = ((Component)__instance).transform.parent; if ((Object)(object)parent != (Object)null) { FinalAscentRiseSound.Remember(((Component)__instance).gameObject, ((Component)parent).gameObject); } } } [HarmonyPatch(typeof(GUIManager), "TheFogRises")] internal static class FinalAscentFogRisesSoundPatch { private static void Postfix(GUIManager __instance) { FinalAscentRiseSound.Replay(__instance.fogRises); } } [HarmonyPatch(typeof(GUIManager), "TheLavaRises")] internal static class FinalAscentLavaRisesSoundPatch { private static void Postfix(GUIManager __instance) { FinalAscentRiseSound.Replay(__instance.lavaRises); } } [HarmonyPatch(typeof(GUIManager), "TheGloomRises")] internal static class FinalAscentGloomRisesSoundPatch { private static void Postfix(GUIManager __instance) { FinalAscentRiseSound.Replay(__instance.gloomRises); } } [HarmonyPatch(typeof(GUIManager), "TheGhostsRise")] internal static class FinalAscentGhostsRiseSoundPatch { private static void Postfix(GUIManager __instance) { FinalAscentRiseSound.Replay(__instance.ghostsRise); } } [HarmonyPatch(typeof(RockMaterialSwapper), "Start")] internal static class FinalAscentRockPaintGate { private const string Tag = "[FinalAscent]"; private static readonly List Waiting = new List(); private static bool _replaying; private const string Placeholder = "M_SaltRock"; private static bool Prefix(RockMaterialSwapper __instance) { if (_replaying || !FinalAscent.Active || !FinalAscentBuilder.Building) { return true; } if (!Waiting.Contains(__instance)) { Waiting.Add(__instance); } return false; } internal static void PaintNow() { _replaying = true; try { int num = 0; int num2 = 0; int num3 = 0; RockMaterialSwapper[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (RockMaterialSwapper val in array) { if ((Object)(object)val == (Object)null || val.parents == null || (Object)(object)val.mat == (Object)null) { continue; } Transform[] parents = val.parents; foreach (Transform val2 in parents) { if ((Object)(object)val2 == (Object)null) { continue; } MeshRenderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren(true); foreach (MeshRenderer val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null)) { ((Renderer)val3).sharedMaterial = val.mat; num2++; } } } num++; num3 += Leftovers(val); } Plugin.Log.LogInfo((object)(string.Format("{0} Gestein eingefaerbt: {1} Faerber, {2} Renderer ", "[FinalAscent]", num, num2) + $"({Waiting.Count} davon waren waehrend des Baus faellig gewesen), " + $"dazu {num3} Nachzuegler mit der Platzhalterfarbe.")); } finally { Waiting.Clear(); _replaying = false; } } private static bool IsPlaceholder(Material mat) { if ((Object)(object)mat != (Object)null && ((Object)mat).name.StartsWith("M_SaltRock", StringComparison.Ordinal)) { return !((Object)mat).name.StartsWith("M_SaltRockX", StringComparison.Ordinal); } return false; } private static int Leftovers(RockMaterialSwapper one) { if ((Object)(object)one == (Object)null || (Object)(object)one.mat == (Object)null || IsPlaceholder(one.mat)) { return 0; } Transform val = ScopeOf(((Component)one).transform); if ((Object)(object)val == (Object)null) { return 0; } bool flag = (Object)(object)((Component)val).GetComponent() != (Object)null; int num = 0; MeshRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren(flag); foreach (MeshRenderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && IsPlaceholder(((Renderer)val2).sharedMaterial)) { ((Renderer)val2).sharedMaterial = one.mat; num++; } } if (num > 0) { Plugin.Log.LogInfo((object)(string.Format("{0} {1} Felsen unter '{2}' trugen noch ", "[FinalAscent]", num, ((Object)val).name) + "'M_SaltRock' und wurden auf '" + ((Object)one.mat).name + "' gebracht (" + (flag ? "Abgeschaltetes mitgezaehlt" : "nur Sichtbares") + ").")); } return num; } private static Transform ScopeOf(Transform from) { BiomeVariant componentInParent = ((Component)from).GetComponentInParent(true); if ((Object)(object)componentInParent != (Object)null) { return ((Component)componentInParent).transform; } Biome componentInParent2 = ((Component)from).GetComponentInParent(true); if (!((Object)(object)componentInParent2 != (Object)null)) { return null; } return ((Component)componentInParent2).transform; } } internal static class FinalAscentRoom { private const string KeyActive = "FA"; private const string KeySeed = "FAs"; private const string KeyVariants = "FAv"; private const string KeyStage = "FAe"; internal static bool JoinedLate { get; private set; } internal static int Stage { get { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return -1; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties != null && ((Dictionary)(object)customProperties).TryGetValue((object)"FAe", out object value) && value is int) { return (int)value; } return -1; } } internal static bool SaysActive { get { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return false; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; bool flag = default(bool); int num; if (customProperties != null && ((Dictionary)(object)customProperties).TryGetValue((object)"FA", out object value)) { if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } } internal static void ClearRoom(string why) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null || !PhotonNetwork.IsMasterClient || ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties == null) { return; } Hashtable val = new Hashtable(); foreach (object key in ((Dictionary)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).Keys) { string text = key as string; if (!string.IsNullOrEmpty(text) && text.StartsWith("FA")) { val[(object)text] = null; } } if (((Dictionary)(object)val).Count != 0) { PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)("[FinalAscent] Raum geleert: " + ((Dictionary)(object)val).Count + " Eigenschaften des Finalen Aufstiegs entfernt (" + why + ").")); } } internal static void Publish(int seed, string variants) { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_0110: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_00b8: Expected O, but got Unknown if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { Plugin.Log.LogWarning((object)"[FinalAscent] Kein Raum - Seed kann nicht hinterlegt werden. Nachzuegler wuerden einen anderen Berg bauen."); return; } FinalAscentDelivery.ForgetRoomPackage(seed); if (PhotonNetwork.IsMasterClient && (((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties == null || !((Dictionary)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"FAs", out object value) || !(value is int num) || num != seed)) { FinalAscentRoster.ForgetRoom(); Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"FAe", (object)(-1)); ((Dictionary)val).Add((object)"FAtomb", (object)null); ((Dictionary)val).Add((object)"FAp", (object)null); ((Dictionary)val).Add((object)"FAasc", (object)null); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)"[FinalAscent] Neuer Lauf: Etappenstand und Gruft-Schalter des vorigen aus dem Raum genommen."); } Room currentRoom2 = PhotonNetwork.CurrentRoom; Hashtable val2 = new Hashtable(); ((Dictionary)val2).Add((object)"FA", (object)true); ((Dictionary)val2).Add((object)"FAs", (object)seed); ((Dictionary)val2).Add((object)"FAv", (object)(variants ?? string.Empty)); currentRoom2.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)($"[FinalAscent] Im Raum hinterlegt: Seed {seed}, Fassungen " + (string.IsNullOrEmpty(variants) ? "zufaellig." : ("'" + variants + "'.")))); } internal static void PublishStage(int key) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0066: Expected O, but got Unknown if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null) { int stage = Stage; if (key <= stage) { Plugin.Detail($"[FinalAscent] Etappenstand {key} nicht hinterlegt - im Raum steht " + $"bereits {stage}, und es geht nur aufwaerts."); return; } Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"FAe", (object)key); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)$"[FinalAscent] Etappenstand {key} im Raum hinterlegt (vorher {stage})."); } } internal static void Adopt() { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties == null || !((Dictionary)(object)customProperties).TryGetValue((object)"FA", out object value) || !(value is bool) || !(bool)value) { return; } bool active = FinalAscent.Active; FinalAscent.Active = true; FinalAscentTerrainRandomiser.StepAside(); object value4; if (!active) { if (((Dictionary)(object)customProperties).TryGetValue((object)"FAs", out object value2) && value2 is int seed) { FinalAscent.Seed = seed; } if (((Dictionary)(object)customProperties).TryGetValue((object)"FAv", out object value3) && value3 is string text) { FinalAscentSetup.RandomVariants = string.IsNullOrEmpty(text); FinalAscentSetup.Deserialize(text); } } else if (((Dictionary)(object)customProperties).TryGetValue((object)"FAs", out value4) && value4 is int num && num != FinalAscent.Seed) { Plugin.Log.LogInfo((object)($"[FinalAscent] Im Raum steht noch Seed {num}, hier laeuft " + $"{FinalAscent.Seed} - der eigene gilt. (Die Raum-Eigenschaft " + "kommt gleich nach.)")); } if (!active) { JoinedLate = true; Plugin.Log.LogInfo((object)("[FinalAscent] Aus dem Raum uebernommen: Finaler Aufstieg mit Seed " + $"{FinalAscent.Seed}. (Nachzuegler - der Startbefehl kam vor unserem Beitritt.)")); } } } internal static class FinalAscentRoster { private const string Tag = "[FinalAscent]"; private const string Key = "FA_R"; private static Coroutine _ticker; private static readonly Dictionary _published = new Dictionary(); private static readonly Dictionary _noted = new Dictionary(); private static string _latched; private static bool _latchedSet; internal static void Begin() { if (_ticker == null && !((Object)(object)Plugin.Instance == (Object)null)) { _ticker = ((MonoBehaviour)Plugin.Instance).StartCoroutine(Tick()); FinalAscentLeaveWatch.Begin(); Plugin.Log.LogInfo((object)"[FinalAscent] Melderegister laeuft (Sekundentakt, nur der Master schreibt)."); } } private static IEnumerator Tick() { WaitForSecondsRealtime beat = new WaitForSecondsRealtime(0.25f); float since = 0f; while (true) { yield return beat; since += 0.25f; try { Remember(); if (since >= 30f) { since = 0f; Publish(); } } catch (Exception ex) { Plugin.Detail("[FinalAscent] Melderegister-Takt gestolpert: " + ex.Message); } } } private static void Remember() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if (!FinalAscent.Active || !PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient || FinalAscentBuilder.Building) { return; } foreach (Character allPlayerCharacter in PlayerHandler.GetAllPlayerCharacters()) { Player val = (((Object)(object)allPlayerCharacter != (Object)null && (Object)(object)((MonoBehaviourPun)allPlayerCharacter).photonView != (Object)null) ? ((MonoBehaviourPun)allPlayerCharacter).photonView.Owner : null); if (val == null) { continue; } Vector3 center = allPlayerCharacter.Center; bool flag = (Object)(object)allPlayerCharacter.data != (Object)null && (allPlayerCharacter.data.dead || allPlayerCharacter.data.fullyPassedOut); string value = string.Format(CultureInfo.InvariantCulture, "{0:F1}|{1:F1}|{2:F1}|{3}|{4}", center.x, center.y, center.z, flag ? 1 : 0, FinalAscentRoom.Stage); foreach (string item in KeysOf(val)) { _noted[item] = value; } } } internal static void Flush() { try { Remember(); Publish(); } catch (Exception ex) { Plugin.Detail("[FinalAscent] Melderegister-Nachtrag gestolpert: " + ex.Message); } } private static void Publish() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (!FinalAscent.Active || !PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient || FinalAscentBuilder.Building) { return; } Hashtable val = new Hashtable(); foreach (KeyValuePair item in _noted) { if (!_published.TryGetValue(item.Key, out var value) || value != item.Value) { val[(object)("FA_R" + item.Key)] = item.Value; _published[item.Key] = item.Value; } } if (((Dictionary)(object)val).Count > 0) { PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Detail(string.Format("{0} Melderegister: {1} Eintraege aufgefrischt.", "[FinalAscent]", ((Dictionary)(object)val).Count)); } } internal static void ForgetRoom() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null || !PhotonNetwork.IsMasterClient) { return; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties == null) { return; } Hashtable val = new Hashtable(); foreach (object key in ((Dictionary)(object)customProperties).Keys) { if (key is string text && text.StartsWith("FA_R")) { val[(object)text] = null; } } _noted.Clear(); _published.Clear(); Unlatch(); if (((Dictionary)(object)val).Count > 0) { PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)(string.Format("{0} Neuer Lauf: {1} Melderegister-Eintraege des vorigen ", "[FinalAscent]", ((Dictionary)(object)val).Count) + "aus dem Raum genommen - sonst gaelte jeder als Rueckkehrer.")); } } private static IEnumerable KeysOf(Player who) { if (who != null) { if (!string.IsNullOrEmpty(who.UserId)) { yield return Safe(who.UserId); } if (!string.IsNullOrEmpty(who.NickName)) { yield return "n_" + Safe(who.NickName); } } } private static string Safe(string raw) { return raw.Replace('|', '_'); } internal static void Latch() { _latched = ReadOwnRaw(); _latchedSet = true; if (_latched == null && PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null) { string text = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.UserId : "(keine)"); StringBuilder stringBuilder = new StringBuilder(); Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties != null) { foreach (object key in ((Dictionary)(object)customProperties).Keys) { if (key is string text2 && text2.StartsWith("FA_R")) { if (stringBuilder.Length > 0) { stringBuilder.Append(", "); } stringBuilder.Append(text2.Substring("FA_R".Length)); } } } Plugin.Log.LogWarning((object)("[FinalAscent] MELDEREGISTER: kein eigener Eintrag. Mein Schluessel ist '" + text + "', im Raum stehen: " + ((stringBuilder.Length > 0) ? stringBuilder.ToString() : "keine") + ". Stehen dort andere Schluessel, hat sich die UserId beim Wiedereintritt geaendert.")); } Plugin.Detail("[FinalAscent] Melderegister eingefroren: " + ((_latched == null) ? "kein eigener Eintrag." : ("'" + _latched + "'."))); } internal static void Unlatch() { _latched = null; _latchedSet = false; } private static string ReadOwnRaw() { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null || PhotonNetwork.LocalPlayer == null) { return null; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties == null) { return null; } foreach (string item in KeysOf(PhotonNetwork.LocalPlayer)) { if (((Dictionary)(object)customProperties).TryGetValue((object)("FA_R" + item), out object value) && value is string result) { Plugin.Detail("[FinalAscent] Melderegister-Eintrag gefunden unter '" + item + "'."); return result; } } return null; } internal static bool TryReadOwn(out Vector3 at, out bool unconscious, out int stage) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_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) at = Vector3.zero; unconscious = false; stage = -1; if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null || PhotonNetwork.LocalPlayer == null || string.IsNullOrEmpty(PhotonNetwork.LocalPlayer.UserId)) { return false; } string text = (_latchedSet ? _latched : ReadOwnRaw()); if (text == null) { return false; } string[] array = text.Split('|'); if (array.Length < 5) { return false; } try { at = new Vector3(float.Parse(array[0], CultureInfo.InvariantCulture), float.Parse(array[1], CultureInfo.InvariantCulture), float.Parse(array[2], CultureInfo.InvariantCulture)); unconscious = array[3] == "1"; stage = int.Parse(array[4], CultureInfo.InvariantCulture); return true; } catch { return false; } } } internal static class FinalAscentSandCover { private const string Tag = "[FinalAscent]"; private const float Wall = 12f; private const float Wide = 22f; private const int Rows = 4; private const int Columns = 5; private const float Lowest = 0f; private const float Highest = 10f; private const float Every = 0.15f; private const float Ease = 4f; private const float Slow = 0.5f; private const float Shelter = 0.35f; private static readonly int Solid = LayerMask.GetMask(new string[2] { "Terrain", "Map" }); private static float _clock; private static float _lastTold; private static float _applied; private static CharacterMovement _braked; internal static float Exposed { get; private set; } internal static int Free { get; private set; } internal static bool Sheltered => Exposed < 0.35f; internal static void Drive(Character me, Vector3 wind, float strength) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)me == (Object)null || (Object)(object)me.data == (Object)null || me.refs == null || strength <= 0f) { Release(); return; } _clock -= Time.deltaTime; if (_clock <= 0f) { _clock = 0.15f; Probe(me.Center, wind); } Brake(me, strength); Tell(me, strength); } private static void Probe(Vector3 middle, Vector3 wind) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.Cross(Vector3.up, wind); Vector3 normalized = ((Vector3)(ref val)).normalized; Vector3 val2 = middle - wind * 12f; float num = 2.5f; float num2 = 4.4f; int num3 = 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 5; j++) { float num4 = 0f + ((float)i + Random.value) * num; float num5 = ((float)j + Random.value) * num2 - 11f; Vector3 val3 = val2 + Vector3.up * num4 + normalized * num5; if (!Physics.Linecast(middle, val3, Solid)) { num3++; } } } Free = num3; float num6 = (float)num3 / 20f; Exposed = Mathf.Lerp(Exposed, num6, 1f - Mathf.Exp(-0.6f)); } private static void Brake(Character me, float strength) { CharacterMovement movement = me.refs.movement; if (!((Object)(object)movement == (Object)null)) { if ((Object)(object)_braked != (Object)null && (Object)(object)_braked != (Object)(object)movement) { _applied = 0f; } _braked = movement; float num = 0.5f * Exposed * Mathf.Clamp01(strength); float num2 = num - _applied; if (Mathf.Abs(num2) > 0.0005f) { movement.movementModifier -= num2; _applied = num; } } } internal static void Release() { if ((Object)(object)_braked != (Object)null && _applied != 0f) { CharacterMovement braked = _braked; braked.movementModifier += _applied; } _applied = 0f; _braked = null; Exposed = 0f; Free = 0; _clock = 0f; } private static void Tell(Character me, float strength) { if (!(Time.unscaledTime - _lastTold < 2f)) { _lastTold = Time.unscaledTime; Plugin.Log.LogInfo((object)(string.Format("{0} Sanddeckung: {1} von {2} Proben frei, erreicht mich ", "[FinalAscent]", Free, 20) + string.Format("{0:0}% ({1}), ", Exposed * 100f, Sheltered ? "GEDECKT" : "im Freien") + $"Staerke {strength:0.00}, Tempo {(1f - _applied) * 100f:0}%.")); } } } internal static class FinalAscentSandVoice { private const string Tag = "[FinalAscent]"; private static readonly string[] Names = new string[5] { "Au_Wind_Loop", "Au_Ambience_WindMedium", "Au_Ambience_WindRough", "Au_SpinLoop", "Au_SpinLoop" }; private static readonly float[] Loudest = new float[5] { 0.5f, 0.4f, 0.45f, 0.06f, 0.06f }; private static readonly float[] Late = new float[5] { 1f, 1.5f, 1.9f, 2.8f, 3.2f }; private static readonly float[] Tone = new float[5] { 1f, 1f, 1f, 0.94f, 1.11f }; private static AudioSource[] _tracks; private static bool _told; internal static void Drive(float strength) { float num = Mathf.Clamp01(strength); if (_tracks == null) { if (num <= 0f) { return; } Build(); } if (_tracks == null) { return; } for (int i = 0; i < _tracks.Length; i++) { if ((Object)(object)_tracks[i] != (Object)null) { _tracks[i].volume = Loudest[i] * Mathf.Pow(num, Late[i]); } } } private static void Build() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown GameObject val = new GameObject("FA_SandVoice"); Object.DontDestroyOnLoad((Object)(object)val); _tracks = (AudioSource[])(object)new AudioSource[Names.Length]; int num = 0; for (int i = 0; i < Names.Length; i++) { AudioClip val2 = FinalAscentLarder.Sound(Names[i]); if (!((Object)(object)val2 == (Object)null)) { AudioSource val3 = val.AddComponent(); val3.clip = val2; val3.loop = true; val3.playOnAwake = false; val3.pitch = Tone[i]; val3.spatialBlend = 0f; val3.volume = 0f; val3.outputAudioMixerGroup = FinalAscentLarder.Bus(); val3.Play(); val3.time = Random.Range(0f, Mathf.Max(0.01f, val2.length - 0.05f)); _tracks[i] = val3; num++; } } if (!_told) { _told = true; Plugin.Log.LogInfo((object)(string.Format("{0} Sandsturm-Klang: {1} von {2} Spuren gefunden ", "[FinalAscent]", num, Names.Length) + "(" + string.Join(", ", Names) + "), versetzt gestartet.")); } } } [HarmonyPatch(typeof(DayNightManager), "UpdateCycle")] internal static class FinalAscentSandSky { private static readonly Color SkyHigh = new Color(0.19f, 0.13f, 0.06f, 1f); private static readonly Color SkyMid = new Color(0.36f, 0.25f, 0.12f, 1f); private static readonly Color SkyLow = new Color(0.52f, 0.38f, 0.19f, 1f); private static readonly Color Dusty = new Color(0.75f, 0.44f, 0.18f, 1f); private static readonly int TopKey = Shader.PropertyToID("SkyTopColor"); private static readonly int MidKey = Shader.PropertyToID("SkyMidColor"); private static readonly int LowKey = Shader.PropertyToID("SkyBottomColor"); internal static float Daylight { get; private set; } = 1f; private static float Lum(Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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) return c.r * 0.299f + c.g * 0.587f + c.b * 0.114f; } internal static Color Dim(Color c, float by) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) return new Color(c.r * by, c.g * by, c.b * by, c.a); } private static void Postfix(DayNightManager __instance) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) float sandStrength = FinalAscentWindStorm.SandStrength; if (sandStrength <= 0f) { Daylight = 1f; return; } Color globalColor = Shader.GetGlobalColor(LowKey); float num = Lum(SkyLow); Daylight = ((num > 0.0001f) ? Mathf.Clamp01(Lum(globalColor) / num) : 1f); Shader.SetGlobalColor(TopKey, Color.Lerp(Shader.GetGlobalColor(TopKey), Dim(SkyHigh, Daylight), sandStrength)); Shader.SetGlobalColor(MidKey, Color.Lerp(Shader.GetGlobalColor(MidKey), Dim(SkyMid, Daylight), sandStrength)); Shader.SetGlobalColor(LowKey, Color.Lerp(globalColor, Dim(SkyLow, Daylight), sandStrength)); Color val = Dim(Dusty, Daylight); if ((Object)(object)__instance.sun != (Object)null) { __instance.sun.color = Color.Lerp(__instance.sun.color, val, sandStrength); } if ((Object)(object)__instance.moon != (Object)null) { __instance.moon.color = Color.Lerp(__instance.moon.color, val, sandStrength); } } } [HarmonyPatch(typeof(AmbienceManager), "Update")] internal static class FinalAscentSandFog { private const float Sight = 14f; private static readonly Color Tint = new Color(0.4f, 0.28f, 0.15f, 1f); private const float Density = 65f; private const float SkyWash = 0f; private static readonly int MaxFog = Shader.PropertyToID("MAXFOG"); private static readonly int Blend = Shader.PropertyToID("_WeatherBlend"); private static readonly int TintKey = Shader.PropertyToID("WindTint"); private static readonly int DensityKey = Shader.PropertyToID("WindFogDensity"); private static readonly int WashKey = Shader.PropertyToID("WindSkyBrightnessValue"); private static readonly int TextureKey = Shader.PropertyToID("WindTextureInfluence"); private static readonly int MixKey = Shader.PropertyToID("WindMixInfluence"); private static float _lastTold; private static bool _ours; private static void Postfix(AmbienceManager __instance) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) float sandStrength = FinalAscentWindStorm.SandStrength; if (sandStrength <= 0f) { if (_ours) { _ours = false; Shader.SetGlobalFloat(Blend, 0f); Plugin.Log.LogInfo((object)"[FinalAscent] Sandnebel: Wetternebel freigegeben."); } return; } _ours = true; float globalFloat = Shader.GetGlobalFloat(MaxFog); float num = Mathf.Lerp(globalFloat, Mathf.Min(globalFloat, 14f), sandStrength); Shader.SetGlobalFloat(MaxFog, num); Shader.SetGlobalFloat(Blend, sandStrength); Shader.SetGlobalColor(TintKey, FinalAscentSandSky.Dim(Tint, FinalAscentSandSky.Daylight)); Shader.SetGlobalFloat(DensityKey, 65f); Shader.SetGlobalFloat(WashKey, 0f); Shader.SetGlobalFloat(TextureKey, 0f); Shader.SetGlobalFloat(MixKey, 0f); if (!(Time.unscaledTime - _lastTold < 2f)) { _lastTold = Time.unscaledTime; Plugin.Log.LogInfo((object)($"[FinalAscent] Sandnebel: Staerke {sandStrength:0.00}, Sichtweite " + $"{globalFloat:0} -> {num:0} (Ziel {14f:0}m), Tageslicht " + $"{FinalAscentSandSky.Daylight:0.00}, Wetternebel {sandStrength:0.00} in " + $"{FinalAscentSandSky.Dim(Tint, FinalAscentSandSky.Daylight)}, " + $"Dichte {65f:0}.")); } } } internal sealed class FinalAscentSandVisual : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const float Across = 24f; private const float Height = 20f; private const float Thickness = 15f; private const float Below = 5f; private const float Upwind = 10f; private const float FullRate = 190000f; private const float Lifetime = 0.45f; private const float FallSpeed = 0.8f; private const float Drift = 42f; private const float Smallest = 0.016f; private const float Biggest = 0.045f; private static readonly Color Grain = new Color(1f, 0.9f, 0.7f, 1f); private static readonly Color GrainDark = new Color(0.78f, 0.62f, 0.38f, 1f); private const float NightFloor = 0.33f; internal static int GrainCount; internal static string Skin = "?"; private ParticleSystem _near; private float _lastTold; internal static FinalAscentSandVisual Make() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown GameObject val = new GameObject("FA_SandVisual"); Object.DontDestroyOnLoad((Object)val); FinalAscentSandVisual finalAscentSandVisual = val.AddComponent(); finalAscentSandVisual.Build(); return finalAscentSandVisual; } internal void Show(Vector3 where, Vector3 wind, float strength) { //IL_0015: 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_005c: 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_0086: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) if (!((Object)(object)_near == (Object)null)) { ((Component)this).transform.position = where; if (((Vector3)(ref wind)).sqrMagnitude > 0.001f) { ((Component)this).transform.rotation = Quaternion.LookRotation(wind); } GrainCount = _near.particleCount; float num = Mathf.Clamp01(strength); EmissionModule emission = _near.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(190000f * num); float num2 = Mathf.Max(FinalAscentSandSky.Daylight, 0.33f); MainModule main = _near.main; ((MainModule)(ref main)).startColor = new MinMaxGradient(FinalAscentSandSky.Dim(Grain, num2), FinalAscentSandSky.Dim(GrainDark, num2)); VelocityOverLifetimeModule velocityOverLifetime = _near.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = new MinMaxCurve(wind.x * 42f * num); ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).z = new MinMaxCurve(wind.z * 42f * num); ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y = new MinMaxCurve(-0.8f); if (num > 0f && !_near.isPlaying) { _near.Play(); } else if (num <= 0f && _near.isPlaying) { _near.Stop(true, (ParticleSystemStopBehavior)1); } if (Time.unscaledTime - _lastTold >= 5f) { _lastTold = Time.unscaledTime; Plugin.Log.LogInfo((object)(string.Format("{0} Sandkoerner: {1} in der Luft, Staerke {2:0.00}, ", "[FinalAscent]", GrainCount, num) + $"{190000f * num:0} je Sekunde, Werkstoff '{Skin}'.")); } } } private void Build() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) Material sharedMaterial = Cloth(); _near = ((Component)this).gameObject.AddComponent(); _near.Stop(true, (ParticleSystemStopBehavior)0); ShapeModule shape = _near.shape; ((ShapeModule)(ref shape)).enabled = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)5; ((ShapeModule)(ref shape)).scale = new Vector3(24f, 20f, 15f); ((ShapeModule)(ref shape)).position = new Vector3(0f, 5f, -10f); MainModule main = _near.main; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.45f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.016f, 0.045f); ((MainModule)(ref main)).startColor = new MinMaxGradient(Grain, GrainDark); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).maxParticles = 130000; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).playOnAwake = false; EmissionModule emission = _near.emission; ((EmissionModule)(ref emission)).enabled = true; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); VelocityOverLifetimeModule velocityOverLifetime = _near.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space = (ParticleSystemSimulationSpace)1; NoiseModule noise = _near.noise; ((NoiseModule)(ref noise)).enabled = true; ((NoiseModule)(ref noise)).strength = MinMaxCurve.op_Implicit(1.1f); ((NoiseModule)(ref noise)).frequency = 0.9f; ((NoiseModule)(ref noise)).scrollSpeed = MinMaxCurve.op_Implicit(1.4f); ((NoiseModule)(ref noise)).damping = true; ((NoiseModule)(ref noise)).quality = (ParticleSystemNoiseQuality)0; ParticleSystemRenderer component = ((Component)this).GetComponent(); component.renderMode = (ParticleSystemRenderMode)1; component.velocityScale = 0.006f; component.lengthScale = 1f; component.alignment = (ParticleSystemRenderSpace)0; ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component).receiveShadows = false; ((Renderer)component).sharedMaterial = sharedMaterial; CollisionModule collision = _near.collision; ((CollisionModule)(ref collision)).enabled = true; ((CollisionModule)(ref collision)).type = (ParticleSystemCollisionType)1; ((CollisionModule)(ref collision)).mode = (ParticleSystemCollisionMode)0; ((CollisionModule)(ref collision)).quality = (ParticleSystemCollisionQuality)2; ((CollisionModule)(ref collision)).collidesWith = LayerMask.op_Implicit(LayerMask.GetMask(new string[2] { "Terrain", "Map" })); ((CollisionModule)(ref collision)).lifetimeLoss = MinMaxCurve.op_Implicit(1f); ((CollisionModule)(ref collision)).dampen = MinMaxCurve.op_Implicit(1f); ((CollisionModule)(ref collision)).bounce = MinMaxCurve.op_Implicit(0f); ((CollisionModule)(ref collision)).sendCollisionMessages = false; Plugin.Log.LogInfo((object)(string.Format("{0} Sandkoerner gebaut - Werkstoff '{1}', {2:0.###}-", "[FinalAscent]", Skin, 0.016f) + $"{0.045f:0.###} breit, Farbe {Grain}, Sinken {0.8f:0.#}, Zug " + $"{42f:0.#}, Kasten {24f:0}x{20f:0}x{15f:0} in " + $"{10f:0}m Luv, bis {190000f:0} je Sekunde, Kollision grob " + "(Guete NIEDRIG, kein Strahl je Korn), keine ferne Lage.")); } private static Material Cloth() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) Shader val = Rules(); if ((Object)(object)val == (Object)null) { Skin = "keiner"; Plugin.Log.LogWarning((object)"[FinalAscent] Sandkoerner: kein Regelwerk gefunden - man sieht nichts."); return null; } Material val2 = new Material(val); val2.mainTexture = (Texture)(object)Grit(); if (val2.HasProperty("_TintColor")) { val2.SetColor("_TintColor", new Color(0.5f, 0.5f, 0.5f, 0.5f)); } return val2; } private static Shader Rules() { string[] array = new string[3] { "Legacy Shaders/Particles/Alpha Blended", "Particles/Alpha Blended", "Legacy Shaders/Particles/Alpha Blended Premultiply" }; for (int i = 0; i < array.Length; i++) { Shader val = Shader.Find(array[i]); if ((Object)(object)val != (Object)null) { Skin = array[i]; return val; } } Shader[] array2 = Resources.FindObjectsOfTypeAll(); foreach (Shader val2 in array2) { if ((Object)(object)val2 == (Object)null) { continue; } for (int k = 0; k < array.Length; k++) { if (((Object)val2).name == array[k]) { Skin = array[k] + " (geladen)"; return val2; } } } return null; } private static Texture2D Grit() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(16, 16, (TextureFormat)4, true); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; Color32[] array = (Color32[])(object)new Color32[256]; float num = 7.5f; float num2 = 1f / num; for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { float num3 = ((float)j - num) / num; float num4 = ((float)i - num) / num; float num5 = Mathf.Pow(Mathf.Max(Mathf.Pow(Mathf.Abs(num3), 4f) + Mathf.Pow(Mathf.Abs(num4), 4f), 0.0001f), 0.25f); byte b = (byte)(Mathf.Clamp01(1f - Mathf.SmoothStep(1f - num2, 1f, num5)) * 255f); array[i * 16 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b); } } val.SetPixels32(array); val.Apply(true); return val; } } internal static class FinalAscentSaws { private const string Tag = "[FinalAscent]"; private static readonly FieldInfo AnchorField = AccessTools.Field(typeof(MovingSawBlade), "randomOffset"); internal static void Reanchor() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0060: Unknown result type (might be due to invalid IL or missing references) if (AnchorField == null) { Plugin.Log.LogWarning((object)"[FinalAscent] Saegen: kein Feld 'randomOffset' gefunden - die Phase bleibt, wie sie beim Erwachen entstand."); return; } int num = 0; int num2 = 0; MovingSawBlade[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (MovingSawBlade val in array) { if ((Object)(object)val == (Object)null) { continue; } try { Vector3 position = ((Component)val).transform.position; float num3 = position.x + position.y + position.z; float num4 = (float)AnchorField.GetValue(val); if (Mathf.Abs(num3 - num4) < 0.0001f) { num2++; continue; } AnchorField.SetValue(val, num3); num++; } catch (Exception ex) { Plugin.Detail("[FinalAscent] Saege '" + ((Object)val).name + "' liess sich nicht neu ankern: " + ex.Message); } } Plugin.Log.LogInfo((object)(string.Format("{0} Saegen neu geankert: {1} von {2} Blaettern ", "[FinalAscent]", num, num + num2) + "auf ihre Endposition gesetzt (der Rest stand schon richtig). Damit rechnen alle Rechner dieselbe Phase - unabhaengig davon, wann das Blatt erwacht ist.")); } } internal sealed class FinalAscentScoutHunt : MonoBehaviour { private enum Phase { Idle, Watched, Hunted, Done } private const string Tag = "[FinalAscent]"; internal const float Gaze = 20f; internal const float Clears = 2f; internal const float Stare = 3f; internal const float Odds = 0.05f; internal const float Blind = 4f; private const float Shared = 3f; private const float Forced = 8f; private const float Renew = 3f; private const float Torchlight = 35f; private const float ConeHalf = 30f; private const float Hiss = 0.28f; private const float HissIn = 3f; private const float Prey = 0.22f; private const float Chill = 30f; private Phase _phase; private float _dark; private float _lit; private float _roll; private float _beam; private float _renew; private float _hiss; private int _rolls; private float _watched; private float _watch; private bool _sighted; private string _why = ""; private static FinalAscentScoutHunt _instance; private static int _brought = -1; private static bool _moaned; private static readonly int StrengthKey = Shader.PropertyToID("_Strength"); private static readonly int GrainKey = Shader.PropertyToID("_GrainMult"); private const float Leaving = 3f; internal static bool Chased { get; private set; } internal static float Dark { get { if (!((Object)(object)_instance != (Object)null)) { return 0f; } return _instance._dark; } } internal static float Held { get { if (!((Object)(object)_instance != (Object)null)) { return 0f; } return _instance._lit; } } internal static float Beamed { get { if (!((Object)(object)_instance != (Object)null)) { return 0f; } return _instance._beam; } } internal static float Hissing { get { if (!((Object)(object)_instance != (Object)null)) { return 0f; } return _instance._hiss; } } internal static int Rolls { get { if (!((Object)(object)_instance != (Object)null)) { return 0; } return _instance._rolls; } } internal static float Staring { get { if (!((Object)(object)_instance != (Object)null)) { return 0f; } return _instance._watched; } } internal static string Where { get { if (!((Object)(object)_instance != (Object)null)) { return "-"; } return _instance._phase.ToString(); } } internal static bool Allowed => !Blocked(); internal static bool Sighted { get { if ((Object)(object)_instance != (Object)null) { return _instance._sighted; } return false; } } internal static string Lantern { get { if (!((Object)(object)_instance != (Object)null)) { return ""; } return _instance._why; } } internal static string Sheet { get { Scoutmaster val = default(Scoutmaster); if (!Scoutmaster.GetPrimaryScoutmaster(ref val) || (Object)(object)val == (Object)null) { return "kein Scoutmaster"; } return State(val, Character.localCharacter); } } 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_ScoutHunt"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } if (!on) { Retreat(); Away(); } if ((Object)(object)_instance != (Object)null) { _instance.Clear(); } Chased = false; if (on) { _moaned = false; Bring(); } else { Send(); } } private void Clear() { _phase = Phase.Idle; _dark = 0f; _lit = 0f; _roll = 0f; _beam = 0f; _renew = 0f; _hiss = 0f; _rolls = 0; _watched = 0f; _watch = 0f; _sighted = false; _why = ""; Hush(); } private void Update() { if (!FinalAscentDarkSky.Wanted || !FinalAscentDarkSky.Full) { if (!FinalAscentDarkSky.Wanted && _phase != Phase.Idle) { Clear(); Chased = false; } return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null) { return; } if (Blocked()) { if (!_moaned) { _moaned = true; Plugin.Log.LogInfo((object)("[FinalAscent] Finsternis: der Scoutmaster ist in diesem Lauf " + $"abgestellt (eigener Lauf {RunSettings.IsCustomRun}, Grad " + $"{Ascents.currentAscent}) - keine Uhr, kein Rauschen, keine Jagd.")); } _dark = 0f; _lit = 0f; Chased = false; return; } Scoutmaster val = default(Scoutmaster); if (!Scoutmaster.GetPrimaryScoutmaster(ref val) || (Object)(object)val == (Object)null) { if (!_moaned) { _moaned = true; Plugin.Log.LogInfo((object)"[FinalAscent] Finsternis: kein Scoutmaster erreichbar - es bleibt dunkel und harmlos."); } return; } Chased = Aimed(val, localCharacter); Clock(); switch (_phase) { case Phase.Idle: if (_dark >= 20f) { _phase = Phase.Watched; _roll = 0f; _watched = 0f; Plugin.Log.LogInfo((object)("[FinalAscent] Finsternis: zu lange ohne Licht - er sieht her. Licht hilft ab jetzt nicht mehr. " + State(val, localCharacter))); } break; case Phase.Watched: _watched += Time.deltaTime; _hiss = Mathf.MoveTowards(_hiss, 0.28f, Time.deltaTime / 3f); Static(val, _hiss); if (_watched < 3f) { break; } _roll += Time.deltaTime; if (_roll >= 1f) { _roll -= 1f; _rolls++; if ((Object)(object)val.currentTarget == (Object)null && Random.value < 0.05f) { Attack(val, localCharacter); } } break; case Phase.Hunted: Hunt(val, localCharacter); break; } } private void Clock() { _sighted = Seen(); if (_phase != Phase.Idle) { return; } if (_sighted) { _lit += Time.deltaTime; if (_lit >= 2f) { _dark = 0f; } } else { _lit = 0f; _dark += Time.deltaTime; } } private bool Seen() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) if (FinalAscentFlashlight.Lit) { _why = "eigene Lampe"; return true; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null) { GloomSafeZone val = default(GloomSafeZone); float num = default(float); if (GloomSafeZone.CharacterProtectedFromStatus(localCharacter, ref val, ref num)) { _why = string.Format("{0} ({1:0.0}m)", ((Object)(object)val != (Object)null) ? ((Object)((Component)val).gameObject).name : "Licht", num); return true; } List aLL_GLOOM_SAFE_ZONES = GloomSafeZone.ALL_GLOOM_SAFE_ZONES; for (int i = 0; i < aLL_GLOOM_SAFE_ZONES.Count; i++) { GloomSafeZone val2 = aLL_GLOOM_SAFE_ZONES[i]; if (!((Object)(object)val2 == (Object)null) && val2.isLit) { float num2 = Vector3.Distance(((Component)val2).transform.position, localCharacter.Center); if (num2 <= 3f) { _why = $"{((Object)((Component)val2).gameObject).name} ({num2:0.0}m)"; return true; } } } } _why = ""; return false; } private void Attack(Scoutmaster him, Character me) { if (Blocked()) { _phase = Phase.Done; Hush(); Plugin.Log.LogWarning((object)("[FinalAscent] Finsternis: der Scoutmaster ist in diesem Lauf ABGESTELLT " + $"(eigener Lauf {RunSettings.IsCustomRun}, Grad " + $"{Ascents.currentAscent}) - keine Jagd, und in dieser Finsternis " + "auch keine weitere.")); } else { _phase = Phase.Hunted; _beam = 0f; _renew = 0f; Force(him, me); Plugin.Log.LogInfo((object)("[FinalAscent] Finsternis: der Scoutmaster kommt. " + State(him, me))); } } private void Hunt(Scoutmaster him, Character me) { if ((Object)(object)him.mat != (Object)null && him.mat.GetFloat(StrengthKey) < 0.22f) { Static(him, 0.22f); } _watch += Time.deltaTime; if (_watch >= 8f) { _watch = 0f; Plugin.Log.LogInfo((object)("[FinalAscent] Finsternis, Jagd laeuft: " + State(him, me))); } if (me.data.fullyPassedOut || me.data.dead) { _phase = Phase.Done; Loose(); Plugin.Log.LogInfo((object)"[FinalAscent] Finsternis: er hat ihn."); return; } if (Shining(him, me)) { _beam += Time.deltaTime; if (_beam >= 4f) { _phase = Phase.Done; Loose(); Plugin.Log.LogInfo((object)string.Format("{0} Finsternis: {1:0}s im Strahl - er zieht sich zurueck.", "[FinalAscent]", 4f)); return; } } else { _beam = 0f; } _renew -= Time.deltaTime; if (_renew <= 0f) { _renew = 3f; Force(him, me); } } private static bool Shining(Scoutmaster him, Character me) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_006c: 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) if (!FinalAscentFlashlight.Lit) { return false; } Character component = ((Component)him).GetComponent(); if ((Object)(object)component == (Object)null) { return false; } Vector3 head = me.Head; Vector3 val = component.Center - head; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude > 35f || magnitude < 0.01f) { return false; } if (Vector3.Angle(FinalAscentTorches.AimOf(me), val) > 30f) { return false; } RaycastHit val2 = HelperFunctions.LineCheck(head, component.Center, (LayerType)1, 0f, (QueryTriggerInteraction)1); return (Object)(object)((RaycastHit)(ref val2)).transform == (Object)null; } internal static string State(Scoutmaster him, Character me) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)him == (Object)null) { return "kein Scoutmaster"; } PhotonView component = ((Component)him).GetComponent(); Character component2 = ((Component)him).GetComponent(); float num = (((Object)(object)component2 != (Object)null && (Object)(object)me != (Object)null) ? Vector3.Distance(component2.Center, me.Center) : (-1f)); object obj = Get(him, "targetForcedUntil"); object obj2 = Get(him, "chillForSeconds"); return $"Nummer {(((Object)(object)component != (Object)null) ? component.ViewID : (-1))}, " + "gehoert " + (((Object)(object)component != (Object)null && component.IsMine) ? "mir" : "einem anderen") + ", Ziel " + (((Object)(object)him.currentTarget != (Object)null) ? ((Object)him.currentTarget).name : "keins") + (((Object)(object)him.currentTarget == (Object)(object)me) ? " (ICH)" : "") + ", " + $"{num:0}m, Frist {((obj is float) ? ((float)obj - Time.time) : (-1f)):0.0}s, " + $"Ruhe {((obj2 is float) ? ((float)obj2) : (-1f)):0.0}s"; } private static object Get(Scoutmaster him, string field) { FieldInfo fieldInfo = AccessTools.Field(typeof(Scoutmaster), field); if (!(fieldInfo != null)) { return null; } return fieldInfo.GetValue(him); } private static bool Aimed(Scoutmaster him, Character me) { if ((Object)(object)him.currentTarget != (Object)null) { return (Object)(object)him.currentTarget == (Object)(object)me; } return false; } private static void Force(Scoutmaster him, Character me) { PhotonView component = ((Component)him).GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)((MonoBehaviourPun)me).photonView == (Object)null)) { component.RPC("RPCA_SetCurrentTarget", (RpcTarget)0, new object[2] { ((MonoBehaviourPun)me).photonView.ViewID, 8f }); } } private void Loose() { _hiss = 0f; Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && localCharacter.refs != null && (Object)(object)localCharacter.refs.view != (Object)null) { localCharacter.refs.view.RPC("RPC_FinalAscentScoutOff", (RpcTarget)0, new object[1] { localCharacter.refs.view.ViewID }); } else { Retreat(); } } internal static void Retreat(Character chased = null) { Scoutmaster val = default(Scoutmaster); if (!Scoutmaster.GetPrimaryScoutmaster(ref val) || (Object)(object)val == (Object)null) { return; } Set(val, "targetForcedUntil", 0f); Set(val, "_currentTarget", null); if ((Object)(object)val.mat != (Object)null) { val.mat.SetFloat(StrengthKey, 0f); } PhotonView component = ((Component)val).GetComponent(); if (!((Object)(object)component == (Object)null) && component.IsMine) { Character component2 = ((Component)val).GetComponent(); if ((Object)(object)component2 != (Object)null && (Object)(object)component2.data != (Object)null && (Object)(object)component2.data.grabJoint != (Object)null && component2.refs != null && (Object)(object)component2.refs.view != (Object)null) { component2.refs.view.RPC("RPCA_GrabUnattach", (RpcTarget)0, Array.Empty()); Plugin.Log.LogInfo((object)"[FinalAscent] Finsternis: er laesst los."); } if ((Object)(object)chased != (Object)null) { val.discovered = chased; } } } private static void Away() { Scoutmaster val = default(Scoutmaster); if (Scoutmaster.GetPrimaryScoutmaster(ref val) && !((Object)(object)val == (Object)null)) { PhotonView component = ((Component)val).GetComponent(); if (!((Object)(object)component == (Object)null) && component.IsMine) { Set(val, "chillForSeconds", 30f); Set(val, "tpCounter", 10f); val.TeleportFarAway(); } } } private static void Set(Scoutmaster him, string field, object value) { FieldInfo fieldInfo = AccessTools.Field(typeof(Scoutmaster), field); if (fieldInfo != null) { fieldInfo.SetValue(him, value); } } private static void Static(Scoutmaster him, float much) { if (!((Object)(object)him.mat == (Object)null)) { him.mat.SetFloat(GrainKey, ((Object)(object)GUIManager.instance != (Object)null && GUIManager.instance.photosensitivity) ? 0f : 1f); him.mat.SetFloat(StrengthKey, much); } } private void Hush() { _hiss = 0f; Scoutmaster val = default(Scoutmaster); if (Scoutmaster.GetPrimaryScoutmaster(ref val) && (Object)(object)val != (Object)null && (Object)(object)val.mat != (Object)null) { val.mat.SetFloat(StrengthKey, 0f); } } private static bool Blocked() { try { if (RunSettings.IsCustomRun) { return RunSettings.GetValue((SETTINGTYPE)2700, false) == 0; } return Ascents.currentAscent < 0; } catch (Exception) { return false; } } private static void Bring() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0058: Unknown result type (might be due to invalid IL or missing references) Scoutmaster val = default(Scoutmaster); if (!PhotonNetwork.IsMasterClient || Blocked() || (Scoutmaster.GetPrimaryScoutmaster(ref val) && (Object)(object)val != (Object)null)) { return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { return; } Vector3 val2 = localCharacter.Center + new Vector3(0f, 0f, 300f); GameObject val3 = PhotonNetwork.InstantiateRoomObject("Character_Scoutmaster", val2, Quaternion.identity, (byte)0, (object[])null); if ((Object)(object)val3 == (Object)null) { Plugin.Log.LogWarning((object)"[FinalAscent] Finsternis: Scoutmaster liess sich nicht absetzen."); return; } Character component = val3.GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.data != (Object)null) { component.data.spawnPoint = val3.transform; } PhotonView componentInChildren = val3.GetComponentInChildren(true); _brought = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.ViewID : (-1)); Plugin.Log.LogInfo((object)string.Format("{0} Finsternis: Scoutmaster fuer die Dauer abgesetzt (Nummer {1}).", "[FinalAscent]", _brought)); } private static void Send() { if (_brought < 0) { return; } int brought = _brought; _brought = -1; if (PhotonNetwork.IsMasterClient) { if ((Object)(object)_instance != (Object)null) { ((MonoBehaviour)_instance).StartCoroutine(Leave(brought)); } else { Vanish(brought); } } } private static IEnumerator Leave(int id) { yield return (object)new WaitForSeconds(3f); Vanish(id); } private static void Vanish(int id) { PhotonView val = PhotonView.Find(id); if ((Object)(object)val != (Object)null) { PhotonNetwork.Destroy(((Component)val).gameObject); Plugin.Log.LogInfo((object)"[FinalAscent] Finsternis: gebrachter Scoutmaster entfernt - nachdem er losgelassen hat und fort war."); } } } internal static class FinalAscentScoutmaster { private const string Tag = "[FinalAscent]"; private const float VanillaShare = 0.6875f; private static readonly FieldInfo AggroField = AccessTools.Field(typeof(Scoutmaster), "maxAggroHeight"); internal static void Raise() { if (AggroField == null) { Plugin.Log.LogWarning((object)"[FinalAscent] Scoutmaster: kein Feld 'maxAggroHeight' gefunden - er bleibt unterhalb von 825 Einheiten haengen und taucht nie auf."); return; } float num = FinalAscentHeights.Summit * 0.6875f; int num2 = 0; float num3 = 0f; Scoutmaster[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Scoutmaster val in array) { if ((Object)(object)val == (Object)null) { continue; } try { num3 = (float)AggroField.GetValue(val); if (!(Mathf.Abs(num3 - num) < 0.5f)) { AggroField.SetValue(val, num); num2++; } } catch (Exception ex) { Plugin.Detail("[FinalAscent] Scoutmaster '" + ((Object)val).name + "': " + ex.Message); } } Plugin.Log.LogInfo((object)(string.Format("{0} Scoutmaster: {1} mal die Aggro-Grenze von {2:F0} auf ", "[FinalAscent]", num2, num3) + $"{num:F0} gehoben (Gipfel {FinalAscentHeights.Summit:F0}, Vanillas " + $"Verhaeltnis 825/{1200f:F0}). Darunter jagt " + "er wie gewohnt, darueber laesst er ab - nur eben auf unserem Berg statt auf der Tageskarte.")); } } [HarmonyPatch(typeof(MushroomZombieSpawner), "Start")] internal static class FinalAscentZombieDice { private static void Prefix(MushroomZombieSpawner __instance, ref bool ___cullRandomly) { if (FinalAscent.Active && !((Object)(object)__instance == (Object)null) && ___cullRandomly) { string text = FinalAscentDelivery.ScenePathOf(((Component)__instance).transform); uint num = 2166136261u; string text2 = text; foreach (char c in text2) { num = (num ^ c) * 16777619; } if ((float)(num % 100000) / 100000f > 0.333f) { Object.Destroy((Object)(object)((Component)__instance).gameObject); } ___cullRandomly = false; } } } internal static class FinalAscentSegmentReport { private const string Tag = "[FinalAscent]"; private static readonly HashSet _reported = new HashSet(); private const int TopMaterials = 20; internal static void Automatic(Vector3 near) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) Transform val = Nearest(near); if (!((Object)(object)val == (Object)null) && _reported.Add(((Object)val).name)) { Write(near); } } internal static void Forget() { _reported.Clear(); } internal static void Write(Vector3 near) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) Transform val = Nearest(near); if ((Object)(object)val == (Object)null) { Plugin.Log.LogInfo((object)"[FinalAscent] Bericht: kein Segment in der Naehe gefunden."); return; } Plugin.Log.LogInfo((object)("[FinalAscent] ===== Bericht ueber '" + ((Object)val).name + "' (Aufstieg: " + (FinalAscent.Active ? "AN" : "aus") + ") =====")); Plugin.Log.LogInfo((object)string.Format("{0} Was steht da ({1} direkte Kinder):", "[FinalAscent]", val.childCount)); for (int i = 0; i < val.childCount; i++) { Transform child = val.GetChild(i); Plugin.Log.LogInfo((object)("[FinalAscent] " + (((Component)child).gameObject.activeSelf ? "AN " : "aus") + " " + $"{((Object)child).name} ({Visible(child)} sichtbar)")); } Dictionary dictionary = new Dictionary(); int num = 0; Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Renderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && val2.enabled && ((Component)val2).gameObject.activeInHierarchy) { num++; Material[] sharedMaterials = val2.sharedMaterials; foreach (Material val3 in sharedMaterials) { string key = (((Object)(object)val3 != (Object)null) ? ((Object)val3).name : "(keins)"); dictionary.TryGetValue(key, out var value); dictionary[key] = value + 1; } } } List> list = new List>(dictionary); list.Sort((KeyValuePair a, KeyValuePair b) => b.Value.CompareTo(a.Value)); Plugin.Log.LogInfo((object)(string.Format("{0} Wie sieht es aus: {1} sichtbare Renderer, ", "[FinalAscent]", num) + $"{dictionary.Count} verschiedene Materialien:")); for (int num2 = 0; num2 < list.Count && num2 < 20; num2++) { Plugin.Log.LogInfo((object)string.Format("{0} {1,6}x {2}", "[FinalAscent]", list[num2].Value, list[num2].Key)); } WhoPlacedThem(val); Plugin.Log.LogInfo((object)"[FinalAscent] ===== Ende des Berichts ====="); } private static void WhoPlacedThem(Transform segment) { Dictionary dictionary = new Dictionary(); Renderer[] componentsInChildren = ((Component)segment).GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || !val.enabled || !((Component)val).gameObject.activeInHierarchy) { continue; } PropSpawner componentInParent = ((Component)val).GetComponentInParent(true); string text = (((Object)(object)componentInParent != (Object)null) ? Short(((Component)componentInParent).transform, segment) : "(kein Spawner)"); Material[] sharedMaterials = val.sharedMaterials; foreach (Material val2 in sharedMaterials) { if (!((Object)(object)val2 == (Object)null)) { string key = ((Object)val2).name + " <- " + text; dictionary.TryGetValue(key, out var value); dictionary[key] = value + 1; } } } List> list = new List>(dictionary); list.Sort((KeyValuePair a, KeyValuePair b) => b.Value.CompareTo(a.Value)); Plugin.Log.LogInfo((object)"[FinalAscent] Wer hat es gesetzt (Material <- Spawner):"); for (int num = 0; num < list.Count && num < 20; num++) { Plugin.Log.LogInfo((object)string.Format("{0} {1,6}x {2}", "[FinalAscent]", list[num].Value, list[num].Key)); } } private static string Short(Transform of, Transform under) { string text = ((Object)of).name; Transform parent = of.parent; while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)under) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private static Transform Nearest(Vector3 near) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) Transform result = null; float num = float.MaxValue; Biome[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Biome val in array) { if ((Object)(object)val == (Object)null) { continue; } foreach (Transform item in ((Component)val).transform) { Transform val2 = item; if (((Object)val2).name.EndsWith("Segment") || ((Object)val2).name.EndsWith("Segment ")) { Vector3 val3 = val2.position - near; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val2; } } } } return result; } private static int Visible(Transform where) { int num = 0; Renderer[] componentsInChildren = ((Component)where).GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.enabled && ((Component)val).gameObject.activeInHierarchy) { num++; } } return num; } } internal class FinalAscentStage { internal BiomeType Type; internal BiomeType Presence; internal string Title; internal GameObject Root; internal int SegmentIndex; internal int ChainIndex; internal GameObject Campfire; internal GameObject Terrain; internal bool TerrainOnly; internal DayNightProfile Profile; internal int WallKey = -1; internal FinalAscentStage Next; internal GameObject AdvanceHides { get { if (!TerrainOnly) { return Root; } return Terrain; } } internal GameObject ToDeactivate { get { if (!TerrainOnly) { return Root; } return Terrain; } } } internal static class FinalAscentSegments { private const string Tag = "[FinalAscent]"; private static readonly FieldInfo SegmentParentField = AccessTools.Field(typeof(MapSegment), "_segmentParent"); private static readonly FieldInfo SegmentCampfireField = AccessTools.Field(typeof(MapSegment), "_segmentCampfire"); private static readonly FieldInfo DayNightProfileField = AccessTools.Field(typeof(MapSegment), "_dayNightProfile"); private static readonly MethodInfo SpawnCampfireItemsMethod = AccessTools.Method(typeof(MapHandler), "SpawnCampfireItems", (Type[])null, (Type[])null); private static GameObject _summitCampfire; private static readonly Dictionary VisibleStage = new Dictionary(); private static readonly Dictionary FirstStage = new Dictionary(); private static readonly Dictionary StageByCampfire = new Dictionary(); private static readonly FieldInfo SceneViewIdField = AccessTools.Field(typeof(PhotonView), "sceneViewId") ?? AccessTools.Field(typeof(PhotonView), "viewIdField"); private static readonly List ReparentedCampfires = new List(); internal static FinalAscentStage CurrentStage { get { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected I4, but got Unknown int key = (int)MapHandler.CurrentSegmentNumber; if (VisibleStage.TryGetValue(key, out var value) && value != null) { return value; } FirstStage.TryGetValue(key, out value); return value; } } internal static void ReportStages() { ReportActiveStages(); } private static void ReportActiveStages() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) List list = new List(); foreach (KeyValuePair item in FirstStage) { for (FinalAscentStage finalAscentStage = item.Value; finalAscentStage != null; finalAscentStage = finalAscentStage.Next) { bool flag = (Object)(object)finalAscentStage.Root != (Object)null && finalAscentStage.Root.activeInHierarchy; bool flag2 = (Object)(object)finalAscentStage.Terrain != (Object)null && finalAscentStage.Terrain.activeInHierarchy; list.Add($"{finalAscentStage.Type}: Wurzel {State(finalAscentStage.Root)}, Gelaende " + $"{State(finalAscentStage.Terrain)}, {Visible(finalAscentStage.Terrain)} sichtbar" + ((flag || flag2) ? "" : " <- ganz aus")); } } Plugin.Log.LogInfo((object)"[FinalAscent] Stand der Etappen:"); foreach (string item2 in list) { Plugin.Log.LogInfo((object)("[FinalAscent] " + item2)); } } private static string State(GameObject of) { if ((Object)(object)of == (Object)null) { return "fehlt"; } if (!of.activeInHierarchy) { if (!of.activeSelf) { return "aus"; } return "an (Elternteil aus)"; } return "an"; } private static int Visible(GameObject under) { if ((Object)(object)under == (Object)null) { return 0; } int num = 0; Renderer[] componentsInChildren = under.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.enabled && ((Component)val).gameObject.activeInHierarchy) { num++; } } return num; } private static void RegisterLoneSegments(MapHandler map) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < map.segments.Length; i++) { if (FirstStage.ContainsKey(i)) { continue; } MapSegment val = map.segments[i]; if (val != null) { object? value = SegmentParentField.GetValue(val); GameObject val2 = (GameObject)((value is GameObject) ? value : null); if (!((Object)(object)val2 == (Object)null)) { Biome componentInParent = val2.GetComponentInParent(true); FinalAscentStage finalAscentStage = new FinalAscentStage { Type = (BiomeType)(((Object)(object)componentInParent != (Object)null) ? ((int)componentInParent.biomeType) : 0), Presence = (BiomeType)(((Object)(object)componentInParent != (Object)null) ? ((int)componentInParent.biomeType) : 0), Title = TitleOf((BiomeType)(((Object)(object)componentInParent != (Object)null) ? ((int)componentInParent.biomeType) : 0)), Root = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).gameObject : val2), Terrain = val2, Campfire = (GameObject)/*isinst with value type is only supported in some contexts*/, Profile = (DayNightProfile)/*isinst with value type is only supported in some contexts*/, SegmentIndex = i, ChainIndex = 0, TerrainOnly = true }; FirstStage[i] = finalAscentStage; VisibleStage[i] = finalAscentStage; Plugin.Detail(string.Format("{0} Einzeletappe fuer Segment {1} nachgetragen: {2} ", "[FinalAscent]", i, finalAscentStage.Type) + "('" + ((Object)val2).name + "')."); } } } } internal static IEnumerable AllStages() { List list = new List(FirstStage.Keys); list.Sort(); foreach (int item in list) { for (FinalAscentStage stage = FirstStage[item]; stage != null; stage = stage.Next) { yield return stage; } } } private static void WakeUp(GameObject of) { if ((Object)(object)of == (Object)null) { return; } List list = new List(); Transform val = of.transform; while ((Object)(object)val != (Object)null) { list.Add(((Component)val).gameObject); val = val.parent; } for (int num = list.Count - 1; num >= 0; num--) { if (!list[num].activeSelf) { list[num].SetActive(true); } } } internal static int KeyOf(FinalAscentStage stage) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected I4, but got Unknown if (stage != null) { return stage.SegmentIndex * 16 + stage.ChainIndex; } return MapHandler.CurrentSegmentNumber * 16; } internal static void MarkFogRevealed() { OrbFogHandler instance = Singleton.Instance; if ((Object)(object)instance == (Object)null) { return; } object obj = AccessTools.Field(typeof(OrbFogHandler), "sphere")?.GetValue(instance); if (obj == null) { Plugin.Detail("[FinalAscent] Keine Nebelkugel - nichts zu enthuellen."); return; } float num = ((instance.fogRevealCurve != null) ? instance.fogRevealCurve.Evaluate(1f) : 0f); FieldInfo fieldInfo = AccessTools.Field(obj.GetType(), "REVEAL_AMOUNT"); if (fieldInfo != null) { fieldInfo.SetValue(obj, num); Plugin.Log.LogInfo((object)string.Format("{0} Nebelkugel als fertig enthuellt markiert (REVEAL_AMOUNT {1:F2}).", "[FinalAscent]", num)); } } internal static Vector3? CampOfStage(int key) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (key < 0) { return null; } int num = key / 16; int num2 = key % 16; foreach (FinalAscentStage item in AllStages()) { if (item.SegmentIndex == num && item.ChainIndex == num2) { return ((Object)(object)item.Campfire != (Object)null) ? new Vector3?(item.Campfire.transform.position) : ((Vector3?)null); } } return null; } internal static Vector3? EntryCampOfStage(int key) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) if (key < 0) { return null; } int num = key / 16; int num2 = key % 16; List list = new List(AllStages()); for (int i = 0; i < list.Count; i++) { if (list[i].SegmentIndex == num && list[i].ChainIndex == num2) { if (i > 0 && (Object)(object)list[i - 1].Campfire != (Object)null) { return list[i - 1].Campfire.transform.position; } return null; } } return null; } internal static bool RestoreToStage(int key) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) if (key < 0) { return false; } int num = key / 16; int num2 = key % 16; List all = new List(AllStages()); int target = -1; for (int i = 0; i < all.Count; i++) { if (all[i].SegmentIndex == num && all[i].ChainIndex == num2) { target = i; break; } } if (target < 0) { Plugin.Log.LogWarning((object)(string.Format("{0} Etappenstand {1} ist unbekannt - der Berg bleibt, wie Vanilla ", "[FinalAscent]", key) + "ihn gestellt hat.")); return false; } for (int j = 0; j < all.Count; j++) { FinalAscentStage stage = all[j]; if (j < target) { Guard($"{stage.Type} zuruecklassen", delegate { HideStage(stage); if ((Object)(object)stage.Campfire != (Object)null && !stage.Campfire.activeInHierarchy) { bool flag = false; Transform parent = stage.Campfire.transform.parent; while ((Object)(object)parent != (Object)null) { if ((Object)(object)stage.Terrain != (Object)null && (Object)(object)((Component)parent).gameObject == (Object)(object)stage.Terrain) { flag = true; break; } parent = parent.parent; } if (flag) { Plugin.Log.LogWarning((object)("[FinalAscent] Lagerfeuer '" + ((Object)stage.Campfire).name + "' haengt unter dem Gelaende - es anzuschalten wuerde die ganze Etappe zurueckholen. Bleibt aus.")); } else { WakeUp(stage.Campfire); Plugin.Log.LogInfo((object)("[FinalAscent] Lagerfeuer '" + ((Object)stage.Campfire).name + "' war aus und wurde angeschaltet - die Gruppe ist daran vorbeigekommen.")); } } }); } else { if (j != target) { continue; } Guard($"{stage.Type} zeigen", delegate { if ((Object)(object)stage.Root != (Object)null) { stage.Root.SetActive(true); } if ((Object)(object)stage.Terrain != (Object)null) { stage.Terrain.SetActive(true); } if ((Object)(object)stage.Campfire != (Object)null) { stage.Campfire.SetActive(true); } }); } } FinalAscentStage here = all[target]; Guard("Lagerfeuer nachtragen", delegate { FinalAscentCamps.Reset(); for (int k = 0; k <= target; k++) { if (!((Object)(object)all[k].Campfire == (Object)null)) { Campfire[] componentsInChildren = all[k].Campfire.GetComponentsInChildren(true); for (int l = 0; l < componentsInChildren.Length; l++) { FinalAscentCamps.NoteLit(componentsInChildren[l]); } } } Plugin.Log.LogInfo((object)("[FinalAscent] Lager beim Einstieg: '" + (((Object)(object)FinalAscentCamps.BaseCamp != (Object)null) ? ((Object)FinalAscentCamps.BaseCamp).name : "keines") + "'.")); }); Guard("Biom umschalten", delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) FinalAscentBiomes.EnterStage(here.Presence, here.Presence); }); Guard("Licht und Himmel", delegate { ApplyProfile(here); }); Guard("Physik abgleichen", (Action)Physics.SyncTransforms); Guard("Gelaende-Objekt nachfuehren", delegate { HandOverAllSegmentParents(all, target); }); Guard("Nebelwaende stellen", delegate { RestoreWalls(all, target); }); Guard("Musik nachziehen", delegate { RestoreAmbience(all, target); }); for (int num3 = 0; num3 <= target; num3++) { VisibleStage[all[num3].SegmentIndex] = all[num3]; } Plugin.Log.LogInfo((object)("[FinalAscent] Berg auf den Stand der Gruppe gebracht: " + here.Title + " " + $"(Etappe {target + 1} von {all.Count}).")); ReportActiveStages(); return true; } private static void RestoreAmbience(List all, int target) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) List list = new List(all.Count); foreach (FinalAscentStage item in all) { list.Add(item.Type); } FinalAscentAmbience.ArmForRestore(list, target); } private static void RestoreWalls(List all, int target) { FinalAscentStage finalAscentStage = all[target]; for (int i = 0; i < all.Count; i++) { FinalAscentStage finalAscentStage2 = all[i]; if (finalAscentStage2.WallKey < 0) { continue; } if (i == target) { FinalAscentBuilder.StageWallsOnSegmentEnter(finalAscentStage2.WallKey); } else if (i < target) { if (finalAscentStage2.SegmentIndex == finalAscentStage.SegmentIndex) { FinalAscentBuilder.StageWallsOnStageAdvance(finalAscentStage2.WallKey); } else { FinalAscentBuilder.StageWallsOnSegmentLeave(finalAscentStage2.WallKey); } } } MapHandler instance = Singleton.Instance; if ((Object)(object)instance == (Object)null || instance.segments == null) { return; } int on = 0; int off = 0; for (int j = 0; j < instance.segments.Length; j++) { MapSegment val = instance.segments[j]; if (val != null) { bool flag = j == finalAscentStage.SegmentIndex; Set(val.wallNext, flag, ref on, ref off); Set(val.wallPrevious, flag && j > 0, ref on, ref off); } } Plugin.Log.LogInfo((object)(string.Format("{0} Nebelwaende auf Segment {1} gestellt: ", "[FinalAscent]", finalAscentStage.SegmentIndex) + $"{on} an, {off} aus.")); } private static void Set(GameObject wall, bool want, ref int on, ref int off) { if (!((Object)(object)wall == (Object)null)) { wall.SetActive(want); if (want) { on++; } else { off++; } } } private static void HandOverAllSegmentParents(List all, int target) { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = new Dictionary(); for (int i = 0; i <= target; i++) { dictionary[all[i].SegmentIndex] = all[i]; } MapHandler instance = Singleton.Instance; if ((Object)(object)instance == (Object)null || instance.segments == null) { return; } foreach (KeyValuePair item in dictionary) { if (item.Key >= 0 && item.Key < instance.segments.Length && !((Object)(object)item.Value.Terrain == (Object)null)) { SegmentParentField.SetValue(instance.segments[item.Key], item.Value.Terrain); Plugin.Detail(string.Format("{0} Segment {1}: Gelaende-Objekt zeigt auf ", "[FinalAscent]", item.Key) + $"'{((Object)item.Value.Terrain).name}' ({item.Value.Type})."); } } } private static void SilentAdvance(FinalAscentStage stage, FinalAscentStage next) { Guard("Alte Etappe aus", delegate { HideStage(stage); }); Guard("Neue Etappe an", delegate { next.Root.SetActive(true); if ((Object)(object)next.Terrain != (Object)null) { next.Terrain.SetActive(true); } if ((Object)(object)next.Campfire != (Object)null) { next.Campfire.SetActive(true); } RetireOlderCampfires(next); FinalAscentBuilder.StageWallsOnStageAdvance(stage.WallKey); FinalAscentBuilder.StageWallsOnSegmentEnter(next.WallKey); Physics.SyncTransforms(); }); Guard("Etappe vormerken", delegate { VisibleStage[next.SegmentIndex] = next; }); Guard("Biom umschalten", delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) FinalAscentBiomes.EnterStage(stage.Presence, next.Presence); }); Guard("Licht und Himmel umstellen", delegate { ApplyProfile(next); }); Guard("Musik umstellen", delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) FinalAscentAmbience.OnStageAdvanced(stage.Type, next.Type); }); } internal static bool TryGetStage(Campfire campfire, out FinalAscentStage stage) { stage = null; if ((Object)(object)campfire != (Object)null) { return StageByCampfire.TryGetValue(campfire, out stage); } return false; } internal static void Wire() { StageByCampfire.Clear(); ReparentedCampfires.Clear(); FinalAscentCamps.Reset(); VisibleStage.Clear(); FirstStage.Clear(); _summitCampfire = null; MapHandler instance = Singleton.Instance; if ((Object)(object)instance == (Object)null || instance.segments == null || instance.variantSegments == null) { Plugin.Log.LogError((object)"[FinalAscent] MapHandler unvollstaendig - keine Verdrahtung moeglich."); return; } LevelGeneration val = Object.FindFirstObjectByType(); BiomeSelector[] selectors = (BiomeSelector[])(((Object)(object)val != (Object)null) ? ((Array)((Component)val).GetComponentsInChildren(true)) : ((Array)new BiomeSelector[0])); MergeSegment(instance, selectors, 1, 1, 1, (BiomeType)1, (BiomeType)7); MergeSegment(instance, selectors, 2, 2, 0, (BiomeType)2, (BiomeType)6); BuildKilnChain(instance, selectors); RegisterLoneSegments(instance); for (int i = 0; i < instance.segments.Length; i++) { if (instance.segments[i] != null && instance.segments[i].hasVariant) { instance.segments[i].hasVariant = false; Plugin.Detail(string.Format("{0} Segment {1}: Varianten-Umleitung abgeschaltet.", "[FinalAscent]", i)); } } FinalAscentProgress.Rebuild(); FinalAscentBiomes.Capture(instance); FinalAscentAmbience.Apply(); } private static void MergeSegment(MapHandler map, BiomeSelector[] selectors, int segmentIndex, int selectorIndex, int variantIndex, BiomeType first, BiomeType second) { //IL_0082: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) if (segmentIndex >= map.segments.Length || variantIndex >= map.variantSegments.Length) { Plugin.Log.LogError((object)string.Format("{0} Segment {1}: Index ausserhalb.", "[FinalAscent]", segmentIndex)); return; } MapSegment val = map.segments[segmentIndex]; MapSegment val2 = map.variantSegments[variantIndex]; if (val == null || val2 == null || selectorIndex >= selectors.Length) { Plugin.Log.LogError((object)string.Format("{0} Segment {1}: fehlende Daten.", "[FinalAscent]", segmentIndex)); return; } GameObject gameObject = ((Component)selectors[selectorIndex]).gameObject; GameObject val3 = FindBiomeRoot(selectors[selectorIndex], first); GameObject val4 = FindBiomeRoot(selectors[selectorIndex], second); if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null) { Plugin.Log.LogError((object)string.Format("{0} Segment {1}: {2} oder {3} nicht gefunden.", "[FinalAscent]", segmentIndex, first, second)); return; } object? value = SegmentCampfireField.GetValue(val); GameObject val5 = (GameObject)((value is GameObject) ? value : null); object? value2 = SegmentCampfireField.GetValue(val2); GameObject val6 = (GameObject)((value2 is GameObject) ? value2 : null); if ((Object)(object)val6 != (Object)null) { val6.transform.SetParent(((Component)map).transform, true); val6.SetActive(false); } FinalAscentStage finalAscentStage = new FinalAscentStage { Type = second, Presence = second, Title = TitleOf(second), Root = val4, SegmentIndex = segmentIndex, Campfire = val6, Terrain = (GameObject)/*isinst with value type is only supported in some contexts*/, Profile = (DayNightProfile)/*isinst with value type is only supported in some contexts*/ }; FinalAscentStage finalAscentStage2 = new FinalAscentStage { Type = first, Presence = first, Title = TitleOf(first), Root = val3, SegmentIndex = segmentIndex, Campfire = val5, Terrain = (GameObject)/*isinst with value type is only supported in some contexts*/, Profile = (DayNightProfile)/*isinst with value type is only supported in some contexts*/, Next = finalAscentStage }; finalAscentStage2.ChainIndex = 0; finalAscentStage.ChainIndex = 1; finalAscentStage2.WallKey = segmentIndex; RegisterStageCampfires(val5, finalAscentStage2); VisibleStage[segmentIndex] = finalAscentStage2; FirstStage[segmentIndex] = finalAscentStage2; int num = (((Object)(object)finalAscentStage2.Terrain != (Object)null) ? finalAscentStage2.Terrain.GetComponentsInChildren(true).Length : (-1)); int num2 = (((Object)(object)finalAscentStage2.Terrain != (Object)null) ? finalAscentStage2.Terrain.GetComponentsInChildren(true).Length : (-1)); int num3 = gameObject.GetComponentsInChildren(true).Length; Plugin.Detail(string.Format("{0} Segment {1}: segmentParent bleibt ", "[FinalAscent]", segmentIndex) + "'" + (((Object)(object)finalAscentStage2.Terrain != (Object)null) ? ((Object)finalAscentStage2.Terrain).name : "?") + "' " + $"({num} EnablingSubsteps, {num2} Spawner) statt " + $"'{((Object)gameObject).name}' ({num3} Spawner)."); val4.SetActive(false); Plugin.Detail(string.Format("{0} Segment {1}: '{2}' = {3} -> ", "[FinalAscent]", segmentIndex, ((Object)gameObject).name, first) + string.Format("[{0}] -> {1} -> ", ((Object)(object)val5 != (Object)null) ? ((Object)val5).name : "-", second) + "[" + (((Object)(object)val6 != (Object)null) ? ((Object)val6).name : "-") + "]"); } private static void BuildKilnChain(MapHandler map, BiomeSelector[] selectors) { //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) if (selectors.Length < 4 || map.segments.Length < 5 || map.variantSegments.Length < 4) { Plugin.Log.LogError((object)"[FinalAscent] Segment 4: Daten unvollstaendig, Gloom bleibt aus."); return; } GameObject val = FindBiomeRoot(selectors[3], (BiomeType)3); GameObject val2 = FindBiomeRoot(selectors[3], (BiomeType)8); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { Plugin.Log.LogError((object)"[FinalAscent] Segment 4: Caldera- oder Gloom-Wurzel fehlt."); return; } MapSegment val3 = map.segments[4]; MapSegment obj = map.variantSegments[2]; MapSegment obj2 = map.variantSegments[3]; object? value = SegmentParentField.GetValue(val3); GameObject val4 = (GameObject)((value is GameObject) ? value : null); object? value2 = SegmentParentField.GetValue(obj); GameObject val5 = (GameObject)((value2 is GameObject) ? value2 : null); object? value3 = SegmentParentField.GetValue(obj2); GameObject val6 = (GameObject)((value3 is GameObject) ? value3 : null); object? value4 = SegmentCampfireField.GetValue(obj); GameObject val7 = (GameObject)((value4 is GameObject) ? value4 : null); if ((Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null) { Plugin.Log.LogError((object)"[FinalAscent] Segment 4: ein Gelaende-Objekt fehlt."); return; } GameObject val8 = CreateKilnSummitCampfire(map, val4); if ((Object)(object)val8 == (Object)null) { Plugin.Log.LogError((object)"[FinalAscent] Segment 4: kein Gipfel-Lagerfeuer - der Weg nach Gloom bleibt zu."); return; } SegmentCampfireField.SetValue(val3, val8); FinalAscentStage finalAscentStage = new FinalAscentStage { Type = (BiomeType)9, Presence = (BiomeType)8, Title = "THE CITADEL", Root = val2, Terrain = val6, SegmentIndex = 4, Profile = (DayNightProfile)/*isinst with value type is only supported in some contexts*/ }; FinalAscentStage finalAscentStage2 = new FinalAscentStage { Type = (BiomeType)8, Presence = (BiomeType)8, Title = "GLOOM", Root = val2, Terrain = val5, Campfire = val7, SegmentIndex = 4, TerrainOnly = true, Next = finalAscentStage, Profile = (DayNightProfile)/*isinst with value type is only supported in some contexts*/ }; FinalAscentStage finalAscentStage3 = new FinalAscentStage { Type = (BiomeType)3, Presence = (BiomeType)3, Title = "THE KILN", Root = val, Terrain = val4, Campfire = val8, SegmentIndex = 4, TerrainOnly = true, Next = finalAscentStage2, Profile = (DayNightProfile)/*isinst with value type is only supported in some contexts*/ }; finalAscentStage3.WallKey = 40; finalAscentStage2.WallKey = 41; RegisterStageCampfires(val8, finalAscentStage3); RegisterStageCampfires(val7, finalAscentStage2); VisibleStage[4] = finalAscentStage3; finalAscentStage3.ChainIndex = 0; finalAscentStage2.ChainIndex = 1; finalAscentStage.ChainIndex = 2; FirstStage[4] = finalAscentStage3; Campfire componentInChildren = val8.GetComponentInChildren(true); GameObject source = (((Object)(object)map.segments[3].wallNext != (Object)null) ? map.segments[3].wallNext : val3.wallPrevious); FinalAscentBuilder.CreateStageWallPairAt(finalAscentStage3.WallKey, source, ((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).transform.position : val8.transform.position, 40f, -30f, val3.wallPrevious); if ((Object)(object)val7 != (Object)null) { FinalAscentBuilder.CreateStageWallPairAt(finalAscentStage2.WallKey, source, val7.transform.position, 40f, -30f, val3.wallPrevious); } val6.SetActive(false); val5.SetActive(true); val2.SetActive(false); Plugin.Detail("[FinalAscent] Segment 4: " + ((Object)val4).name + " -> [" + ((Object)val8).name + "] -> " + ((Object)val5).name + " -> [" + (((Object)(object)val7 != (Object)null) ? ((Object)val7).name : "-") + "] -> " + ((Object)val6).name + " -> GIPFEL"); } private static GameObject CreateKilnSummitCampfire(MapHandler map, GameObject kilnTerrain) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0104: 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_0126: Unknown result type (might be due to invalid IL or missing references) object? value = SegmentCampfireField.GetValue(map.segments[3]); GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"[FinalAscent] Kein Vorlagen-Lagerfeuer in Segment 3."); return null; } Vector3 val2 = FinalAscentBuilder.KilnSummit() + Vector3.up * 0f; GameObject val3 = Object.Instantiate(val, val2, val.transform.rotation); ((Object)val3).name = "FA_KilnSummitCampfire"; val3.transform.SetParent(((Component)map).transform, true); Campfire componentInChildren = val3.GetComponentInChildren(true); Vector3 val4 = val2; if ((Object)(object)componentInChildren != (Object)null) { Transform transform = val3.transform; transform.position += val4 - ((Component)componentInChildren).transform.position; Plugin.Detail("[FinalAscent] Feuer steht auf " + FinalAscentBuilder.Fmt(((Component)componentInChildren).transform.position) + "."); } else { Plugin.Log.LogWarning((object)"[FinalAscent] Kopie enthaelt keine Campfire-Komponente."); } FreshViewIDs(val3); val3.SetActive(false); List taken = new List(); GameObject val5 = CloneScoutStatue(map, val3, kilnTerrain, val4, taken); int num = CloneLuggage(val3, kilnTerrain, val4, taken); Plugin.Log.LogInfo((object)("[FinalAscent] Gipfel-Lagerfeuer bei " + FinalAscentBuilder.Fmt(val4) + ", " + string.Format("{0}, {1} Koffer.", ((Object)(object)val5 != (Object)null) ? "Statue" : "OHNE Statue", num))); return val3; } private static GameObject CloneScoutStatue(MapHandler map, GameObject campfireClone, GameObject kilnTerrain, Vector3 campfire, List taken) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) Transform val = null; RespawnChest[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (RespawnChest val2 in array) { if (!((Object)(object)val2 == (Object)null)) { Biome componentInParent = ((Component)val2).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.biomeType == 3) { val = (((Object)(object)((Component)val2).transform.parent != (Object)null) ? ((Component)val2).transform.parent : ((Component)val2).transform); break; } } } if ((Object)(object)val == (Object)null) { val = FindCampfireGroup("Respawn_Beach", typeof(RespawnChest)) ?? FindCampfireGroup("Respawn_Jungle", typeof(RespawnChest)) ?? FindCampfireGroup("Respawn_", typeof(RespawnChest)); Plugin.Log.LogWarning((object)("[FinalAscent] Keine Statue in der Caldera gefunden - " + (((Object)(object)val != (Object)null) ? "es wird die vom Strand kopiert." : "keine Gipfelstatue."))); } if ((Object)(object)val == (Object)null) { return null; } Vector3 val3 = FinalAscentBuilder.FindFlatSpot(kilnTerrain, campfire, new Vector3(12f, 0f, -3f), taken, 4f); Transform parent = val.parent; Vector3 position = val.position; Quaternion rotation = val.rotation; int siblingIndex = val.GetSiblingIndex(); GameObject val4 = PlaceGroup(val, val3, campfireClone, "FA_KilnSummitStatue", 0.25f); if ((Object)(object)val4 != (Object)null && ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy)) { GameObject obj = Object.Instantiate(val4, position, rotation, parent); ((Object)obj).name = "FA_CalderaStatue"; obj.transform.SetSiblingIndex(siblingIndex); FreshViewIDs(obj); obj.SetActive(true); Plugin.Log.LogWarning((object)("[FinalAscent] Die Vorlage ist beim Kopieren abhanden gekommen - aus unserer Kopie bei " + FinalAscentBuilder.Fmt(position) + " ersetzt.")); } StandFreeAndStraight(val4, val3); Plugin.Log.LogInfo((object)("[FinalAscent] Statue aus '" + ((Object)val).name + "' auf Boden " + FinalAscentBuilder.Fmt(val3) + ".")); return val4; } private static void StandFreeAndStraight(GameObject statue, Vector3 ground) { //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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)statue == (Object)null) { return; } RespawnChest componentInChildren = statue.GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { return; } List list = new List(); Renderer[] componentsInChildren = statue.GetComponentsInChildren(true); Bounds bounds; foreach (Renderer val in componentsInChildren) { if (((Component)val).gameObject.activeSelf && !IsParticles(val)) { bounds = val.bounds; float y = ((Bounds)(ref bounds)).size.y; if (y > 5f) { ((Component)val).gameObject.SetActive(false); list.Add($"{((Object)val).name} ({y:F0} hoch)"); } } } Transform val2 = ((Component)componentInChildren).transform.Find("Fake Ground Plane"); if ((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeSelf) { ((Component)val2).gameObject.SetActive(false); list.Add("Fake Ground Plane"); } Vector3 position = ((Component)componentInChildren).transform.position; float num = Vector3.Angle(statue.transform.up, Vector3.up); statue.transform.rotation = Quaternion.FromToRotation(statue.transform.up, Vector3.up) * statue.transform.rotation; Transform transform = statue.transform; transform.position += position - ((Component)componentInChildren).transform.position; float num2 = float.NaN; componentsInChildren = statue.GetComponentsInChildren(true); foreach (Renderer val3 in componentsInChildren) { if (val3.enabled && ((Component)val3).gameObject.activeSelf && !IsParticles(val3)) { bounds = val3.bounds; float y2 = ((Bounds)(ref bounds)).min.y; num2 = (float.IsNaN(num2) ? y2 : Mathf.Min(num2, y2)); } } if (!float.IsNaN(num2)) { Transform transform2 = statue.transform; transform2.position += Vector3.up * (ground.y - num2 - 0.75f); } float num3 = 0f; Plugin.Log.LogInfo((object)("[FinalAscent] Gipfelstatue: " + ((list.Count > 0) ? (string.Join(" + ", list) + " abgeschaltet") : "kein Podest gefunden") + ", " + $"Unterkante auf {ground.y:F1} gesetzt, " + $"Neigung {num:F0} Grad herausgenommen, " + ((Mathf.Abs(num3) > 0.01f) ? $"um {num3:F2} nachgesetzt." : "Hoehe passte."))); } private static void LieFlat(GameObject bag, Vector3 ground) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bag == (Object)null) { return; } Vector3 val = Vector3.up; RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(ground + Vector3.up * 5f, Vector3.down, ref val2, 20f, -1, (QueryTriggerInteraction)1)) { val = ((RaycastHit)(ref val2)).normal; } Luggage componentInChildren = bag.GetComponentInChildren(true); if (!((Object)(object)componentInChildren != (Object)null)) { _ = bag.transform.position; } else { _ = ((Component)componentInChildren).transform.position; } float num = Vector3.Angle(bag.transform.up, val); float num2 = float.NaN; MeshFilter[] componentsInChildren = bag.GetComponentsInChildren(true); foreach (MeshFilter val3 in componentsInChildren) { if (!((Object)(object)val3.sharedMesh == (Object)null) && IsOn(((Component)val3).transform, bag.transform)) { num2 = Lowest(num2, val3.sharedMesh.bounds, ((Component)val3).transform); } } float num3 = 0f; if (!float.IsNaN(num2)) { num3 = ground.y - num2; Transform transform = bag.transform; transform.position += Vector3.up * num3; } Plugin.Detail("[FinalAscent] '" + ((Object)bag).name + "' liegt auf: Boden geneigt um " + $"{Vector3.Angle(Vector3.up, val):F0} Grad, Kippung {num:F0} Grad" + ((Mathf.Abs(num3) > 0.01f) ? $", um {num3:F2} nachgesetzt." : ", Hoehe passte.")); } private static bool IsParticles(Renderer renderer) { return ((object)renderer).GetType().Name == "ParticleSystemRenderer"; } private static bool IsOn(Transform leaf, Transform root) { Transform val = leaf; while ((Object)(object)val != (Object)null) { if (!((Component)val).gameObject.activeSelf) { return false; } if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } return true; } private static float Lowest(float sofar, Bounds local, Transform where) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) Vector3 center = ((Bounds)(ref local)).center; Vector3 extents = ((Bounds)(ref local)).extents; Vector3 val = default(Vector3); for (int i = 0; i < 8; i++) { ((Vector3)(ref val))..ctor(center.x + (((i & 1) == 0) ? (0f - extents.x) : extents.x), center.y + (((i & 2) == 0) ? (0f - extents.y) : extents.y), center.z + (((i & 4) == 0) ? (0f - extents.z) : extents.z)); float y = where.TransformPoint(val).y; if (float.IsNaN(sofar) || y < sofar) { sofar = y; } } return sofar; } private static void FromGloomPool(GameObject bag) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) Luggage[] componentsInChildren = bag.GetComponentsInChildren(true); foreach (Luggage obj in componentsInChildren) { ((Spawner)obj).spawnMode = (SpawnMode)1; ((Spawner)obj).spawnPool = (SpawnPool)268435456; } } private static string RelativePath(Transform root, Transform leaf) { string text = ""; Transform val = leaf; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root) { text = ((text.Length == 0) ? ((Object)val).name : (((Object)val).name + "/" + text)); val = val.parent; } return text; } private static int CloneLuggage(GameObject campfireClone, GameObject kilnTerrain, Vector3 campfire, List taken) { //IL_0046: 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_0061: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) Transform val = FindCampfireGroup("LuggageSpawner", typeof(Luggage)); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[FinalAscent] Keinen Koffer an einem normalen Lagerfeuer gefunden."); return 0; } Vector3[] array = (Vector3[])(object)new Vector3[2] { new Vector3(-5f, 0f, -3f), new Vector3(-3f, 0f, 5f) }; int num = 0; for (int i = 0; i < array.Length; i++) { Vector3 ground = FinalAscentBuilder.FindFlatSpot(kilnTerrain, campfire, array[i], taken, 3f); GameObject bag = PlaceGroup(val, ground, campfireClone, "FA_KilnSummitLuggage" + i, 0f); LieFlat(bag, ground); FromGloomPool(bag); num++; } Plugin.Detail(string.Format("{0} {1} Koffer aus '{2}' kopiert.", "[FinalAscent]", num, ((Object)val).name)); Luggage[] componentsInChildren = campfireClone.GetComponentsInChildren(true); foreach (Luggage val2 in componentsInChildren) { Plugin.Detail("[FinalAscent] Koffer '" + ((Object)val2).name + "' bei " + FinalAscentBuilder.Fmt(((Component)val2).transform.position) + ", " + $"sichtbar={((Component)val2).gameObject.activeInHierarchy}, " + $"Renderer={((Component)val2).GetComponentsInChildren(true).Length}"); } return num; } private static GameObject PlaceGroup(Transform group, Vector3 ground, GameObject parent, string name, float sink = 0f) where T : Component { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) T componentInChildren = ((Component)group).GetComponentInChildren(true); float num = (((Object)(object)componentInChildren != (Object)null) ? FinalAscentBuilder.HeightAboveGround(((Component)componentInChildren).gameObject) : 0f); float num2 = ((num <= 3f) ? num : 0f); if (!Mathf.Approximately(num2, num)) { Plugin.Detail(string.Format("{0} '{1}': gemessener Abstand {2:F1} ist unplausibel, ", "[FinalAscent]", name, num) + $"{num2:F1} gilt."); } Vector3 val = ground + Vector3.up * (num2 - sink); bool activeSelf = ((Component)group).gameObject.activeSelf; ((Component)group).gameObject.SetActive(false); GameObject val2 = Object.Instantiate(((Component)group).gameObject, val, group.rotation); FreshViewIDs(val2); ((Component)group).gameObject.SetActive(activeSelf); ((Object)val2).name = name; T componentInChildren2 = val2.GetComponentInChildren(true); if ((Object)(object)componentInChildren2 != (Object)null) { Vector3 val3 = val - ((Component)componentInChildren2).transform.position; Transform transform = val2.transform; transform.position += val3; if (((Vector3)(ref val3)).sqrMagnitude > 1f) { Plugin.Detail("[FinalAscent] '" + name + "' um " + FinalAscentBuilder.Fmt(val3) + " nachgerueckt."); } int num3 = 0; Transform val4 = ((Component)componentInChildren2).transform; while ((Object)(object)val4 != (Object)null && (Object)(object)val4 != (Object)(object)val2.transform.parent) { if (!((Component)val4).gameObject.activeSelf) { ((Component)val4).gameObject.SetActive(true); num3++; } val4 = val4.parent; } Transform[] componentsInChildren = ((Component)((Component)componentInChildren2).transform).GetComponentsInChildren(true); foreach (Transform val5 in componentsInChildren) { if (!((Component)val5).gameObject.activeSelf && ((Object)val5).name.IndexOf("statue", StringComparison.OrdinalIgnoreCase) >= 0) { ((Component)val5).gameObject.SetActive(true); num3++; Plugin.Log.LogInfo((object)("[FinalAscent] '" + name + "': '" + ((Object)val5).name + "' war abgeschaltet - eingeblendet.")); } } if (num3 > 0) { Plugin.Detail(string.Format("{0} '{1}': {2} abgeschaltete Ebenen eingeschaltet.", "[FinalAscent]", name, num3)); } } FreshViewIDs(val2); val2.transform.SetParent(parent.transform, true); val2.SetActive(true); if (((Component)group).gameObject.activeSelf != activeSelf) { ((Component)group).gameObject.SetActive(activeSelf); Plugin.Log.LogWarning((object)("[FinalAscent] Vorlage '" + ((Object)group).name + "' hatte sich beim Kopieren umgestellt - zurueckgesetzt.")); } Plugin.Detail("[FinalAscent] Vorlage '" + ((Object)group).name + "' steht weiter bei " + $"{FinalAscentBuilder.Fmt(group.position)}, sichtbar={((Component)group).gameObject.activeInHierarchy}."); return val2; } private static Transform FindCampfireGroup(string prefix) { return FindCampfireGroup(prefix, null); } private static Transform FindCampfireGroup(string prefix, Type mustContain) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) Transform[] array = Resources.FindObjectsOfTypeAll(); foreach (Transform val in array) { if (((Object)val).name.StartsWith(prefix) && !((Object)(object)val.parent == (Object)null) && ((Object)val.parent).name.EndsWith("_Campfire")) { Scene scene = ((Component)val).gameObject.scene; if (((Scene)(ref scene)).IsValid() && (!(mustContain != null) || !((Object)(object)((Component)val).GetComponentInChildren(mustContain, true) == (Object)null))) { return val; } } } return null; } internal static string PlaceSummitCampfireAtPlayer() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_008c: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { return "KEIN SPIELER"; } if ((Object)(object)_summitCampfire == (Object)null) { return "KEIN GIPFEL-LAGERFEUER"; } Vector3 val = localCharacter.Center + Vector3.down * 1.5f; Campfire componentInChildren = _summitCampfire.GetComponentInChildren(true); Vector3 val2 = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).transform.position : _summitCampfire.transform.position); Transform transform = _summitCampfire.transform; transform.position += val - val2; Physics.SyncTransforms(); Vector3 val3 = FinalAscentBuilder.KilnSummit(); Plugin.Log.LogInfo((object)("[FinalAscent] Gipfel-Lagerfeuer versetzt: " + FinalAscentBuilder.Fmt(val2) + " -> " + FinalAscentBuilder.Fmt(val) + ". Gegenueber der gerechneten Stelle " + FinalAscentBuilder.Fmt(val3) + " ergibt das KilnCampfireShift = " + FinalAscentBuilder.Fmt(FinalAscentBuilder.KilnCampfireShift + (val - val3)) + ".")); return $"LAGERFEUER GESETZT ({val.x:F0} / {val.y:F0} / {val.z:F0})"; } private static void FreshViewIDs(GameObject clone) { PhotonView[] componentsInChildren = clone.GetComponentsInChildren(true); foreach (PhotonView val in componentsInChildren) { val.ViewID = 0; if (SceneViewIdField != null) { SceneViewIdField.SetValue(val, 0); } } } internal static void WallsOnSegmentLeave(int segment) { for (FinalAscentStage finalAscentStage = Get(FirstStage, segment); finalAscentStage != null; finalAscentStage = finalAscentStage.Next) { FinalAscentBuilder.StageWallsOnSegmentLeave(finalAscentStage.WallKey); } } internal static void WallsOnSegmentEnter(int segment) { FinalAscentStage finalAscentStage = Get(FirstStage, segment); if (finalAscentStage != null) { FinalAscentBuilder.StageWallsOnSegmentEnter(finalAscentStage.WallKey); } } private static FinalAscentStage Get(Dictionary map, int key) { if (!map.TryGetValue(key, out var value)) { return null; } return value; } internal static void HandOverSegmentParent(int leavingSegment) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) MapHandler instance = Singleton.Instance; if (instance?.segments != null && leavingSegment >= 0 && leavingSegment < instance.segments.Length && VisibleStage.TryGetValue(leavingSegment, out var value) && value != null) { GameObject toDeactivate = value.ToDeactivate; if (!((Object)(object)toDeactivate == (Object)null)) { SegmentParentField.SetValue(instance.segments[leavingSegment], toDeactivate); Plugin.Detail(string.Format("{0} Segment {1} wird verlassen: segmentParent zeigt jetzt auf ", "[FinalAscent]", leavingSegment) + $"'{((Object)toDeactivate).name}' (sichtbare Etappe {value.Type})."); } } } private static string TitleOf(BiomeType biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected I4, but got Unknown return (int)biome switch { 0 => "SHORE", 1 => "TROPICS", 7 => "ROOTS", 2 => "ALPINE", 6 => "MESA", 3 => "THE KILN", 8 => "GLOOM", 9 => "THE CITADEL", _ => null, }; } private static GameObject FindBiomeRoot(BiomeSelector selector, BiomeType type) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) foreach (BiomeOption biome in selector.Biomes) { if (biome != null && (Object)(object)biome.biomeParent != (Object)null && biome.biomeParent.biomeType == type) { return ((Component)biome.biomeParent).gameObject; } } return null; } private static void RegisterStageCampfires(GameObject campfireRoot, FinalAscentStage stage) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)campfireRoot == (Object)null)) { Campfire[] componentsInChildren = campfireRoot.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { StageByCampfire[componentsInChildren[i]] = stage; Plugin.Detail("[FinalAscent] Etappen-Lagerfeuer registriert: '" + ((Object)componentsInChildren[i]).name + "' " + $"(unter '{((Object)campfireRoot).name}') -> wechselt zu {stage.Next?.Type}"); } if (componentsInChildren.Length == 0) { Plugin.Log.LogError((object)("[FinalAscent] '" + ((Object)campfireRoot).name + "' enthaelt keine Campfire-Komponente - der Etappenwechsel kann nie ausgeloest werden.")); } } } internal static void AdvanceStage(FinalAscentStage stage, Campfire litCampfire) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (stage?.Next == null) { return; } if (VisibleStage.TryGetValue(stage.SegmentIndex, out var value) && value != null && value.ChainIndex >= stage.Next.ChainIndex) { Plugin.Log.LogInfo((object)(string.Format("{0} Etappenwechsel nach {1} uebersprungen - ", "[FinalAscent]", stage.Next.Type) + $"{value.Type} steht bereits (nachgeholter Ruf).")); return; } MapHandler instance = Singleton.Instance; if (!((Object)(object)instance == (Object)null)) { ((MonoBehaviour)instance).StartCoroutine(AdvanceRoutine(stage, litCampfire)); } } private static IEnumerator AdvanceRoutine(FinalAscentStage stage, Campfire litCampfire) { FinalAscentStage next = stage.Next; OrbFogHandler fog = Singleton.Instance; Plugin.Log.LogInfo((object)string.Format("{0} Etappenwechsel {1} -> {2}: Nebel zieht zu.", "[FinalAscent]", stage.Type, next.Type)); if ((Object)(object)fog != (Object)null) { Guard("Nebelkugel sichtbar machen", delegate { EnsureSphereVisible(fog); }); yield return fog.WaitForFogCatchUp(); yield return (object)new WaitForSecondsRealtime(1f); } Guard("Alte Etappe aus", delegate { HideStage(stage); }); yield return null; Guard("Neue Etappe an", delegate { next.Root.SetActive(true); if ((Object)(object)next.Terrain != (Object)null) { next.Terrain.SetActive(true); } if ((Object)(object)next.Campfire != (Object)null) { next.Campfire.SetActive(true); } RetireOlderCampfires(next); FinalAscentBuilder.StageWallsOnStageAdvance(stage.WallKey); FinalAscentBuilder.StageWallsOnSegmentEnter(next.WallKey); Physics.SyncTransforms(); }); Plugin.Detail(string.Format("{0} {1} aktiv={2}", "[FinalAscent]", next.Type, next.Root.activeInHierarchy)); Guard("Etappe vormerken", delegate { VisibleStage[next.SegmentIndex] = next; }); Guard("Stand hinterlegen", delegate { FinalAscentRoom.PublishStage(KeyOf(next)); }); Guard("Biom umschalten", delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) FinalAscentBiomes.EnterStage(stage.Presence, next.Presence); }); Guard("Licht und Himmel umstellen", delegate { ApplyProfile(next); }); Guard("Musik umstellen", delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) FinalAscentAmbience.OnStageAdvanced(stage.Type, next.Type); }); Guard("Spawner ausloesen", delegate { SpawnStageItems(next); }); Guard("Lagerfeuer bestuecken", delegate { StockCampfire(next); }); Guard("Biom-Titel zeigen", delegate { FinalAscentProgress.ShowStageTitle(next.Title); }); if ((Object)(object)fog != (Object)null) { yield return (object)new WaitForSeconds(0.5f); yield return fog.WaitForReveal(); Guard("Nebelursprung setzen", delegate { MoveFogToStage(litCampfire, next); }); } yield return (object)new WaitForSeconds(2f); Guard("Lichtstimmung pruefen", delegate { DayNightManager instance = DayNightManager.instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)next.Profile == (Object)null) && !((Object)(object)instance.currentProfile == (Object)(object)next.Profile) && !((Object)(object)instance.newProfile == (Object)(object)next.Profile)) { Plugin.Log.LogWarning((object)("[FinalAscent] Lichtstimmung steht auf '" + (((Object)(object)instance.currentProfile != (Object)null) ? ((Object)instance.currentProfile).name : "-") + "' statt '" + ((Object)next.Profile).name + "' - wird nachgezogen.")); ApplyProfile(next); } }); Plugin.Log.LogInfo((object)string.Format("{0} Etappe {1} steht.", "[FinalAscent]", next.Type)); Guard("Sichtbares zaehlen", ReportActiveStages); if (Plugin.Diagnosing) { Character localCharacter = Character.localCharacter; FinalAscentWallProbe.Dump(((object)Unsafe.As(ref next.Type)/*cast due to .constrained prefix*/).ToString(), ((Object)(object)localCharacter != (Object)null) ? localCharacter.Center : (((Object)(object)next.Campfire != (Object)null) ? next.Campfire.transform.position : Vector3.zero)); } } private static void HideStage(FinalAscentStage stage) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) if (stage.TerrainOnly) { if ((Object)(object)stage.Terrain != (Object)null) { stage.Terrain.SetActive(false); } Plugin.Detail(string.Format("{0} {1}: '{2}' aus, ", "[FinalAscent]", stage.Type, ((Object)(object)stage.Terrain != (Object)null) ? ((Object)stage.Terrain).name : "-") + "Wurzel '" + ((Object)stage.Root).name + "' bleibt (naechste Etappe haengt darunter)."); return; } Transform transform = stage.Root.transform; for (int i = 0; i < transform.childCount; i++) { GameObject gameObject = ((Component)transform.GetChild(i)).gameObject; if (!((Object)(object)stage.Campfire != (Object)null) || !((Object)(object)gameObject == (Object)(object)stage.Campfire)) { gameObject.SetActive(false); } } Plugin.Detail(string.Format("{0} {1}: Gelaende und Wetter aus, ", "[FinalAscent]", stage.Type) + "'" + (((Object)(object)stage.Campfire != (Object)null) ? ((Object)stage.Campfire).name : "-") + "' bleibt stehen."); } private static void ApplyProfile(FinalAscentStage stage) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)DayNightManager.instance == (Object)null) { Plugin.Log.LogWarning((object)"[FinalAscent] Kein DayNightManager - Licht bleibt wie es ist."); return; } if ((Object)(object)stage.Profile == (Object)null) { Plugin.Log.LogWarning((object)string.Format("{0} {1} hat kein DayNightProfile hinterlegt.", "[FinalAscent]", stage.Type)); return; } FinalAscentBuilder.HeightFog.SetLift(FinalAscentBuilder.Offsets.TryGetValue(stage.Presence, out var value) ? value.y : 0f, ((object)Unsafe.As(ref stage.Type)/*cast due to .constrained prefix*/).ToString()); DayNightManager.instance.BlendProfiles(stage.Profile); Plugin.Detail(string.Format("{0} Lichtstimmung '{1}' fuer {2} ", "[FinalAscent]", ((Object)stage.Profile).name, stage.Type) + $"(Sonne {stage.Profile.sunIntensity:F1}); vorher lief " + "'" + (((Object)(object)DayNightManager.instance.currentProfile != (Object)null) ? ((Object)DayNightManager.instance.currentProfile).name : "-") + "'."); } private static void RetireOlderCampfires(FinalAscentStage current) { if ((Object)(object)current.Campfire != (Object)null && !ReparentedCampfires.Contains(current.Campfire)) { ReparentedCampfires.Add(current.Campfire); } int num = Mathf.Max(0, ReparentedCampfires.Count - 1); for (int i = 0; i < ReparentedCampfires.Count; i++) { GameObject val = ReparentedCampfires[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)current.Campfire) && i < num) { val.SetActive(false); Plugin.Detail("[FinalAscent] Altes Lagerfeuer '" + ((Object)val).name + "' abgeschaltet."); } } } private static void Guard(string what, Action action) { try { action(); } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("{0} FEHLER beim Etappenwechsel ({1}): {2}", "[FinalAscent]", what, arg)); } } private static void EnsureSphereVisible(OrbFogHandler fog) { object? obj = AccessTools.Field(typeof(OrbFogHandler), "sphere")?.GetValue(fog); Component val = (Component)((obj is Component) ? obj : null); if (val != null) { val.gameObject.SetActive(true); } } private static void MoveFogToStage(Campfire litCampfire, FinalAscentStage next) { //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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) OrbFogHandler instance = Singleton.Instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)litCampfire == (Object)null)) { Vector3 position = ((Component)litCampfire).transform.position; Vector3 val = (((Object)(object)next?.Campfire != (Object)null) ? next.Campfire.transform.position : (position + new Vector3(0f, 300f, 400f))); float num = Vector3.Distance(position, val); GameObject val2 = new GameObject("FA_FogOrigin_" + ((next != null) ? ((object)Unsafe.As(ref next.Type)/*cast due to .constrained prefix*/).ToString() : "?")); val2.transform.position = val; FogSphereOrigin val3 = val2.AddComponent(); float num2 = VanillaOriginSize(instance, next?.SegmentIndex ?? (-1)); val3.size = Mathf.Max(num2, (num > num2) ? RadiusForStage(num) : 0f); val3.moveOnHeight = position.y - 0.07f * (val.y - position.y); val3.moveOnForward = position.z + 0.18f * (val.z - position.z); float num3 = val3.moveOnForward - position.z; instance.hasArrived = false; EnsureSphereVisible(instance); instance.InitNewSphere(val3); Plugin.Detail(string.Format("{0} Nebelursprung auf {1}, Radius {2:F0} ", "[FinalAscent]", FinalAscentBuilder.Fmt(val), val3.size) + $"(Vanilla {num2:F0}) fuer {num:F0} Einheiten Etappe, " + $"Aufstiegsschwelle y={val3.moveOnHeight:F0} z={val3.moveOnForward:F0} " + $"({num3:F0} Vorsprung)."); } } private static void StockCampfire(FinalAscentStage stage) { if (PhotonNetwork.IsMasterClient && !((Object)(object)stage.Campfire == (Object)null)) { if (SpawnCampfireItemsMethod == null) { Plugin.Log.LogWarning((object)"[FinalAscent] SpawnCampfireItems nicht gefunden - Lagerfeuer bleibt leer."); return; } SpawnCampfireItemsMethod.Invoke(null, new object[2] { stage.Campfire, false }); int num = stage.Campfire.GetComponentsInChildren().Length; Plugin.Detail(string.Format("{0} Lagerfeuer '{1}' bestueckt ({2} Spawner).", "[FinalAscent]", ((Object)stage.Campfire).name, num)); } } private static float VanillaOriginSize(OrbFogHandler fog, int segmentIndex) { if (!(AccessTools.Field(typeof(OrbFogHandler), "origins")?.GetValue(fog) is FogSphereOrigin[] array) || segmentIndex < 0 || segmentIndex >= array.Length || (Object)(object)array[segmentIndex] == (Object)null) { return 750f; } return array[segmentIndex].size; } internal static float RadiusForStage(float stageLength) { return Mathf.Max(650f, stageLength * 1.2f + 80f); } private static void SpawnStageItems(FinalAscentStage stage) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient) { return; } ISpawner[] componentsInChildren = stage.Root.GetComponentsInChildren(); int num = 0; int num2 = 0; ISpawner[] array = componentsInChildren; foreach (ISpawner val in array) { try { val.TrySpawnItems(); num++; } catch (Exception ex) { num2++; if (num2 <= 3) { Plugin.Log.LogWarning((object)("[FinalAscent] Spawner " + ((object)val).GetType().Name + " wirft: " + ex.Message)); } } } Plugin.Detail(string.Format("{0} Spawner fuer {1}: {2} ok, {3} fehlgeschlagen.", "[FinalAscent]", stage.Type, num, num2)); } } [HarmonyPatch(typeof(Campfire), "Light_Rpc")] internal static class FinalAscentStageCampfirePatch { private static void Prefix(Campfire __instance, ref bool updateSegment, out FinalAscentStage __state) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) __state = null; if (FinalAscent.Active) { FinalAscentCamps.NoteLit(__instance); FinalAscentStage stage; bool flag = FinalAscentSegments.TryGetStage(__instance, out stage); Plugin.Log.LogInfo((object)("[FinalAscent] Lagerfeuer '" + ((Object)__instance).name + "' angezuendet: " + $"updateSegment={updateSegment}, Etappenfeuer={flag}, " + $"advanceToSegment={__instance.advanceToSegment}")); if (updateSegment && flag) { updateSegment = false; __state = stage; } } } private static void Postfix(Campfire __instance, FinalAscentStage __state) { if (__state != null) { FinalAscentSegments.AdvanceStage(__state, __instance); } } } internal static class FinalAscentProgress { private const string Tag = "[FinalAscent]"; internal static void Rebuild() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) MountainProgressHandler instance = Singleton.Instance; if ((Object)(object)instance == (Object)null || instance.progressPoints == null) { Plugin.Log.LogWarning((object)"[FinalAscent] Keine ProgressPoints vorhanden."); return; } if (instance.progressPoints.Length < 10) { Plugin.Log.LogWarning((object)(string.Format("{0} Nur {1} ProgressPoints - die Liste wurde schon ", "[FinalAscent]", instance.progressPoints.Length) + "gefiltert, die Biom-Titel bleiben dadurch unvollstaendig.")); } SplitSharedTrigger(instance, "ROOTS"); SplitSharedTrigger(instance, "MESA"); SplitSharedTrigger(instance, "GLOOM"); SplitSharedTrigger(instance, "THE CITADEL"); ProgressPoint[] progressPoints = instance.progressPoints; foreach (ProgressPoint val in progressPoints) { if (!((Object)(object)val?.transform == (Object)null) && FinalAscentBuilder.Offsets.TryGetValue(val.biome, out var value) && !(value == Vector3.zero)) { Transform transform = val.transform; transform.position += value; Plugin.Detail("[FinalAscent] Trigger '" + val.title + "' -> " + FinalAscentBuilder.Fmt(val.transform.position)); } } } internal static int IndexOfTitle(MountainProgressHandler progress, string title) { if (progress?.progressPoints == null) { return -1; } for (int i = 0; i < progress.progressPoints.Length; i++) { if (progress.progressPoints[i]?.title == title) { return i; } } return -1; } internal static void ShowStageTitle(string title) { MountainProgressHandler instance = Singleton.Instance; if (instance?.progressPoints == null || string.IsNullOrEmpty(title)) { return; } ProgressPoint[] progressPoints = instance.progressPoints; foreach (ProgressPoint val in progressPoints) { if (val != null && !(val.title != title) && !val.Reached) { val.Reached = true; instance.TriggerReached(val, false); if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(TitleLater(val)); Plugin.Detail("[FinalAscent] Titel '" + val.title + "' folgt gleich (Vorhang ist durch)."); } else { instance.TriggerReached(val, true); Plugin.Detail("[FinalAscent] Titel '" + val.title + "' eingeblendet."); } break; } } } private static IEnumerator TitleLater(ProgressPoint point) { yield return (object)new WaitForSeconds(0.25f); if ((Object)(object)GUIManager.instance != (Object)null && point != null) { GUIManager.instance.SetHeroTitle(point.localizedTitle, point.clip, false); } } private static void SplitSharedTrigger(MountainProgressHandler progress, string title) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) ProgressPoint[] progressPoints = progress.progressPoints; foreach (ProgressPoint val in progressPoints) { if (val != null && !(val.title != title) && !((Object)(object)val.transform == (Object)null)) { GameObject val2 = new GameObject("FA_Trigger_" + title); val2.transform.position = val.transform.position; val.transform = val2.transform; Plugin.Detail("[FinalAscent] '" + title + "' hat jetzt einen eigenen Trigger."); break; } } } } [HarmonyPatch(typeof(MountainProgressHandler), "InitProgressPoints")] internal static class FinalAscentProgressOrderPatch { private const string Tag = "[FinalAscent]"; private static ProgressPoint[] _untouched; private static MountainProgressHandler _owner; private static bool Prefix(MountainProgressHandler __instance) { if ((Object)(object)__instance != (Object)null && (Object)(object)_owner != (Object)(object)__instance && __instance.progressPoints != null) { _owner = __instance; _untouched = (ProgressPoint[])__instance.progressPoints.Clone(); } if (!FinalAscent.Active) { return true; } if (FinalAscentBuilder.Awaited) { Plugin.Log.LogInfo((object)"[FinalAscent] Fortschrittspunkte warten - der Berg wird noch gebaut. Sie entstehen, sobald er steht."); return false; } FinalAscentBiomes.RestoreAll(); return true; } internal static void Rebuild(MountainProgressHandler handler) { if (!((Object)(object)handler == (Object)null)) { int num = ((handler.progressPoints != null) ? handler.progressPoints.Length : 0); if (_untouched != null && (Object)(object)_owner == (Object)(object)handler) { handler.progressPoints = (ProgressPoint[])_untouched.Clone(); AccessTools.Field(typeof(MountainProgressHandler), "_isInitialized")?.SetValue(handler, false); } AccessTools.Method(typeof(MountainProgressHandler), "InitProgressPoints", (Type[])null, (Type[])null)?.Invoke(handler, null); int num2 = ((handler.progressPoints != null) ? handler.progressPoints.Length : 0); Plugin.Log.LogInfo((object)(string.Format("{0} Fortschrittspunkte neu gebaut: {1} -> {2} ", "[FinalAscent]", num, num2) + "(Urliste " + ((_untouched != null) ? _untouched.Length.ToString() : "fehlt") + ").")); } } private static void Postfix(MountainProgressHandler __instance) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (!FinalAscent.Active || __instance.progressPoints == null) { return; } FinalAscentBiomes.Apply(); Dictionary rank = new Dictionary(); List list = new List(); int num = 0; foreach (FinalAscentStage item in FinalAscentSegments.AllStages()) { if (!rank.ContainsKey(item.Type)) { rank[item.Type] = num; } list.Add(item.Title); num++; } Array.Sort(__instance.progressPoints, delegate(ProgressPoint a, ProgressPoint b) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)a?.transform == (Object)null || (Object)(object)b?.transform == (Object)null) { return 0; } if ((int)a.biome == 5) { return 1; } if ((int)b.biome == 5) { return -1; } int value; bool flag = rank.TryGetValue(a.biome, out value); int value2; bool flag2 = rank.TryGetValue(b.biome, out value2); if (flag && flag2 && value != value2) { return value.CompareTo(value2); } return (flag != flag2) ? ((!flag) ? 1 : (-1)) : a.transform.position.z.CompareTo(b.transform.position.z); }); string text = ""; ProgressPoint[] progressPoints = __instance.progressPoints; foreach (ProgressPoint val in progressPoints) { text = text + ((text.Length > 0) ? " -> " : "") + val.title; } Plugin.Log.LogInfo((object)("[FinalAscent] Etappenreihenfolge: " + text)); Plugin.Log.LogInfo((object)("[FinalAscent] Massgeblich war die Kette: " + string.Join(" -> ", list))); } } internal static class FinalAscentBiomes { private const string Tag = "[FinalAscent]"; private static readonly List All = new List(); private static readonly HashSet Hidden = new HashSet(); internal static void Capture(MapHandler map) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_004d: Invalid comparison between Unknown and I4 //IL_0054: Unknown result type (might be due to invalid IL or missing references) All.Clear(); Hidden.Clear(); if (map?.biomes == null) { return; } All.AddRange(map.biomes); foreach (BiomeType item in All) { if ((int)item != 0 && (int)item != 1) { Hidden.Add(item); } } Apply(); } internal static void EnterStage(BiomeType from, BiomeType to) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (from != to) { Hidden.Remove(to); Hidden.Add(from); Apply(); } } internal static void LeaveSegment(Segment entering) { //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_0018: Expected I4, but got Unknown switch (entering - 1) { default: return; case 0: Hidden.Remove((BiomeType)1); break; case 1: Hidden.Remove((BiomeType)2); Hidden.Add((BiomeType)1); Hidden.Add((BiomeType)7); break; case 2: Hidden.Remove((BiomeType)3); Hidden.Add((BiomeType)2); Hidden.Add((BiomeType)6); break; case 3: Hidden.Remove((BiomeType)3); break; } Apply(); } internal static void RestoreAll() { MapHandler instance = Singleton.Instance; if (!((Object)(object)instance == (Object)null) && All.Count != 0) { instance.biomes.Clear(); instance.biomes.AddRange(All); } } internal static void Apply() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) MapHandler instance = Singleton.Instance; if ((Object)(object)instance == (Object)null || All.Count == 0) { return; } instance.biomes.Clear(); foreach (BiomeType item in All) { if (!Hidden.Contains(item)) { instance.biomes.Add(item); } } Plugin.Detail("[FinalAscent] Gilt als vorhanden: " + string.Join(", ", instance.biomes)); } } internal static class FinalAscentSetup { internal enum Kind { BiomeVariant, VariantObject, None } internal sealed class BiomeVariants { internal string Key; internal Kind Kind; internal string Segment; internal string[] Names; internal string[] Labels; } private const string Tag = "[FinalAscent]"; internal const string RandomChoice = "*"; internal static readonly BiomeVariants[] Catalogue = new BiomeVariants[7] { new BiomeVariants { Key = "biome.Shore", Kind = Kind.BiomeVariant, Segment = "Beach_Segment", Names = new string[6] { "Default", "BlackSand", "BlueBeach", "JellyHell", "RedBeach", "SnakeBeach" }, Labels = new string[6] { "Default", "Black Sand", "Blue Beach", "Jelly Hell", "Red Beach", "Snake Beach" } }, new BiomeVariants { Key = "biome.Tropics", Kind = Kind.BiomeVariant, Segment = "Jungle_Segment", Names = new string[7] { "Default", "Bombs", "Ivy", "Lava", "Pillars", "SkyJungle", "Thorny" }, Labels = new string[7] { "Default", "Bombs", "Ivy", "Lava", "Pillars", "Sky Jungle", "Thorny" } }, new BiomeVariants { Key = "biome.Roots", Kind = Kind.VariantObject, Segment = "Roots Segment", Names = new string[5] { "- Redwoods Default Variant", "- Cave Mania Variant", "- Deep Water variant", "- Redwood Clearcut Variant", "- redwoods deep woods Variant" }, Labels = new string[5] { "Redwoods", "Cave Mania", "Deep Water", "Clearcut", "Deep Woods" } }, new BiomeVariants { Key = "biome.Alpine", Kind = Kind.BiomeVariant, Segment = "Snow_Segment", Names = new string[4] { "Default", "GeyserHell", "Lava", "Spiky" }, Labels = new string[4] { "Default", "Geyser Hell", "Lava", "Spiky" } }, new BiomeVariants { Key = "biome.Mesa", Kind = Kind.VariantObject, Segment = "Desert_Segment", Names = new string[6] { "NoVariant", "CactusForest", "TumblerHell", "CacusHell", "DynamiteHell", "ScorpionsHell" }, Labels = new string[6] { "None", "Cactus Forest", "Tumbler Hell", "Cactus Hell", "Dynamite Hell", "Scorpion Hell" } }, new BiomeVariants { Key = "biome.Caldera", Kind = Kind.None, Segment = "Caldera_Segment", Names = new string[0], Labels = new string[0] }, new BiomeVariants { Key = "biome.Gloom", Kind = Kind.None, Segment = "Swamp_Segment", Names = new string[0], Labels = new string[0] } }; internal static readonly Dictionary Picks = new Dictionary(); internal static readonly Dictionary Chosen = new Dictionary(); private static Random _dice = new Random(0); internal static bool RandomSeed { get; set; } = true; internal static bool RandomVariants { get; set; } = true; internal static int ChosenSeed { get; set; } = 1; internal static string SerializeChosen() { List list = new List(); BiomeVariants[] catalogue = Catalogue; foreach (BiomeVariants biomeVariants in catalogue) { if (biomeVariants.Kind != Kind.None && Chosen.TryGetValue(biomeVariants.Key, out var value)) { list.Add(biomeVariants.Key + "=" + value); } } return string.Join("|", list); } internal static void ApplyDelivered(string choices, LevelGeneration levelGen) { RandomVariants = false; Deserialize(choices); Apply(levelGen); } internal static string PickOf(BiomeVariants biome) { if (!Picks.TryGetValue(biome.Key, out var value)) { return "*"; } return value; } internal static void SetPick(BiomeVariants biome, string name) { Picks[biome.Key] = name; } internal static string Serialize() { List list = new List(); BiomeVariants[] catalogue = Catalogue; foreach (BiomeVariants biomeVariants in catalogue) { if (biomeVariants.Kind != Kind.None) { list.Add(biomeVariants.Key + "=" + PickOf(biomeVariants)); } } return string.Join("|", list); } internal static void Deserialize(string packed) { Picks.Clear(); if (string.IsNullOrEmpty(packed)) { return; } string[] array = packed.Split('|'); foreach (string text in array) { int num = text.IndexOf('='); if (num > 0) { Picks[text.Substring(0, num)] = text.Substring(num + 1); } } } internal static void Apply(LevelGeneration levelGen) { if ((Object)(object)levelGen == (Object)null) { return; } _dice = new Random(FinalAscent.Seed); BiomeVariants[] catalogue = Catalogue; foreach (BiomeVariants biomeVariants in catalogue) { if (biomeVariants.Kind == Kind.None) { continue; } Transform val = FinalAscentBuilder.DeepFindPublic(((Component)levelGen).transform, biomeVariants.Segment); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("[FinalAscent] '" + biomeVariants.Segment + "' nicht gefunden - " + FinalAscentText.Get(biomeVariants.Key) + " behaelt seine Fassung.")); continue; } List list = Collect(val, biomeVariants); if (list.Count == 0) { Plugin.Log.LogWarning((object)("[FinalAscent] Unter '" + biomeVariants.Segment + "' steht keine der erwarteten Fassungen.")); continue; } string wanted = (RandomVariants ? "*" : PickOf(biomeVariants)); GameObject val2 = null; if (wanted != "*") { val2 = list.Find((GameObject o) => ((Object)o).name == wanted); } if ((Object)(object)val2 == (Object)null) { val2 = list[_dice.Next(list.Count)]; } Chosen[biomeVariants.Key] = ((Object)val2).name; foreach (GameObject item in list) { item.SetActive((Object)(object)item == (Object)(object)val2); } Plugin.Log.LogInfo((object)("[FinalAscent] " + FinalAscentText.Get(biomeVariants.Key) + ": '" + ((Object)val2).name + "' (" + ((wanted == "*") ? ("ausgelost aus " + list.Count) : "gewaehlt") + ").")); CheckOnlyOne(val, biomeVariants, val2); } } private static void CheckOnlyOne(Transform segment, BiomeVariants biome, GameObject winner) { List active = new List(); List strangers = new List(); BiomeVariant[] componentsInChildren = ((Component)segment).GetComponentsInChildren(true); foreach (BiomeVariant val in componentsInChildren) { Note(((Component)val).gameObject, ((Component)val).transform, "BiomeVariant"); } VariantObject[] componentsInChildren2 = ((Component)segment).GetComponentsInChildren(true); foreach (VariantObject val2 in componentsInChildren2) { Note(((Component)val2).gameObject, ((Component)val2).transform, "VariantObject"); } if (Plugin.Diagnosing) { Describe(segment, biome); } if (active.Count <= 1) { return; } Plugin.Log.LogWarning((object)(string.Format("{0} {1}: {2} Fassungen sind ", "[FinalAscent]", FinalAscentText.Get(biome.Key), active.Count) + "GLEICHZEITIG an - '" + string.Join("', '", active) + "'. Gewollt war nur '" + ((Object)winner).name + "'. So sieht die Landschaft aus wie zwei uebereinander.")); foreach (string item in strangers) { Plugin.Log.LogWarning((object)("[FinalAscent] Nicht abgeschaltet: " + item)); } void Note(GameObject what, Transform where, string kind) { if (what.activeInHierarchy) { active.Add(((Object)what).name); bool flag = Array.IndexOf(biome.Names, ((Object)what).name) >= 0; bool flag2 = (Object)(object)where.parent == (Object)(object)segment; if (!flag || !flag2) { strangers.Add(((Object)what).name + " (" + kind + ", " + (flag ? "im Katalog" : "NICHT im Katalog") + ", " + (flag2 ? "direkt unter dem Segment" : "tiefer verschachtelt") + ")"); } } } } private static int Renderers(Transform where, bool onlyVisible) { Renderer[] componentsInChildren = ((Component)where).GetComponentsInChildren(true); if (!onlyVisible) { return componentsInChildren.Length; } int num = 0; Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if ((Object)(object)val != (Object)null && val.enabled && ((Component)val).gameObject.activeInHierarchy) { num++; } } return num; } private static void Describe(Transform segment, BiomeVariants biome) { Plugin.Log.LogInfo((object)string.Format("{0} Unter '{1}' haengen {2} Objekte:", "[FinalAscent]", ((Object)segment).name, segment.childCount)); for (int i = 0; i < segment.childCount; i++) { Transform child = segment.GetChild(i); Plugin.Log.LogInfo((object)("[FinalAscent] " + (((Component)child).gameObject.activeSelf ? "AN " : "aus") + " " + $"{((Object)child).name} ({Renderers(child, onlyVisible: false)} vorhanden, " + $"{Renderers(child, onlyVisible: true)} sichtbar)")); } } internal static void CountWhenDone(LevelGeneration levelGen) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Expected O, but got Unknown if ((Object)(object)levelGen == (Object)null) { return; } BiomeVariants[] catalogue = Catalogue; foreach (BiomeVariants biomeVariants in catalogue) { if (biomeVariants.Kind == Kind.None) { continue; } Transform val = FinalAscentBuilder.DeepFindPublic(((Component)levelGen).transform, biomeVariants.Segment); if ((Object)(object)val == (Object)null) { continue; } string text = "-"; int num = 0; foreach (Transform item in val) { Transform val2 = item; if (((Component)val2).gameObject.activeSelf && Array.IndexOf(biomeVariants.Names, ((Object)val2).name) >= 0) { text = ((Object)val2).name; num = Renderers(val2, onlyVisible: true); break; } } int num2 = Renderers(val, onlyVisible: true); Plugin.Log.LogInfo((object)("[FinalAscent] Fertig - " + FinalAscentText.Get(biomeVariants.Key) + ": " + $"{num2} sichtbar im Segment, davon " + $"{num} in der Fassung '{text}'.")); if (num2 - num <= 0) { continue; } foreach (Transform item2 in val) { Transform val3 = item2; if (!(((Object)val3).name == text)) { int num3 = Renderers(val3, onlyVisible: true); if (num3 > 0) { bool flag = Array.IndexOf(biomeVariants.Names, ((Object)val3).name) >= 0; Plugin.Log.LogInfo((object)(string.Format("{0} ausserhalb der Fassung: '{1}' mit {2} ", "[FinalAscent]", ((Object)val3).name, num3) + "sichtbar" + (flag ? " - DAS IST EINE ANDERE FASSUNG" : " (geteiltes Stueck)") + ".")); } } } } } private static List Collect(Transform segment, BiomeVariants biome) { List list = new List(); if (biome.Kind == Kind.BiomeVariant) { BiomeVariant[] componentsInChildren = ((Component)segment).GetComponentsInChildren(true); foreach (BiomeVariant val in componentsInChildren) { if ((Object)(object)((Component)val).transform.parent == (Object)(object)segment && Array.IndexOf(biome.Names, ((Object)val).name) >= 0) { list.Add(((Component)val).gameObject); } } } else { VariantObject[] componentsInChildren2 = ((Component)segment).GetComponentsInChildren(true); foreach (VariantObject val2 in componentsInChildren2) { if (Array.IndexOf(biome.Names, ((Object)val2).name) >= 0) { list.Add(((Component)val2).gameObject); } } } if (list.Count != biome.Names.Length) { Plugin.Log.LogWarning((object)(string.Format("{0} {1}: {2} von ", "[FinalAscent]", FinalAscentText.Get(biome.Key), list.Count) + $"{biome.Names.Length} Fassungen gefunden - die Liste im Katalog passt " + "nicht mehr zur Szene.")); } return list; } } internal static class FinalAscentSetupMemory { private const string Tag = "[FinalAscent]"; private const string FileName = "TrueFinalAscent.Auswahl.txt"; private const string OldFileName = "PiCHUPatches.Auswahl.txt"; private static string Path => FinalAscentStore.State("TrueFinalAscent.Auswahl.txt"); private static string ReadPath => FinalAscentStore.ReadPath("TrueFinalAscent.Auswahl.txt", "PiCHUPatches.Auswahl.txt"); internal static void Load() { try { string readPath = ReadPath; if (!File.Exists(readPath)) { return; } string[] array = File.ReadAllLines(readPath, 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 "seed": { if (int.TryParse(text3, out var result) && result > 0) { FinalAscentSetup.ChosenSeed = result; } break; } case "seed.zufaellig": FinalAscentSetup.RandomSeed = text3 == "1"; break; case "varianten.zufaellig": FinalAscentSetup.RandomVariants = text3 == "1"; break; case "varianten": FinalAscentSetup.Deserialize(text3); break; case "apokalypse": FinalAscentApocalypse.Restore(text3 == "1"); break; } } Plugin.Log.LogInfo((object)(string.Format("{0} Letzte Auswahl uebernommen: Seed {1}", "[FinalAscent]", FinalAscentSetup.ChosenSeed) + " (" + (FinalAscentSetup.RandomSeed ? "zufaellig" : "fest") + "), Varianten " + (FinalAscentSetup.RandomVariants ? "zufaellig" : "gewaehlt") + ".")); if (!string.Equals(readPath, Path, StringComparison.OrdinalIgnoreCase)) { Save(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] TrueFinalAscent.Auswahl.txt nicht lesbar (" + ex.Message + ") - Vorgaben gelten.")); } } internal static void Save() { try { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# Die zuletzt gespielte Auswahl. Wird beim Start eines Laufs geschrieben."); stringBuilder.AppendLine("#"); stringBuilder.AppendLine("# 'seed' ist der Wert, mit dem tatsaechlich gebaut wurde - auch dann,"); stringBuilder.AppendLine("# wenn er ausgelost war. So laesst sich derselbe Berg noch einmal"); stringBuilder.AppendLine("# starten: Haken bei 'Zufaellig' heraus, die Zahl steht schon da."); stringBuilder.AppendLine(); stringBuilder.AppendLine($"seed = {FinalAscentSetup.ChosenSeed}"); stringBuilder.AppendLine($"seed.zufaellig = {(FinalAscentSetup.RandomSeed ? 1 : 0)}"); stringBuilder.AppendLine($"varianten.zufaellig = {(FinalAscentSetup.RandomVariants ? 1 : 0)}"); stringBuilder.AppendLine("varianten = " + FinalAscentSetup.Serialize()); stringBuilder.AppendLine($"apokalypse = {(FinalAscentApocalypse.Wanted ? 1 : 0)}"); File.WriteAllText(Path, stringBuilder.ToString(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: true)); FinalAscentStore.Retire("TrueFinalAscent.Auswahl.txt", "PiCHUPatches.Auswahl.txt"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] TrueFinalAscent.Auswahl.txt nicht schreibbar: " + ex.Message)); } } } internal sealed class FinalAscentSetupWindow : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const float Width = 1560f; private const float Height = 900f; private const float Margin = 90f; private static FinalAscentSetupWindow _instance; private BoardingPass _pass; private GameObject _root; private TMP_InputField _seed; private Toggle _randomSeed; private Toggle _randomVariants; private readonly List _drops = new List(); private readonly List _dropLabels = new List(); private readonly List _shown = new List(); internal static bool Confirmed { get; private set; } internal static void Show(BoardingPass pass) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_instance != (Object)null && FinalAscentText.Changed()) { FinalAscentText.Load(); Object.Destroy((Object)(object)((Component)_instance).gameObject); _instance = null; } if ((Object)(object)_instance == (Object)null) { Canvas componentInParent = ((Component)pass).GetComponentInParent(); GameObject val = new GameObject("FA_SetupWindow"); val.transform.SetParent(((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).transform : ((Component)pass).transform, false); _instance = val.AddComponent(); _instance._pass = pass; _instance.Build(); } _instance._pass = pass; _instance.Fill(); _instance._root.SetActive(true); ((Component)_instance).transform.SetAsLastSibling(); } private void Hide() { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } } private void Build() { //IL_0085: 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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Unknown result type (might be due to invalid IL or missing references) //IL_05f7: Unknown result type (might be due to invalid IL or missing references) //IL_0612: Unknown result type (might be due to invalid IL or missing references) //IL_061c: Expected O, but got Unknown //IL_0631: Unknown result type (might be due to invalid IL or missing references) //IL_0681: Unknown result type (might be due to invalid IL or missing references) //IL_0686: Unknown result type (might be due to invalid IL or missing references) //IL_06a1: Unknown result type (might be due to invalid IL or missing references) //IL_06ab: Expected O, but got Unknown FinalAscentUiKit.Sample(_pass); _root = FinalAscentUiKit.Node("Window", ((Component)this).transform); FinalAscentUiKit.Stretch(_root); GameObject go = FinalAscentUiKit.Node("Shade", _root.transform); FinalAscentUiKit.Stretch(go); FinalAscentUiKit.Box(go, new Color(0f, 0f, 0f, 0.78f)); GameObject obj = FinalAscentUiKit.Node("Card", _root.transform); FinalAscentUiKit.Place(obj, 0f, 0f, 1560f, 900f); FinalAscentUiKit.Box(obj, FinalAscentUiKit.Card, FinalAscentUiKit.CardSprite); Transform transform = obj.transform; float num = 450f; GameObject go2 = FinalAscentUiKit.Node("BandTop", transform); FinalAscentUiKit.Place(go2, 0f, num - 62f, 1560f, 124f); FinalAscentUiKit.Box(go2, FinalAscentUiKit.Band, FinalAscentUiKit.CardSprite); GameObject go3 = FinalAscentUiKit.Node("BandBottom", transform); FinalAscentUiKit.Place(go3, 0f, 0f - num + 40f, 1560f, 80f); FinalAscentUiKit.Box(go3, FinalAscentUiKit.Band, FinalAscentUiKit.CardSprite); FinalAscentUiKit.Place(((Component)FinalAscentUiKit.Label(transform, FinalAscentText.Get("window.title"), 80f, (TextAlignmentOptions)514, FinalAscentUiKit.Accent)).gameObject, 0f, num - 176f, 1380f, 84f); GameObject go4 = FinalAscentUiKit.Node("Rule", transform); FinalAscentUiKit.Place(go4, 0f, num - 228f, 1380f, 3f); FinalAscentUiKit.Box(go4, FinalAscentUiKit.Rule); float num2 = -690f; FinalAscentUiKit.Place(((Component)FinalAscentUiKit.Label(transform, FinalAscentText.Get("seed.label"), 38f, (TextAlignmentOptions)513, FinalAscentUiKit.InkDim)).gameObject, num2 + 66f, num - 290f, 140f, 44f); _seed = FinalAscentUiKit.Input(transform, num2 + 340f, num - 290f, 360f, 62f); _randomSeed = FinalAscentUiKit.Check(transform, num2 + 340f, num - 364f, 360f, 48f, FinalAscentText.Get("seed.random"), 34f); ((UnityEvent)(object)_randomSeed.onValueChanged).AddListener((UnityAction)delegate { SyncEnabled(); }); _randomVariants = FinalAscentUiKit.Check(transform, num2 + 400f, num - 430f, 480f, 48f, FinalAscentText.Get("variants.random"), 34f); ((UnityEvent)(object)_randomVariants.onValueChanged).AddListener((UnityAction)delegate { SyncEnabled(); }); FinalAscentUiKit.Place(((Component)FinalAscentUiKit.Label(transform, FinalAscentText.Get("variants.heading"), 36f, (TextAlignmentOptions)513, FinalAscentUiKit.InkDim)).gameObject, num2 + 200f, num - 506f, 440f, 42f); GameObject go5 = FinalAscentUiKit.Node("Rule2", transform); FinalAscentUiKit.Place(go5, 0f, num - 534f, 1380f, 3f); FinalAscentUiKit.Box(go5, FinalAscentUiKit.Rule); List list = new List(); FinalAscentSetup.BiomeVariants[] catalogue = FinalAscentSetup.Catalogue; foreach (FinalAscentSetup.BiomeVariants biomeVariants in catalogue) { if (biomeVariants.Kind != FinalAscentSetup.Kind.None) { list.Add(biomeVariants); } } int count = list.Count; float num4 = 1380f / (float)Mathf.Max(1, count); float num5 = (0f - 1380f) * 0.5f + num4 * 0.5f; for (int num6 = 0; num6 < count; num6++) { FinalAscentSetup.BiomeVariants biomeVariants2 = list[num6]; float x = num5 + (float)num6 * num4; TextMeshProUGUI val = FinalAscentUiKit.Label(transform, FinalAscentText.Get(biomeVariants2.Key), 32f, (TextAlignmentOptions)514, FinalAscentUiKit.Ink); FinalAscentUiKit.Place(((Component)val).gameObject, x, num - 586f, num4 - 14f, 40f); _dropLabels.Add(val); TMP_Dropdown val2 = FinalAscentUiKit.Drop(transform, x, num - 640f, num4 - 18f, 54f); List list2 = new List { FinalAscentText.Get("pick.random") }; for (int num7 = 0; num7 < biomeVariants2.Names.Length; num7++) { list2.Add(FinalAscentText.VariantLabel(biomeVariants2, num7)); } val2.ClearOptions(); val2.AddOptions(list2); val2.value = 0; val2.RefreshShownValue(); FinalAscentSetup.BiomeVariants remembered = biomeVariants2; ((UnityEvent)(object)val2.onValueChanged).AddListener((UnityAction)delegate(int chosen) { Remember(remembered, chosen); }); _drops.Add(val2); _shown.Add(biomeVariants2); } TextMeshProUGUI obj2 = FinalAscentUiKit.Label(transform, FinalAscentText.Get("ascent.title"), 32f, (TextAlignmentOptions)514, FinalAscentUiKit.Ink); float x2 = 690f - 130f; FinalAscentUiKit.Place(((Component)obj2).gameObject, x2, num - 380f, 260f, 40f); TMP_Dropdown val3 = FinalAscentUiKit.Drop(transform, x2, num - 434f, 260f, 54f); List list3 = new List(); int highest = FinalAscentDifficulty.Highest; for (int num8 = -1; num8 <= highest; num8++) { list3.Add(FinalAscentDifficulty.TitleOf(num8)); } val3.ClearOptions(); val3.AddOptions(list3); val3.value = FinalAscentDifficulty.Chosen - -1; val3.RefreshShownValue(); ((UnityEvent)(object)val3.onValueChanged).AddListener((UnityAction)delegate(int picked) { FinalAscentDifficulty.Chosen = picked + -1; }); ((UnityEvent)FinalAscentUiKit.Push(transform, 550f, 0f - num + 130f, 280f, 76f, FinalAscentText.Get("button.start"), FinalAscentUiKit.Blue, Color.white, 38f).onClick).AddListener(new UnityAction(Launch)); FinalAscentUiKit.Place(((Component)FinalAscentUiKit.Label(transform, FinalAscentText.Get("warning.load"), 28f, (TextAlignmentOptions)513, FinalAscentUiKit.Accent)).gameObject, num2 + 380f, 0f - num + 130f, 760f, 84f); ((UnityEvent)FinalAscentUiKit.Push(transform, 250f, 0f - num + 130f, 260f, 76f, FinalAscentText.Get("button.cancel"), FinalAscentUiKit.Inset, FinalAscentUiKit.Ink, 38f).onClick).AddListener(new UnityAction(Hide)); FinalAscentUiKit.Outline(_root.transform, 1560f, 900f); } private void Fill() { _randomSeed.isOn = FinalAscentSetup.RandomSeed; _randomVariants.isOn = FinalAscentSetup.RandomVariants; _seed.text = FinalAscentSetup.ChosenSeed.ToString(); for (int i = 0; i < _drops.Count; i++) { FinalAscentSetup.BiomeVariants biomeVariants = _shown[i]; string text = FinalAscentSetup.PickOf(biomeVariants); int valueWithoutNotify = 0; for (int j = 0; j < biomeVariants.Names.Length; j++) { if (biomeVariants.Names[j] == text) { valueWithoutNotify = j + 1; break; } } _drops[i].SetValueWithoutNotify(valueWithoutNotify); _drops[i].RefreshShownValue(); } SyncEnabled(); } private void SyncEnabled() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) bool flag = !_randomSeed.isOn; ((Selectable)_seed).interactable = flag; ((Graphic)((Selectable)_seed).image).color = (flag ? FinalAscentUiKit.Inset : FinalAscentUiKit.InsetOff); ((Graphic)_seed.textComponent).color = (flag ? FinalAscentUiKit.Ink : FinalAscentUiKit.InkDim); bool flag2 = !_randomVariants.isOn; for (int i = 0; i < _drops.Count; i++) { bool flag3 = flag2; ((Selectable)_drops[i]).interactable = flag3; ((Graphic)((Selectable)_drops[i]).image).color = (flag3 ? FinalAscentUiKit.Inset : FinalAscentUiKit.InsetOff); ((Graphic)_drops[i].captionText).color = (flag3 ? FinalAscentUiKit.Ink : FinalAscentUiKit.InkDim); ((Graphic)_dropLabels[i]).color = (flag3 ? FinalAscentUiKit.Ink : FinalAscentUiKit.InkDim); } } private void Remember(FinalAscentSetup.BiomeVariants biome, int chosen) { FinalAscentSetup.SetPick(biome, (chosen <= 0) ? "*" : biome.Names[chosen - 1]); } private void Launch() { FinalAscentSetup.RandomSeed = _randomSeed.isOn; FinalAscentSetup.RandomVariants = _randomVariants.isOn; int result; if (FinalAscentSetup.RandomSeed) { FinalAscentSetup.ChosenSeed = Random.Range(1, 999999); } else if (!int.TryParse(_seed.text, out result) || result <= 0) { FinalAscentSetup.ChosenSeed = Random.Range(1, 999999); Plugin.Log.LogInfo((object)("[FinalAscent] Kein brauchbarer Seed eingegeben - es wird einer ausgelost " + $"({FinalAscentSetup.ChosenSeed}).")); } else { FinalAscentSetup.ChosenSeed = result; } Plugin.Log.LogInfo((object)(string.Format("{0} Start mit Seed {1} ", "[FinalAscent]", FinalAscentSetup.ChosenSeed) + "(" + (FinalAscentSetup.RandomSeed ? "ausgelost" : "eingegeben") + "), Varianten " + (FinalAscentSetup.RandomVariants ? "zufaellig" : ("gewaehlt: " + FinalAscentSetup.Serialize())) + ".")); FinalAscentSetupMemory.Save(); Hide(); Confirmed = true; try { _pass.StartGame(); } finally { Confirmed = false; } } } internal static class FinalAscentSkyBodies { private const string Tag = "[FinalAscent]"; private const float Shrink = 0.05f; private static readonly List Bodies = new List(); private static readonly List Sizes = new List(); private static MaterialPropertyBlock _block; private static bool _looked; private static bool _held; private static readonly int Colour = Shader.PropertyToID("_Color"); private static readonly int BaseColour = Shader.PropertyToID("_BaseColor"); private static readonly int Tint = Shader.PropertyToID("_TintColor"); private static readonly int SunLit = Shader.PropertyToID("_SunIntensity"); private static readonly int SunSize = Shader.PropertyToID("_SunSize"); private static readonly int MoonSliver = Shader.PropertyToID("_MoonSliver"); private static readonly int SunPower = Shader.PropertyToID("_SunPower"); private static Material _sky; private static float _sunWas; private static float _sizeWas; private static float _moonWas; private static bool _skyKept; private static bool _skyHeld; internal static void Fade(DayNightManager cycle, float rain) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) Look(cycle); Discs(rain); if (Bodies.Count == 0) { return; } if (rain <= 0f) { if (_held) { _held = false; Restore(); } return; } _held = true; if (_block == null) { _block = new MaterialPropertyBlock(); } float num = Mathf.Lerp(1f, 0.05f, rain); for (int i = 0; i < Bodies.Count; i++) { Renderer val = Bodies[i]; if (!((Object)(object)val == (Object)null)) { ((Component)val).transform.localScale = Sizes[i] * num; val.GetPropertyBlock(_block); Fade(_block, Colour, num); Fade(_block, BaseColour, num); Fade(_block, Tint, num); val.SetPropertyBlock(_block); } } } private static void Discs(float rain) { Material skybox = RenderSettings.skybox; if ((Object)(object)skybox == (Object)null) { return; } if (!_skyKept || (Object)(object)skybox != (Object)(object)_sky) { _sky = skybox; _skyKept = true; _sunWas = (skybox.HasProperty(SunLit) ? skybox.GetFloat(SunLit) : (-1f)); _sizeWas = (skybox.HasProperty(SunSize) ? skybox.GetFloat(SunSize) : (-1f)); _moonWas = (skybox.HasProperty(MoonSliver) ? skybox.GetFloat(MoonSliver) : (-1f)); Plugin.Log.LogInfo((object)(string.Format("{0} Himmelsscheiben gemerkt: Helligkeit {1:0.###}, ", "[FinalAscent]", _sunWas) + $"Groesse {_sizeWas:0.###}, Schaerfe " + $"{(skybox.HasProperty(SunPower) ? skybox.GetFloat(SunPower) : (-1f)):0.###}, " + $"Mondsichel {_moonWas:0.###}. Angefasst wird nur die Helligkeit.")); } if (rain <= 0f) { if (_skyHeld) { _skyHeld = false; Put(skybox, SunLit, _sunWas); Put(skybox, SunSize, _sizeWas); Put(skybox, MoonSliver, _moonWas); } } else { _skyHeld = true; Put(skybox, SunLit, _sunWas * (1f - rain)); if (_sizeWas >= 0f) { Put(skybox, SunSize, Mathf.Lerp(_sizeWas, 1f, rain)); } } } private static void Put(Material sky, int key, float value) { if (value >= 0f && sky.HasProperty(key)) { sky.SetFloat(key, value); } } private static void Fade(MaterialPropertyBlock block, int key, float left) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) Color color = block.GetColor(key); block.SetColor(key, new Color(color.r, color.g, color.b, left)); } private static void Restore() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < Bodies.Count; i++) { if (!((Object)(object)Bodies[i] == (Object)null)) { ((Component)Bodies[i]).transform.localScale = Sizes[i]; Bodies[i].SetPropertyBlock((MaterialPropertyBlock)null); } } } private static void Look(DayNightManager cycle) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (_looked || (Object)(object)cycle == (Object)null) { return; } _looked = true; if ((Object)(object)cycle.earth != (Object)null) { Renderer[] componentsInChildren = ((Component)cycle.earth).GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { Bodies.Add(val); Sizes.Add(((Component)val).transform.localScale); Material sharedMaterial = val.sharedMaterial; Plugin.Log.LogInfo((object)("[FinalAscent] Himmelskoerper gefunden: '" + ((Object)val).name + "' unter " + $"'{((Component)val).transform.parent}', Material " + "'" + (((Object)(object)sharedMaterial != (Object)null) ? ((Object)sharedMaterial).name : "keins") + "', Regelwerk '" + (((Object)(object)sharedMaterial != (Object)null && (Object)(object)sharedMaterial.shader != (Object)null) ? ((Object)sharedMaterial.shader).name : "keins") + "'.")); } } } Plugin.Log.LogInfo((object)(string.Format("{0} Am Himmel gefunden: {1} Netz(e) unter dem Rahmen ", "[FinalAscent]", Bodies.Count) + "'" + (((Object)(object)cycle.earth != (Object)null) ? ((Object)cycle.earth).name : "keiner") + "'.")); Sky(); } private static void Sky() { Material skybox = RenderSettings.skybox; if ((Object)(object)skybox == (Object)null || (Object)(object)skybox.shader == (Object)null) { Plugin.Log.LogInfo((object)"[FinalAscent] Kein Himmelsmaterial gesetzt."); return; } StringBuilder stringBuilder = new StringBuilder(); int propertyCount = skybox.shader.GetPropertyCount(); for (int i = 0; i < propertyCount; i++) { if (stringBuilder.Length > 0) { stringBuilder.Append(", "); } stringBuilder.Append(skybox.shader.GetPropertyName(i)); } Plugin.Log.LogInfo((object)string.Format("{0} Himmelsmaterial '{1}' / '{2}' - Regler: {3}.", "[FinalAscent]", ((Object)skybox).name, ((Object)skybox.shader).name, stringBuilder)); } } internal static class FinalAscentSkyProbe { private sealed class Seen { internal float Value; internal float When; } private const string Tag = "[FinalAscent]"; private const int Rays = 24; private const float Reach = 60f; private const float Sheltered = 0.25f; private const float Open = 0.75f; private const float CellSize = 2f; private const float Keep = 0.4f; private static readonly int Solid = LayerMask.GetMask(new string[2] { "Terrain", "Map" }); private static readonly Dictionary Known = new Dictionary(); private static readonly List Stale = new List(); private static Vector3[] _fan; private static float _lastTold; private static float _sweep; internal static float Exposure(Vector3 point) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) Vector3Int key = default(Vector3Int); ((Vector3Int)(ref key))..ctor(Mathf.RoundToInt(point.x / 2f), Mathf.RoundToInt(point.y / 2f), Mathf.RoundToInt(point.z / 2f)); if (Known.TryGetValue(key, out var value) && Time.time - value.When < 0.4f) { return value.Value; } float num = Openness(point); float num2 = Mathf.Clamp01(Mathf.InverseLerp(0.25f, 0.75f, num)); if (value == null) { value = new Seen(); Known[key] = value; } value.Value = num2; value.When = Time.time; Forgetful(); Tell(num, num2); return num2; } private static float Openness(Vector3 point) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (_fan == null) { Fan(); } _sweep += 0.618f; Quaternion val = Quaternion.AngleAxis(_sweep * 360f, Vector3.up); float num = 0f; float num2 = 0f; for (int i = 0; i < _fan.Length; i++) { Vector3 val2 = val * _fan[i]; float y = val2.y; if (!(y <= 0f)) { num2 += y; if (!Physics.Raycast(point, val2, 60f, Solid)) { num += y; } } } if (!(num2 > 0f)) { return 1f; } return num / num2; } private static void Fan() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) _fan = (Vector3[])(object)new Vector3[24]; float num = MathF.PI * (3f - Mathf.Sqrt(5f)); for (int i = 0; i < 24; i++) { float num2 = ((float)i + 0.5f) / 24f; float num3 = Mathf.Sqrt(1f - num2 * num2); float num4 = num * (float)i; Vector3[] fan = _fan; int num5 = i; Vector3 val = new Vector3(Mathf.Cos(num4) * num3, num2, Mathf.Sin(num4) * num3); fan[num5] = ((Vector3)(ref val)).normalized; } } private static void Forgetful() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if (Known.Count < 512) { return; } Stale.Clear(); foreach (KeyValuePair item in Known) { if (Time.time - item.Value.When > 4f) { Stale.Add(item.Key); } } for (int i = 0; i < Stale.Count; i++) { Known.Remove(Stale[i]); } } private static void Tell(float open, float exposed) { if (!(Time.unscaledTime - _lastTold < 5f)) { _lastTold = Time.unscaledTime; Plugin.Log.LogInfo((object)(string.Format("{0} Himmelsprobe: {1:0}% offen, erreicht mich ", "[FinalAscent]", open * 100f) + $"{exposed * 100f:0}% ({24} Strahlen, {60f:0}m). Das Lichtgitter " + "wird nicht gefragt - es ist nicht fuer diesen Berg gebacken.")); } } } [HarmonyPatch(typeof(WindChillZone), "GetWindIntensityAtPoint")] internal static class FinalAscentSkyProbePatch { private static bool Prefix(Vector3 point, ref float __result) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (FinalAscentLight.Baked || !FinalAscent.Active) { return true; } __result = FinalAscentSkyProbe.Exposure(point); return false; } } internal sealed class FinalAscentSleepFog : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const float Rate = 3f; private const float Amount = 0.025f; private const float Warmup = 2f; private float _since; private const float Volume = 0.55f; private float _counter; private AudioSource _voice; private bool _told; private static FinalAscentSleepFog _instance; private static readonly string[] Wishes = new string[3] { "Au_Ambience_Cavern", "Au_Ambience_Night", "Au_Ambience_WindLow" }; internal static void Run(bool on) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown FinalAscentFogWorms.Run(on); if (on && (Object)(object)_instance == (Object)null) { GameObject val = new GameObject("FA_SleepFog"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); FinalAscentGloomBand.Install(); FinalAscentFogVoices.Install(); } if (!((Object)(object)_instance == (Object)null)) { _instance._counter = 0f; _instance._since = 0f; _instance._told = false; } } private void Update() { float lift = FinalAscentSleepFogSky.Lift; Sing(lift); if (!FinalAscentSleepFogSky.Wanted) { _since = 0f; _counter = 0f; return; } _since += Time.deltaTime; if (_since < 2f) { return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || localCharacter.refs == null || (Object)(object)localCharacter.refs.afflictions == (Object)null) { return; } _counter += Time.deltaTime; if (!(_counter <= 3f)) { _counter = 0f; if (FinalAscentGloomBand.Drowning) { Tell("uebergibt an den echten Gloom - dessen Kaelte gilt"); return; } GloomSafeZone val = default(GloomSafeZone); float num = default(float); if (GloomSafeZone.CharacterProtectedFromStatus(localCharacter, ref val, ref num)) { Tell("haelt sich von '" + (((Object)(object)val != (Object)null) ? ((Object)val).name : "Licht") + "' fern " + $"({num:0.#}m) - keine Muedigkeit"); return; } localCharacter.refs.afflictions.AddStatus((STATUSTYPE)6, 0.025f, false, true, true, false); Tell($"macht muede: {2.5f:0.#} alle {3f:0.#}s"); } } private void Sing(float thick) { if ((Object)(object)_voice == (Object)null) { if (thick <= 0f) { return; } bool own; AudioClip val = Borrow(out own); if ((Object)(object)val == (Object)null) { return; } _voice = ((Component)this).gameObject.AddComponent(); _voice.clip = val; _voice.loop = true; _voice.spatialBlend = 0f; _voice.volume = 0f; _voice.outputAudioMixerGroup = FinalAscentLarder.Bus(); _voice.pitch = (own ? 1f : 0.8f); _voice.Play(); } _voice.volume = 0.55f * thick; if (thick <= 0f && _voice.isPlaying) { _voice.Stop(); Object.Destroy((Object)(object)_voice); _voice = null; } } private static AudioClip Borrow(out bool own) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) own = true; AudioSource[] array = Resources.FindObjectsOfTypeAll(); Scene scene; foreach (AudioSource val in array) { if (!((Object)(object)val == (Object)null)) { scene = ((Component)val).gameObject.scene; if (((Scene)(ref scene)).IsValid() && !((Object)(object)val.clip == (Object)null) && ((Object)((Component)val).gameObject).name.IndexOf("Gloom", StringComparison.OrdinalIgnoreCase) >= 0) { Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel: Kulisse '" + ((Object)val.clip).name + "' von '" + ((Object)((Component)val).gameObject).name + "' geliehen.")); return val.clip; } } } AudioClip[] array2 = Resources.FindObjectsOfTypeAll(); string text = ""; AudioClip[] array3 = array2; foreach (AudioClip val2 in array3) { if ((Object)(object)val2 != (Object)null && ((Object)val2).name.StartsWith("Au_Ambience", StringComparison.OrdinalIgnoreCase)) { text = text + ((text.Length > 0) ? ", " : "") + ((Object)val2).name; } } Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel: geladene Ambiente-Klaenge - " + ((text.Length > 0) ? text : "keine") + ".")); string[] wishes = Wishes; for (int i = 0; i < wishes.Length; i++) { AudioClip val3 = FinalAscentLarder.Sound(wishes[i]); if ((Object)(object)val3 != (Object)null) { Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel: Kulisse '" + ((Object)val3).name + "'.")); return val3; } } array3 = array2; foreach (AudioClip val4 in array3) { if ((Object)(object)val4 != (Object)null && ((Object)val4).name.StartsWith("Au_Ambience", StringComparison.OrdinalIgnoreCase)) { own = false; Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel: Wunschklang nicht geladen - '" + ((Object)val4).name + "' genommen und tiefer gestimmt.")); return val4; } } array = Resources.FindObjectsOfTypeAll(); foreach (AudioSource val5 in array) { if ((Object)(object)val5 != (Object)null) { scene = ((Component)val5).gameObject.scene; if (((Scene)(ref scene)).IsValid() && (Object)(object)val5.clip != (Object)null && val5.loop && val5.clip.length > 10f) { own = false; Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel: Klangbett '" + ((Object)val5.clip).name + "' von '" + ((Object)((Component)val5).gameObject).name + "' geliehen und tiefer gestimmt.")); return val5.clip; } } } Plugin.Log.LogWarning((object)"[FinalAscent] Schlafnebel: gar keine Kulisse gefunden - er bleibt stumm."); return null; } private void Tell(string what) { if (!_told) { _told = true; Plugin.Log.LogInfo((object)("[FinalAscent] Schlafnebel " + what + ".")); } } } [HarmonyPatch(typeof(DayNightManager), "UpdateCycle")] internal static class FinalAscentSleepFogSky { private const float FadeSeconds = 5f; internal static bool Wanted; internal static float Lift; private static readonly int TopKey = Shader.PropertyToID("SkyTopColor"); private static readonly int MidKey = Shader.PropertyToID("SkyMidColor"); private static readonly int LowKey = Shader.PropertyToID("SkyBottomColor"); private static void Prefix() { Lift = Mathf.MoveTowards(Lift, Wanted ? 1f : 0f, Time.deltaTime / 5f); } private static void Postfix() { } } [HarmonyPatch(typeof(AmbienceManager), "Update")] internal static class FinalAscentSleepFogSight { private const float Thick = 0.045f; private static readonly int MaxFog = Shader.PropertyToID("MAXFOG"); private static void Postfix() { float lift = FinalAscentSleepFogSky.Lift; if (!(lift <= 0f)) { float globalFloat = Shader.GetGlobalFloat(MaxFog); Shader.SetGlobalFloat(MaxFog, Mathf.Lerp(globalFloat, globalFloat * 0.045f, lift)); } } } public class FinalAscentSlipSync : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const float FallSeconds = 2f; private const float FeetForce = 200f; private const float HipForce = 1500f; private const float HeadForce = 300f; private static SFX_Instance[] _voice; [PunRPC] public void RPC_FinalAscentSlip() { Character val = ((Component)this).GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)this).GetComponentInChildren(); } if ((Object)(object)val != (Object)null) { Apply(val); } } private static void Apply(Character who) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if (who.refs == null || (Object)(object)who.refs.ragdoll == (Object)null) { return; } Vector3 lookDirection_Flat = who.data.lookDirection_Flat; who.RPCA_Fall(2f, 0f); Push(who, (BodypartType)16, (lookDirection_Flat + Vector3.up) * 200f); Push(who, (BodypartType)13, (lookDirection_Flat + Vector3.up) * 200f); Push(who, (BodypartType)0, Vector3.up * 1500f); Push(who, (BodypartType)4, lookDirection_Flat * -300f); SFX_Instance[] array = Voice(); if (array == null) { return; } for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null) { array[i].Play(who.Center); } } } private static void Push(Character who, BodypartType part, Vector3 force) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (who.refs.ragdoll.partDict.TryGetValue(part, out var value) && !((Object)(object)value == (Object)null) && !((Object)(object)value.Rig == (Object)null)) { value.Rig.AddForce(force, (ForceMode)1); } } private static SFX_Instance[] Voice() { if (_voice != null) { return _voice; } SlipperyJellyfish[] array = Resources.FindObjectsOfTypeAll(); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null && array[i].slipSFX != null && array[i].slipSFX.Length != 0) { _voice = array[i].slipSFX; Plugin.Log.LogInfo((object)"[FinalAscent] Ausrutschklang von der Qualle geliehen."); return _voice; } } BananaPeel[] array2 = Resources.FindObjectsOfTypeAll(); for (int j = 0; j < array2.Length; j++) { if ((Object)(object)array2[j] != (Object)null && array2[j].slipSFX != null && array2[j].slipSFX.Length != 0) { _voice = array2[j].slipSFX; Plugin.Log.LogInfo((object)"[FinalAscent] Ausrutschklang von der Bananenschale geliehen."); return _voice; } } Plugin.Log.LogWarning((object)"[FinalAscent] Kein Ausrutschklang gefunden - weder Qualle noch Bananenschale sind geladen. Der Sturz bleibt stumm."); return null; } } [HarmonyPatch(typeof(Character), "Awake")] internal static class FinalAscentSlipAttach { private static void Postfix(Character __instance) { PhotonView componentInParent = ((Component)__instance).GetComponentInParent(); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)((Component)componentInParent).GetComponent() != (Object)null)) { ((Component)componentInParent).gameObject.AddComponent(); componentInParent.RefreshRpcMonoBehaviourCache(); } } } [HarmonyPatch(typeof(AmbienceManager), "Update")] internal static class FinalAscentSnowFog { private const float Thick = 0.17f; private static readonly int MaxFog = Shader.PropertyToID("MAXFOG"); private static float _lastTold; private static void Postfix(AmbienceManager __instance) { float snowStrength = FinalAscentWindStorm.SnowStrength; if (!(snowStrength <= 0f)) { float globalFloat = Shader.GetGlobalFloat(MaxFog); float num = Mathf.Lerp(globalFloat, globalFloat * 0.17f, snowStrength); Shader.SetGlobalFloat(MaxFog, num); if (!(Time.unscaledTime - _lastTold < 2f)) { _lastTold = Time.unscaledTime; Plugin.Log.LogInfo((object)($"[FinalAscent] Schneenebel: Staerke {snowStrength:0.00}, Sichtweite " + $"{globalFloat:0} -> {num:0}.")); } } } } internal sealed class FinalAscentSnowMeter : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const Key ShowKey = (Key)103; private const Key ResetKey = (Key)104; private const float Step = 0.25f; private bool _shown; private float _clock; private int _low = -1; private int _high; private long _sum; private int _count; private float _since; private static bool Ducking { get { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null) { return localCharacter.data.isCrouching; } return false; } } internal static void Install(GameObject host) { if ((Object)(object)host.GetComponent() == (Object)null) { host.AddComponent(); } } private void Update() { if (Keyboard.current == null || !FinalAscentApocalypse.Active || FinalAscentDarkSky.Wanted) { return; } if (((ButtonControl)Keyboard.current[(Key)103]).wasPressedThisFrame) { _shown = !_shown; if (_shown) { Reset(); } Plugin.Log.LogInfo((object)("[FinalAscent] Flockenmesser " + (_shown ? "an" : "aus") + ".")); } if (((ButtonControl)Keyboard.current[(Key)104]).wasPressedThisFrame && _shown) { Report(); Reset(); } if (!_shown) { return; } _since += Time.deltaTime; _clock += Time.deltaTime; if (!(_clock < 0.25f)) { _clock = 0f; int num = Mathf.RoundToInt(FinalAscentWindStorm.LastOpen * 100f); if (_low < 0 || num < _low) { _low = num; } if (num > _high) { _high = num; } _sum += num; _count++; } } private void Reset() { _low = -1; _high = 0; _sum = 0L; _count = 0; _since = 0f; _clock = 0f; } private void Report() { if (_count != 0) { Plugin.Log.LogInfo((object)(string.Format("{0} MESSUNG ueber {1:0.0}s: freier Wandanteil ", "[FinalAscent]", _since) + $"kleinster {_low}%, Mittel {(float)_sum / (float)_count:0.0}%, groesster {_high}%" + $" | umschlossen {FinalAscentSnowVisual.Enclosed}" + $" | Wand frei {FinalAscentSnowVisual.Clear * 100f:0}%" + $" | geduckt {Ducking}" + $" | Wirkung {FinalAscentWindStorm.LastExposure:0.00}" + $" | Sturmstaerke {FinalAscentWindStorm.SnowStrength:0.00}.")); } } private void OnGUI() { //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Expected O, but got Unknown //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Expected O, but got Unknown //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) if (_shown) { string text = "SCHNEEMESSER F10 aus F11 neu\n" + $"frei (5 Strahl): {FinalAscentWindStorm.LastOpen * 100f:0} %\n" + $"Flocken frei : {FinalAscentSnowVisual.Clear * 100f:0} %\n" + $"kleinster : {((_low >= 0) ? _low : 0)} %\n" + $"Mittel : {((_count > 0) ? ((float)_sum / (float)_count) : 0f):0.0} %\n" + $"groesster : {_high} %\n" + $"ueber : {_since:0.0} s\n" + $"Wirkung : {FinalAscentWindStorm.LastExposure:0.00}\n" + $"Sturmstaerke : {FinalAscentWindStorm.SnowStrength:0.00}\n" + "umschlossen : " + (FinalAscentSnowVisual.Enclosed ? "ja" : "nein") + "\ngeduckt : " + (Ducking ? $"ja - Deckel {0.5f:0.00}" : "nein") + "\n" + $"Einschlaege : {FinalAscentSnowVisual.Hits} /s (nur Kenntnis)"; GUIStyle val = new GUIStyle(GUI.skin.box); val.alignment = (TextAnchor)0; val.fontSize = 14; val.normal.textColor = Color.white; val.padding = new RectOffset(10, 10, 8, 8); Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = new Color(0f, 0f, 0f, 0.85f); GUI.Box(new Rect(14f, 120f, 320f, 250f), text, val); GUI.backgroundColor = backgroundColor; } } } internal sealed class FinalAscentSnowVisual : MonoBehaviour { private const float Height = 20f; private const float Below = 2f; private const float Upwind = 14f; private const float CaveReach = 8f; private const float Lifetime = 1.4f; private const float Across = 26f; private const float Thickness = 4f; private const float FullRate = 3000f; private const float FallSpeed = 1.5f; private const float Drift = 26f; internal static int FlakeCount; internal static string Skin = "?"; internal static int Wanted; internal static int Bornt; internal static int Stunted; internal static int Visible; internal static int Hits; internal static bool EverHit; internal static bool Enclosed; internal static float Clear = 1f; private const float Near = 3.5f; private const float Smallest = 0.1f; private const float Biggest = 0.42f; private const int MostPerFrame = 120; private float _owed; private static readonly int Solid = LayerMask.GetMask(new string[2] { "Terrain", "Map" }); private const float TallySeconds = 0.25f; private readonly List _events = new List(); private int _tally; private float _tallyClock; private ParticleSystem _flakes; private ParticleSystemRenderer _rend; private ParticleSystem _far; private const float FarAcross = 130f; private const float FarHeight = 60f; private const float FarDeep = 70f; private const float FarUpwind = 35f; private const float FarRate = 2500f; private const float FarLife = 4f; private const float FarDrop = 300f; private const float FarAir = 12f; private float _farOwed; internal static FinalAscentSnowVisual Make() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown GameObject val = new GameObject("FA_SnowVisual"); Object.DontDestroyOnLoad((Object)val); FinalAscentSnowVisual finalAscentSnowVisual = val.AddComponent(); finalAscentSnowVisual.Build(); return finalAscentSnowVisual; } private void Build() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) _flakes = ((Component)this).gameObject.AddComponent(); _rend = ((Component)this).GetComponent(); _flakes.Stop(true, (ParticleSystemStopBehavior)0); MainModule main = _flakes.main; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.4f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.1f, 0.42f); ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(2.1f, 2.2f, 2.4f, 1f)); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).maxParticles = 20000; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).playOnAwake = false; ShapeModule shape = _flakes.shape; ((ShapeModule)(ref shape)).enabled = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)5; ((ShapeModule)(ref shape)).scale = new Vector3(26f, 20f, 4f); ((ShapeModule)(ref shape)).position = new Vector3(0f, 8f, 0f); EmissionModule emission = _flakes.emission; ((EmissionModule)(ref emission)).enabled = true; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); VelocityOverLifetimeModule velocityOverLifetime = _flakes.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space = (ParticleSystemSimulationSpace)1; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y = new MinMaxCurve(-1.5f); NoiseModule noise = _flakes.noise; ((NoiseModule)(ref noise)).enabled = true; ((NoiseModule)(ref noise)).strength = MinMaxCurve.op_Implicit(0.6f); ((NoiseModule)(ref noise)).frequency = 0.28f; ((NoiseModule)(ref noise)).scrollSpeed = MinMaxCurve.op_Implicit(0.35f); ((NoiseModule)(ref noise)).damping = true; ((NoiseModule)(ref noise)).quality = (ParticleSystemNoiseQuality)1; _rend.renderMode = (ParticleSystemRenderMode)1; _rend.velocityScale = 0f; _rend.lengthScale = 1f; _rend.alignment = (ParticleSystemRenderSpace)0; ((Renderer)_rend).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)_rend).receiveShadows = false; CollisionModule collision = _flakes.collision; ((CollisionModule)(ref collision)).enabled = true; ((CollisionModule)(ref collision)).type = (ParticleSystemCollisionType)1; ((CollisionModule)(ref collision)).mode = (ParticleSystemCollisionMode)0; ((CollisionModule)(ref collision)).quality = (ParticleSystemCollisionQuality)1; ((CollisionModule)(ref collision)).collidesWith = LayerMask.op_Implicit(LayerMask.GetMask(new string[3] { "Terrain", "Map", "Character" })); ((CollisionModule)(ref collision)).lifetimeLoss = MinMaxCurve.op_Implicit(1f); ((CollisionModule)(ref collision)).dampen = MinMaxCurve.op_Implicit(1f); ((CollisionModule)(ref collision)).bounce = MinMaxCurve.op_Implicit(0f); ((CollisionModule)(ref collision)).sendCollisionMessages = true; ((Renderer)_rend).sharedMaterial = FinalAscentRainVisual.Borrow(out var from, new string[2] { "Snowflake softy", "M_snow-UV" }); Skin = (((Object)(object)((Renderer)_rend).sharedMaterial != (Object)null) ? ((Object)((Renderer)_rend).sharedMaterial).name : "keiner"); ManualLogSource log = Plugin.Log; string[] obj = new string[10] { "[FinalAscent] Flocken gebaut - Werkstoff '", Skin, "' von ", from, ", ", null, null, null, null, null }; MinMaxCurve startSize = ((MainModule)(ref main)).startSize; object arg = ((MinMaxCurve)(ref startSize)).constantMin; startSize = ((MainModule)(ref main)).startSize; obj[5] = $"{arg:0.##}-{((MinMaxCurve)(ref startSize)).constantMax:0.##} "; MinMaxGradient startColor = ((MainModule)(ref main)).startColor; obj[6] = $"breit, Farbe {((MinMaxGradient)(ref startColor)).color}, Sinken {1.5f:0.#}, Zug "; obj[7] = $"{26f:0.#}, Wand {26f:0.#}x{20f:0.#}x{4f:0.#} in "; obj[8] = $"{14f:0.#}m Luv, bis zu {3000f:0} je Sekunde, Lebensdauer "; obj[9] = $"{1.4f:0.0}s."; log.LogInfo((object)string.Concat(obj)); BuildFar(); _flakes.Play(); } private void BuildFar() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0076: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00dd: 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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Far"); val.transform.SetParent(((Component)this).transform, false); _far = val.AddComponent(); ParticleSystemRenderer component = val.GetComponent(); _far.Stop(true, (ParticleSystemStopBehavior)0); MainModule main = _far.main; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(4f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.5f, 1.2f); ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(1.5f, 1.55f, 1.7f, 0.8f)); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).maxParticles = 20000; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).playOnAwake = false; ShapeModule shape = _far.shape; ((ShapeModule)(ref shape)).enabled = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)5; ((ShapeModule)(ref shape)).scale = new Vector3(130f, 60f, 70f); EmissionModule emission = _far.emission; ((EmissionModule)(ref emission)).enabled = true; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); VelocityOverLifetimeModule velocityOverLifetime = _far.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space = (ParticleSystemSimulationSpace)1; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y = new MinMaxCurve(-1.5f); NoiseModule noise = _far.noise; ((NoiseModule)(ref noise)).enabled = true; ((NoiseModule)(ref noise)).strength = MinMaxCurve.op_Implicit(1.1f); ((NoiseModule)(ref noise)).frequency = 0.28f; ((NoiseModule)(ref noise)).scrollSpeed = MinMaxCurve.op_Implicit(0.35f); ((NoiseModule)(ref noise)).damping = true; ((NoiseModule)(ref noise)).quality = (ParticleSystemNoiseQuality)1; component.renderMode = (ParticleSystemRenderMode)1; component.velocityScale = 0f; component.lengthScale = 1f; component.alignment = (ParticleSystemRenderSpace)0; ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component).receiveShadows = false; ((Renderer)component).sharedMaterial = ((Renderer)_rend).sharedMaterial; CollisionModule collision = _far.collision; ((CollisionModule)(ref collision)).enabled = true; ((CollisionModule)(ref collision)).type = (ParticleSystemCollisionType)1; ((CollisionModule)(ref collision)).mode = (ParticleSystemCollisionMode)0; ((CollisionModule)(ref collision)).quality = (ParticleSystemCollisionQuality)1; ((CollisionModule)(ref collision)).collidesWith = LayerMask.op_Implicit(Solid); ((CollisionModule)(ref collision)).lifetimeLoss = MinMaxCurve.op_Implicit(1f); ((CollisionModule)(ref collision)).dampen = MinMaxCurve.op_Implicit(1f); ((CollisionModule)(ref collision)).bounce = MinMaxCurve.op_Implicit(0f); ((CollisionModule)(ref collision)).sendCollisionMessages = false; _far.Play(); } private void Far(Vector3 wind, float strength) { //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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_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_0113: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_018a: 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_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_far == (Object)null) { return; } EmissionModule emission = _far.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); VelocityOverLifetimeModule velocityOverLifetime = _far.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = new MinMaxCurve(wind.x * 26f * strength); ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).z = new MinMaxCurve(wind.z * 26f * strength); if (strength <= 0f) { _farOwed = 0f; return; } _farOwed += 2500f * strength * Time.deltaTime; int num = Mathf.FloorToInt(_farOwed); if (num <= 0) { return; } _farOwed -= num; if (num > 120) { num = 120; _farOwed = 0f; } Vector3 val = Vector3.Cross(Vector3.up, wind); Vector3 normalized = ((Vector3)(ref val)).normalized; Vector3 val2 = ((Component)this).transform.position - wind * 35f + Vector3.up * 18f; Vector3 val3 = wind * (26f * strength) + Vector3.down * 1.5f; float magnitude = ((Vector3)(ref val3)).magnitude; Vector3 val4 = ((magnitude > 0.01f) ? (val3 / magnitude) : wind); float num2 = magnitude * 4f; EmitParams val5 = default(EmitParams); ((EmitParams)(ref val5)).applyShapeToPosition = false; RaycastHit val7 = default(RaycastHit); RaycastHit val8 = default(RaycastHit); for (int i = 0; i < num; i++) { Vector3 val6 = val2 + normalized * Random.Range(-65f, 65f) + Vector3.up * Random.Range(-30f, 30f) + wind * Random.Range(-35f, 35f); if (Physics.Raycast(val6, Vector3.down, ref val7, 300f, Solid) && !(((RaycastHit)(ref val7)).distance < 12f)) { ((EmitParams)(ref val5)).startLifetime = (Physics.Raycast(val6, val4, ref val8, num2, Solid) ? (((RaycastHit)(ref val8)).distance / magnitude) : 4f); ((EmitParams)(ref val5)).position = val6; ((EmitParams)(ref val5)).startSize = Random.Range(0.35f, 1.4f); _far.Emit(val5, 1); } } } private void OnParticleCollision(GameObject other) { if ((Object)(object)other == (Object)null || (Object)(object)_flakes == (Object)null) { return; } Character componentInParent = other.GetComponentInParent(); if (!((Object)(object)componentInParent == (Object)null) && componentInParent.IsLocal) { _tally += ParticlePhysicsExtensions.GetCollisionEvents(_flakes, other, _events); if (!EverHit) { EverHit = true; Plugin.Log.LogInfo((object)"[FinalAscent] Erste Flocke hat den Spieler getroffen - der Versteckmelder arbeitet."); } } } private void Update() { _tallyClock += Time.deltaTime; if (!(_tallyClock < 0.25f)) { Hits = Mathf.RoundToInt((float)_tally / _tallyClock); _tally = 0; _tallyClock = 0f; } } internal void Show(Vector3 where, Vector3 wind, float strength) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_flakes == (Object)null)) { ((Component)this).transform.position = where; FlakeCount = _flakes.particleCount; Enclosed = Physics.Raycast(where, Vector3.up, 8f, Solid) && Physics.Raycast(where, -wind, 8f, Solid) && Physics.Raycast(where, wind, 8f, Solid); float num = Mathf.Clamp01(strength); VelocityOverLifetimeModule velocityOverLifetime = _flakes.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = new MinMaxCurve(wind.x * 26f * num); ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).z = new MinMaxCurve(wind.z * 26f * num); Sow(where, wind, num); Far(wind, num); } } private void Sow(Vector3 where, Vector3 wind, float power) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) EmissionModule emission = _flakes.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); if (power <= 0f) { Clear = 0f; _owed = 0f; return; } _owed += 3000f * power * Time.deltaTime; int num = Mathf.FloorToInt(_owed); if (num <= 0) { return; } _owed -= num; if (num > 120) { num = 120; _owed = 0f; } Vector3 val = Vector3.Cross(Vector3.up, wind); Vector3 normalized = ((Vector3)(ref val)).normalized; Vector3 val2 = where - wind * 14f + Vector3.up * 8f; EmitParams val3 = default(EmitParams); ((EmitParams)(ref val3)).applyShapeToPosition = false; Vector3 val4 = wind * (26f * power) + Vector3.down * 1.5f; float magnitude = ((Vector3)(ref val4)).magnitude; Vector3 val5 = ((magnitude > 0.01f) ? (val4 / magnitude) : wind); float num2 = magnitude * 1.4f; int num3 = 0; int num4 = 0; int num5 = 0; Wanted = num; Bornt = 0; Stunted = 0; RaycastHit val7 = default(RaycastHit); for (int i = 0; i < num; i++) { Vector3 val6 = val2 + normalized * Random.Range(-13f, 13f) + Vector3.up * Random.Range(-10f, 10f) + wind * Random.Range(-2f, 2f); if (Physics.Linecast(where, val6, Solid)) { continue; } num5++; float num6 = 1.4f; float num7 = num2; if (Physics.Raycast(val6, val5, ref val7, num2, Solid)) { num6 = ((RaycastHit)(ref val7)).distance / magnitude; num7 = ((RaycastHit)(ref val7)).distance; } float num8 = Mathf.Clamp(Vector3.Dot(where - val6, val5), 0f, num2); if (Vector3.Distance(val6 + val5 * num8, where) <= 3.5f) { num3++; if (num7 >= num8) { num4++; } } if (num6 < 0.14f) { Stunted++; continue; } ((EmitParams)(ref val3)).position = val6; ((EmitParams)(ref val3)).startLifetime = num6; ((EmitParams)(ref val3)).startSize = Random.Range(0.1f, 0.42f); _flakes.Emit(val3, 1); Bornt++; } Visible = num5; if (num5 <= 0) { Clear = Mathf.MoveTowards(Clear, 0f, Time.deltaTime * 4f); } else if (num3 > 0) { Clear = Mathf.Lerp(Clear, (float)num4 / (float)num3, Time.deltaTime * 2f); } } } internal static class FinalAscentSoftLanding { private const string Tag = "[FinalAscent]"; private const float Lift = 0.5f; private static Coroutine _running; internal static void Begin() { if ((Object)(object)Plugin.Instance == (Object)null) { return; } Vector3 at; bool unconscious; int stage; bool flag = FinalAscentRoster.TryReadOwn(out at, out unconscious, out stage); int stage2 = FinalAscentRoom.Stage; if (!FinalAscentRoom.JoinedLate && stage2 <= 0) { Plugin.Log.LogInfo((object)(string.Format("{0} Frischer Start (Etappenstand {1}, Eintrag ", "[FinalAscent]", stage2) + (flag ? "vorhanden" : "fehlt") + ") - es gibt nichts zurueckzuversetzen.")); return; } Plugin.Log.LogInfo((object)("[FinalAscent] Rueckkehr erkannt: Eintrag " + (flag ? "vorhanden" : "fehlt") + ", " + $"Etappenstand der Gruppe {stage2}, spaet beigetreten " + $"{FinalAscentRoom.JoinedLate}.")); if (_running != null) { ((MonoBehaviour)Plugin.Instance).StopCoroutine(_running); } _running = ((MonoBehaviour)Plugin.Instance).StartCoroutine(Hold()); } private static Vector3? NearestMate(Character me) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) foreach (Character allCharacter in Character.AllCharacters) { if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)me) && !allCharacter.isBot && !((Object)(object)allCharacter.data == (Object)null) && !allCharacter.data.dead && !allCharacter.data.fullyPassedOut) { return allCharacter.Center; } } return null; } private static IEnumerator Hold() { Vector3 saved; bool unconscious; int savedStage; bool known = FinalAscentRoster.TryReadOwn(out saved, out unconscious, out savedStage); FinalAscentRoster.Unlatch(); float patience = 60f; while (patience > 0f && (Object)(object)Character.localCharacter == (Object)null) { patience -= Time.deltaTime; yield return null; } Character me = Character.localCharacter; if ((Object)(object)me == (Object)null) { Plugin.Log.LogError((object)"[FinalAscent] RUECKKEHR MISSLUNGEN: nach 60s gibt es keine eigene Figur. Die Position konnte NICHT gesetzt werden."); _running = null; yield break; } if (known && unconscious) { Plugin.Log.LogInfo((object)"[FinalAscent] Laut Melderegister war dieser Spieler beim Abbruch ohnmaechtig - er wird an seinen Platz versetzt, aber nicht wiederbelebt."); } int stage = FinalAscentRoom.Stage; Vector3? val = null; string text = null; if (known && savedStage == stage) { val = saved; text = $"gemerkte Position (Etappe {savedStage} laeuft noch)"; } else if (stage > 0) { val = FinalAscentSegments.EntryCampOfStage(stage); text = (known ? $"Anfang der Etappe {stage} (gemerkte Etappe {savedStage} ist vorbei)" : $"Anfang der Etappe {stage} (kein Eintrag im Melderegister)"); if (!val.HasValue) { val = FinalAscentSegments.CampOfStage(stage); text = $"Lagerfeuer der Etappe {stage} - der Anfang war nicht zu finden"; } if (!val.HasValue && known) { val = saved; text = $"gemerkte Position aus Etappe {savedStage} - zur laufenden " + $"Etappe {stage} war kein Lagerfeuer zu finden"; } if (!val.HasValue) { val = NearestMate(me); text = "Platz eines Mitspielers - zu dieser Etappe war nichts zu finden"; } } if (!val.HasValue && stage > 0) { Plugin.Log.LogError((object)(string.Format("{0} RUECKKEHR OHNE ZIEL: Etappenstand {1}, Eintrag ", "[FinalAscent]", stage) + (known ? "vorhanden" : "fehlt") + " - es liess sich KEIN Ort bestimmen. Der Spieler bleibt, wo Vanilla ihn hingesetzt hat.")); } if (val.HasValue && (Object)(object)((MonoBehaviourPun)me).photonView == (Object)null) { Plugin.Log.LogWarning((object)"[FinalAscent] Rueckkehrer hat keine Rufnummer - er wird ohne Netzruf versetzt."); ((Component)me).transform.position = val.Value + Vector3.up * 1f; } if (val.HasValue && (Object)(object)((MonoBehaviourPun)me).photonView != (Object)null && Vector3.Distance(me.Center, val.Value) > 3f) { Vector3 val2 = val.Value + Vector3.up * 1f; Plugin.Log.LogInfo((object)("[FinalAscent] Rueckkehrer wird versetzt: " + text + " " + $"({val2.x:F0} / {val2.y:F0} / {val2.z:F0}).")); try { ((MonoBehaviourPun)me).photonView.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { val2, false }); if ((Object)(object)me.data != (Object)null && me.data.dead && (known ? (!unconscious) : (stage > 0))) { Plugin.Log.LogWarning((object)"[FinalAscent] Vanilla hat diesen Spieler als Geist gestellt, das Melderegister sagt WACH - er wird am Ziel wiederbelebt."); ((MonoBehaviourPun)me).photonView.RPC("RPCA_ReviveAtPosition", (RpcTarget)0, new object[3] { val2, false, -1 }); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Versetzen fehlgeschlagen: " + ex.Message)); } yield return (object)new WaitForFixedUpdate(); } List bodies = new List(); if (me.refs != null && (Object)(object)me.refs.ragdoll != (Object)null && me.refs.ragdoll.partList != null) { foreach (Bodypart part in me.refs.ragdoll.partList) { if ((Object)(object)part != (Object)null && (Object)(object)part.Rig != (Object)null && !part.Rig.isKinematic) { bodies.Add(part.Rig); } } } if (bodies.Count == 0) { Plugin.Log.LogInfo((object)"[FinalAscent] Nichts zum Festhalten (Geist oder starre Puppe) - versetzt wurde trotzdem."); _running = null; yield break; } List before = new List(bodies.Count); foreach (Rigidbody item in bodies) { item.position += Vector3.up * 0.5f; item.linearVelocity = Vector3.zero; item.angularVelocity = Vector3.zero; before.Add(item.constraints); item.constraints = (RigidbodyConstraints)126; } Plugin.Log.LogInfo((object)(string.Format("{0} Figur um {1:F1} angehoben und arretiert ", "[FinalAscent]", 0.5f) + $"({bodies.Count} Koerperteile) - bis der Berg fertig gemeldet ist.")); float sinceDone = -1f; float held = 0f; while (held < 10f) { if (FinalAscentBuilder.Done && !FinalAscentBuilder.Building && sinceDone < 0f) { sinceDone = 0f; } if (sinceDone >= 0.75f) { break; } if ((Object)(object)me.data != (Object)null) { me.data.fallSeconds = 0f; me.data.sinceGrounded = 0f; } yield return (object)new WaitForFixedUpdate(); held += Time.fixedDeltaTime; if (sinceDone >= 0f) { sinceDone += Time.fixedDeltaTime; } } RaycastHit val3 = default(RaycastHit); if (Physics.Raycast(me.Center + Vector3.up * 0.5f, Vector3.down, ref val3, 30f, LayerMask.op_Implicit(HelperFunctions.terrainMapMask), (QueryTriggerInteraction)1)) { float num = me.Center.y - ((RaycastHit)(ref val3)).point.y; if (num > 1.2f) { Vector3 val4 = Vector3.down * (num - 1f); foreach (Rigidbody item2 in bodies) { if ((Object)(object)item2 != (Object)null) { item2.position += val4; } } Plugin.Detail(string.Format("{0} Vor dem Loslassen um {1:F1} abgesenkt.", "[FinalAscent]", num - 1f)); } } if ((Object)(object)me.data != (Object)null) { me.data.fallSeconds = 0f; me.data.sinceGrounded = 0f; } for (int i = 0; i < bodies.Count; i++) { Rigidbody val5 = bodies[i]; if (!((Object)(object)val5 == (Object)null)) { val5.constraints = (RigidbodyConstraints)((i < before.Count) ? ((int)before[i]) : 0); val5.linearVelocity = Vector3.zero; val5.angularVelocity = Vector3.zero; } } Plugin.Log.LogInfo((object)(string.Format("{0} Figur geloest nach {1:F1}s Arretierung", "[FinalAscent]", held) + ((held >= 10f) ? " (Hoechstdauer erreicht)." : "."))); _running = null; } } internal static class FinalAscentSpawnAudit { [HarmonyPatch(typeof(PropSpawner), "TryToSpawn")] private static class TryPatch { private static void Prefix() { if (_on) { _attempts++; _pendingConstraint = null; _spawnRan = false; } } private static void Postfix(bool __result) { if (_on) { if (__result) { _successes++; } else { Count(_pendingConstraint ?? (_spawnRan ? "Nachpruefung" : "kein Punkt")); } } } } [HarmonyPatch(typeof(PropSpawner), "Spawn")] private static class SpawnPatch { private static void Prefix() { if (_on) { _spawnRan = true; } } } [HarmonyPatch(typeof(PropSpawner), "AllConstraintsPass")] private static class ConstraintPatch { private static bool Prefix(IEnumerable currentConstraints, SpawnData spawnData, ref bool __result) { if (!_on) { return true; } foreach (PropSpawnerConstraint currentConstraint in currentConstraints) { if (currentConstraint != null && !currentConstraint.mute && !currentConstraint.CheckConstraint(spawnData)) { _pendingConstraint = ((object)currentConstraint).GetType().Name; __result = false; return false; } } __result = true; return false; } } private static readonly Dictionary _rejects = new Dictionary(); private static int _attempts; private static int _successes; private static string _pendingConstraint; private static bool _spawnRan; private static bool _on; internal static void Begin() { _on = FinalAscent.Active; _attempts = 0; _successes = 0; _rejects.Clear(); } internal static string Summary() { if (!_on || _attempts == 0) { return null; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("versuche ").Append(_attempts).Append(", gelungen ") .Append(_successes); if (_rejects.Count > 0) { stringBuilder.Append(", abgelehnt:"); foreach (KeyValuePair reject in _rejects) { stringBuilder.Append(' ').Append(reject.Key).Append(' ') .Append(reject.Value); } } _attempts = 0; _successes = 0; _rejects.Clear(); return stringBuilder.ToString(); } private static void Count(string reason) { _rejects.TryGetValue(reason, out var value); _rejects[reason] = value + 1; } } [HarmonyPatch] internal static class FinalAscentSpawnGate { private const string Tag = "[FinalAscent]"; private static bool _replaying; internal static int Held; private static bool Blocked { get { if (FinalAscentBuilder.Awaited) { return !_replaying; } return false; } } internal static bool Holding => Held > 0; [HarmonyPatch(typeof(CharacterSpawner), "SpawnHostCharacter")] [HarmonyPrefix] private static bool BeforeHostSpawn() { if (!Blocked) { return true; } return false; } [HarmonyPatch(typeof(CharacterSpawner), "RPC_NewPlayerSpawn")] [HarmonyPrefix] private static bool BeforeGuestSpawn(CharacterSpawner __instance, Segment currentMapStage, bool canRevive, int lastReviveSegment, PhotonMessageInfo info) { //IL_002a: 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) if (!Blocked) { return true; } Held++; Plugin.Log.LogInfo((object)"[FinalAscent] Spawnruf fuer diesen Spieler kam, waehrend der Berg noch gebaut wird - er wird aufgehoben und nachgeholt."); ((MonoBehaviour)Plugin.Instance).StartCoroutine(Later(__instance, currentMapStage, canRevive, lastReviveSegment, info)); return false; } private static IEnumerator Later(CharacterSpawner spawner, Segment currentMapStage, bool canRevive, int lastReviveSegment, PhotonMessageInfo info) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) float waited = 0f; while (!FinalAscentBuilder.Ready && waited < 120f) { waited += Time.unscaledDeltaTime; yield return null; } if ((Object)(object)spawner == (Object)null) { Plugin.Log.LogWarning((object)"[FinalAscent] Der Spawner ist verschwunden, bevor der Berg stand - der aufgehobene Ruf verfaellt."); yield break; } Plugin.Log.LogInfo((object)string.Format("{0} Berg steht nach {1:F1}s - der aufgehobene Spawnruf wird nachgeholt.", "[FinalAscent]", waited)); Held = Math.Max(0, Held - 1); _replaying = true; try { spawner.RPC_NewPlayerSpawn(currentMapStage, canRevive, lastReviveSegment, info); } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("{0} Nachgeholter Spawnruf wirft: {1}", "[FinalAscent]", arg)); } finally { _replaying = false; } } } [HarmonyPatch(typeof(SpawnPoint), "GetSpawnPoint")] internal static class FinalAscentSpawnPointLog { private static void Postfix(int actorNumber, SpawnPoint __result) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (FinalAscent.Active) { Plugin.Log.LogInfo((object)("[FinalAscent] Spawnpunkt fuer Platz " + actorNumber + ": " + (((Object)(object)__result != (Object)null) ? ("'" + ((Object)__result).name + "' bei " + FinalAscentBuilder.Fmt(((Component)__result).transform.position)) : "KEINER") + " - " + SpawnPoint.allSpawnPoints.Count + " Punkte angemeldet, Berg " + (FinalAscentBuilder.Ready ? "steht" : "IM BAU") + ".")); } } } internal sealed class FinalAscentSporeCloud : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const float Dose = 0.02f; private const float Ducked = 0.5f; private const float Downward = -0.35f; private const float Nearest = 15f; private const float Furthest = 25f; private const float Arc = 65f; private const float Below = 3f; private const float Spare = 10f; private const int Tries = 12; private const float Linger = 2f; private static FinalAscentSporeCloud _instance; private static GameObject _seed; private static bool _searched; private static bool _up; private float _clock; private bool _told; private static string _how = ""; private const float Hold = 40f; 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_SporeCloud"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); FinalAscentSporeVisual.Install(); } if (!((Object)(object)_instance == (Object)null)) { if (on) { _up = true; _instance._clock = 0f; _instance._told = false; FinalAscentSporeSky.Holding = false; } else if (_up) { _up = false; FinalAscentSporeSky.Holding = true; ((MonoBehaviour)_instance).StartCoroutine(_instance.Settle()); } } } private void Update() { if (!FinalAscentSporeSky.Wanted || !FinalAscentSporeSky.Full) { return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || localCharacter.refs == null || (Object)(object)localCharacter.refs.afflictions == (Object)null || localCharacter.data.dead) { return; } _clock += Time.deltaTime; if (!(_clock < 1f)) { _clock -= 1f; float num = 0.02f * (Tucked(localCharacter) ? 0.5f : 1f); localCharacter.refs.afflictions.AddStatus((STATUSTYPE)10, num, false, true, true, false); if (!_told) { _told = true; Plugin.Log.LogInfo((object)(string.Format("{0} Sporenwolke: {1:0.#} Sporen je Sekunde, ", "[FinalAscent]", 2f) + $"geduckt und nach unten {1f:0.#}.")); } } } internal static bool Tucked(Character who) { if ((Object)(object)who != (Object)null && (Object)(object)who.data != (Object)null && who.data.isCrouching) { return who.data.lookDirection.y <= -0.35f; } return false; } private IEnumerator Settle() { Condense(); yield return (object)new WaitForSeconds(2f); FinalAscentSporeSky.Holding = false; } private void Condense() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient) { return; } GameObject val = Sleeper(); if ((Object)(object)val == (Object)null) { return; } List list = Living(); if (list.Count == 0) { return; } Vector3 hub = Middle(list); Vector3 back = Behind(list, hub); float value = Random.value; int num = ((value < 0.1f) ? 3 : ((!(value < 0.6f)) ? 1 : 2)); int num2 = 0; for (int i = 0; i < num; i++) { if (Spot(hub, back, list, out var where) && (Object)(object)Raise(val, where, Nearestest(where, list)) != (Object)null) { num2++; } } Plugin.Log.LogInfo((object)(string.Format("{0} Sporenwolke zieht ab: {1} gewuerfelt, {2} Pilzzombies ", "[FinalAscent]", num, num2) + "hinter der Gruppe aufgestanden (" + _how + "). Sie bleiben und leben ihre eigene Zeit.")); } private static Vector3 Middle(List all) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) Vector3 val = Vector3.zero; for (int i = 0; i < all.Count; i++) { val += all[i].Center; } return val / (float)Mathf.Max(1, all.Count); } private static Vector3 Behind(List all, Vector3 hub) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) Character val = null; for (int i = 0; i < all.Count; i++) { if ((Object)(object)val == (Object)null || all[i].Center.y > val.Center.y) { val = all[i]; } } if ((Object)(object)val == (Object)null) { return Vector3.zero; } Vector3 val2 = hub - val.Center; val2.y = 0f; if (!(((Vector3)(ref val2)).sqrMagnitude > 1f)) { return Vector3.zero; } return ((Vector3)(ref val2)).normalized; } private static bool Spot(Vector3 hub, Vector3 back, List all, out Vector3 where) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 3; i++) { Vector3 heading = ((i < 2) ? back : Vector3.zero); bool flag = i == 0; for (int j = 0; j < 12; j++) { if (FinalAscentSpot.Toward(hub, heading, 65f, 15f, 25f, 1, out where) && (!flag || !(where.y > hub.y - 3f)) && !Crowded(where, all)) { _how = i switch { 1 => "hinter, aber nicht tiefer", 0 => "hinter und tiefer", _ => "irgendwo im Ring", }; return true; } } } where = hub; _how = "keine Stelle gefunden"; return false; } private static Character Nearestest(Vector3 where, List all) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) Character result = null; float num = float.MaxValue; for (int i = 0; i < all.Count; i++) { Character val = all[i]; if (!((Object)(object)val == (Object)null)) { float num2 = Vector3.Distance(val.Center, where); if (num2 < num) { num = num2; result = val; } } } return result; } private static bool Crowded(Vector3 where, List all) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < all.Count; i++) { Character val = all[i]; if ((Object)(object)val != (Object)null && Vector3.Distance(val.Center, where) < 10f) { return true; } } return false; } private static List Living() { List allPlayerCharacters = PlayerHandler.GetAllPlayerCharacters(); List list = new List(); 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) { list.Add(val); } } return list; } private static GameObject Sleeper() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_seed != (Object)null || _searched) { return _seed; } _searched = true; MushroomZombie[] array = Resources.FindObjectsOfTypeAll(); foreach (MushroomZombie val in array) { if (!((Object)(object)val == (Object)null)) { Scene scene = ((Component)val).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { _seed = ((Component)val).gameObject; Plugin.Log.LogInfo((object)("[FinalAscent] Sporenwolke: Zombievorlage '" + ((Object)_seed).name + "' gefunden.")); return _seed; } } } Plugin.Log.LogWarning((object)"[FinalAscent] Sporenwolke: keine Zombievorlage gefunden - sie zieht ohne Rest ab."); return null; } private GameObject Raise(GameObject seed, Vector3 where, Character after) { //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 val = PhotonNetwork.Instantiate(((Object)seed).name, where, Quaternion.Euler(0f, Random.value * 360f, 0f), (byte)0, (object[])null); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("[FinalAscent] Sporenwolke: '" + ((Object)seed).name + "' liess sich nicht absetzen.")); return null; } ((MonoBehaviour)this).StartCoroutine(Rise(val, after)); return val; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Sporenwolke: '" + ((Object)seed).name + "' nicht vernetzbar (" + ex.GetType().Name + ").")); return null; } } private IEnumerator Rise(GameObject born, Character after) { MushroomZombie zombie = born.GetComponentInChildren(true); PhotonView componentInChildren = born.GetComponentInChildren(true); if ((Object)(object)zombie == (Object)null || (Object)(object)componentInChildren == (Object)null) { yield break; } zombie.currentState = (State)1; if ((Object)(object)after != (Object)null && (Object)(object)((MonoBehaviourPun)after).photonView != (Object)null) { componentInChildren.RPC("RPCA_SetCurrentTarget", (RpcTarget)0, new object[2] { ((MonoBehaviourPun)after).photonView.ViewID, 40f }); } yield return (object)new WaitForSeconds(zombie.initialWakeUpTime + 0.5f); if (!((Object)(object)zombie == (Object)null)) { Character componentInChildren2 = born.GetComponentInChildren(true); if ((Object)(object)componentInChildren2 != (Object)null && (Object)(object)componentInChildren2.data != (Object)null) { componentInChildren2.data.passedOut = false; } zombie.currentState = (State)3; } } } [HarmonyPatch(typeof(DayNightManager), "UpdateCycle")] internal static class FinalAscentSporeSky { private const float FadeSeconds = 4f; internal static bool Wanted; internal static float Lift; internal static bool Holding; private static readonly Color SkyHigh = new Color(0.3f, 0.1f, 0.09f, 1f); private static readonly Color SkyMid = new Color(0.44f, 0.15f, 0.13f, 1f); private static readonly Color SkyLow = new Color(0.55f, 0.22f, 0.18f, 1f); private static readonly Color Glow = new Color(0.95f, 0.62f, 0.52f, 1f); private static readonly int TopKey = Shader.PropertyToID("SkyTopColor"); private static readonly int MidKey = Shader.PropertyToID("SkyMidColor"); private static readonly int LowKey = Shader.PropertyToID("SkyBottomColor"); private static readonly int FogKey = Shader.PropertyToID("MAXFOG"); private const float Thick = 0.22f; private static float _wasFog = -1f; private static float Daylight = 1f; private const float Gloom = 0.68f; internal static bool Full => Lift >= 1f; private static float Lum(Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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) return c.r * 0.299f + c.g * 0.587f + c.b * 0.114f; } private static Color Dim(Color c, float by) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) return new Color(c.r * by, c.g * by, c.b * by, c.a); } private static void Prefix() { bool flag = Wanted || Holding; Lift = Mathf.MoveTowards(Lift, flag ? 1f : 0f, Time.deltaTime / 4f); } private static void Postfix(DayNightManager __instance) { //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_0058: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) if (Lift <= 0f) { if (_wasFog >= 0f) { Shader.SetGlobalFloat(FogKey, _wasFog); _wasFog = -1f; } return; } if (_wasFog < 0f) { _wasFog = Shader.GetGlobalFloat(FogKey); } Color globalColor = Shader.GetGlobalColor(LowKey); float num = Lum(SkyLow); Daylight = ((num > 0.0001f) ? Mathf.Clamp01(Lum(globalColor) / num) : 1f) * 0.68f; Shader.SetGlobalColor(TopKey, Color.Lerp(Shader.GetGlobalColor(TopKey), Dim(SkyHigh, Daylight), Lift)); Shader.SetGlobalColor(MidKey, Color.Lerp(Shader.GetGlobalColor(MidKey), Dim(SkyMid, Daylight), Lift)); Shader.SetGlobalColor(LowKey, Color.Lerp(globalColor, Dim(SkyLow, Daylight), Lift)); Shader.SetGlobalFloat(FogKey, Mathf.Lerp(_wasFog, _wasFog * 0.22f, Lift)); Color val = Dim(Glow, Daylight); if ((Object)(object)__instance.sun != (Object)null) { __instance.sun.color = Color.Lerp(__instance.sun.color, val, Lift); } if ((Object)(object)__instance.moon != (Object)null) { __instance.moon.color = Color.Lerp(__instance.moon.color, val, Lift); } } } internal sealed class FinalAscentSporeVisual : MonoBehaviour { private const string Tag = "[FinalAscent]"; private const string ShaderName = "SmokeParticleSimple"; private const string TextureName = "A_Texture 60"; private static readonly string[] Bases = new string[4] { "SporeSmokeExplo", "HealingSporeSmoke", "PetrifyExplo", "SmokeKick" }; private const float Around = 38f; private const float FullRate = 170f; private const float Lifetime = 5f; private const float Smallest = 3f; private const float Biggest = 10f; private static readonly Color Seed = new Color(0.8155f, 1f, 0.051f, 1f); private ParticleSystem _motes; private static FinalAscentSporeVisual _instance; private float _lastTold; private const float Density = 0.85f; internal static void Install() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("FA_Spores"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } } private void LateUpdate() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) float lift = FinalAscentSporeSky.Lift; Character localCharacter = Character.localCharacter; if (lift <= 0f || (Object)(object)localCharacter == (Object)null) { if ((Object)(object)_motes != (Object)null && _motes.isPlaying) { _motes.Stop(true, (ParticleSystemStopBehavior)1); } return; } if ((Object)(object)_motes == (Object)null) { Build(); } if (!((Object)(object)_motes == (Object)null)) { ((Component)this).transform.position = localCharacter.Center; if (!_motes.isPlaying) { _motes.Play(); } EmissionModule emission = _motes.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(170f * lift); if (Time.unscaledTime - _lastTold >= 2f) { _lastTold = Time.unscaledTime; ParticleSystemRenderer component = ((Component)this).GetComponent(); Plugin.Log.LogInfo((object)(string.Format("{0} Sporenwerk: {1} Teilchen leben, Rate ", "[FinalAscent]", _motes.particleCount) + $"{170f * lift:0}, Werkstoff " + (((Object)(object)component != (Object)null && (Object)(object)((Renderer)component).sharedMaterial != (Object)null) ? ((Object)((Renderer)component).sharedMaterial).name : "KEINER") + ", sichtbar " + (((Object)(object)component != (Object)null && ((Renderer)component).isVisible) ? "ja" : "nein") + ", " + $"Stelle {((Component)this).transform.position}.")); } } } private void Build() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) _motes = ((Component)this).gameObject.AddComponent(); MainModule main = _motes.main; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(5f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).startSize = new MinMaxCurve(3f, 10f); ((MainModule)(ref main)).startRotation = new MinMaxCurve(0f, MathF.PI * 2f); ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(Seed); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).maxParticles = 2000; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).playOnAwake = false; ShapeModule shape = _motes.shape; ((ShapeModule)(ref shape)).enabled = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = 38f; EmissionModule emission = _motes.emission; ((EmissionModule)(ref emission)).enabled = true; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); ColorOverLifetimeModule colorOverLifetime = _motes.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = new MinMaxGradient(Fade()); RotationOverLifetimeModule rotationOverLifetime = _motes.rotationOverLifetime; ((RotationOverLifetimeModule)(ref rotationOverLifetime)).enabled = true; ((RotationOverLifetimeModule)(ref rotationOverLifetime)).z = new MinMaxCurve(-MathF.PI / 180f, MathF.PI / 180f); NoiseModule noise = _motes.noise; ((NoiseModule)(ref noise)).enabled = true; ((NoiseModule)(ref noise)).strength = MinMaxCurve.op_Implicit(0.1f); ((NoiseModule)(ref noise)).frequency = 0.5f; ((NoiseModule)(ref noise)).scrollSpeed = MinMaxCurve.op_Implicit(0.1f); ((NoiseModule)(ref noise)).damping = true; ((NoiseModule)(ref noise)).quality = (ParticleSystemNoiseQuality)1; ((NoiseModule)(ref noise)).octaveCount = 1; ((NoiseModule)(ref noise)).octaveMultiplier = 0.5f; ((NoiseModule)(ref noise)).octaveScale = 2f; ParticleSystemRenderer component = ((Component)this).GetComponent(); component.renderMode = (ParticleSystemRenderMode)0; ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component).receiveShadows = false; ((Renderer)component).sharedMaterial = Cloth(); Plugin.Log.LogInfo((object)(string.Format("{0} Sporenwerk gebaut: Kugel {1:0}m, Teilchen {2:0}-{3:0} ", "[FinalAscent]", 38f, 3f, 10f) + $"gross, {170f:0}/s, Werkstoff " + (((Object)(object)((Renderer)component).sharedMaterial != (Object)null) ? ((Object)((Renderer)component).sharedMaterial.shader).name : "keiner") + ".")); } private static Material Cloth() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00ed: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) Material val = Base(); Material val2; if ((Object)(object)val != (Object)null) { val2 = new Material(val); Plugin.Log.LogInfo((object)("[FinalAscent] Sporenwerk: Werkstoff '" + ((Object)val).name + "' als Grundlage kopiert (Regelwerk '" + ((Object)val.shader).name + "').")); } else { Shader val3 = Shader.Find("SmokeParticleSimple") ?? Found(); if ((Object)(object)val3 == (Object)null) { Plugin.Log.LogWarning((object)"[FinalAscent] Sporenwerk: weder Grundlage noch Regelwerk 'SmokeParticleSimple' gefunden - die Wolke bleibt unsichtbar."); return null; } val2 = new Material(val3); val2.EnableKeyword("_FLIP_ON"); Plugin.Log.LogWarning((object)"[FinalAscent] Sporenwerk: keine Grundlage im Bestand - Werkstoff von null gebaut, das kann anders aussehen."); } ((Object)val2).hideFlags = (HideFlags)61; Texture val4 = FinalAscentLarder.Picture("A_Texture 60"); if ((Object)(object)val4 != (Object)null) { val2.SetTexture("_Textureu", val4); } val2.SetColor("_AlphaRemap", new Color(0.4596f, 0.82f, 0f, 0f)); val2.SetColor("_Color2", new Color(0.0723f, 0.1211f, 0.5283f, 0f)); val2.SetColor("_Color2Remap", new Color(0.1041f, 0.3018f, 0f, 0f)); val2.SetColor("_Color3", new Color(1f, 0f, 0.1648f, 0.502f)); val2.SetColor("_Color3Remap", new Color(0.2475f, 0.6439f, 0f, 0f)); val2.SetColor("_FinalAlphaRemap", new Color(0f, 0.6706f, 0f, 0f)); val2.SetColor("_DistortionScroll", new Color(0f, -0.01f, 0f, 0f)); val2.SetColor("_TexScroll", new Color(0f, 0.001f, 0f, 0f)); val2.SetColor("_Tint", new Color(1f, 1f, 1f, 0f)); val2.SetFloat("_Alpha", 1f); val2.SetFloat("_Distortion", 0.02f); val2.SetFloat("_DistortionScale", 15f); val2.SetFloat("_Roundness", 1.76f); val2.SetFloat("_RoundnessExp", 8f); val2.SetFloat("_ShadowStr", 0.48f); val2.SetFloat("_SkyBrightnessValue", 0.97f); val2.SetFloat("_SunContribute", 0.66f); val2.SetFloat("_SunGlowLighting", 1f); val2.SetFloat("_TextureInfluence", 0.27f); val2.SetFloat("_TextureRotateSpeed", 0.1f); val2.SetFloat("_Opacity", 0.85f); return val2; } private static Material Base() { for (int i = 0; i < Bases.Length; i++) { Material val = FinalAscentLarder.ByName(Bases[i]); if ((Object)(object)val != (Object)null && (Object)(object)val.shader != (Object)null) { return val; } } return FinalAscentLarder.ByShader("SmokeParticleSimple"); } private static Shader Found() { Shader[] array = Resources.FindObjectsOfTypeAll(); foreach (Shader val in array) { if ((Object)(object)val != (Object)null && ((Object)val).name == "SmokeParticleSimple") { return val; } } return null; } private static Gradient Fade() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_000f: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_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_0061: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) Gradient val = new Gradient(); val.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(Color.white, 0f), new GradientColorKey(Color.white, 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[3] { new GradientAlphaKey(0f, 0f), new GradientAlphaKey(1f, 0.485f), new GradientAlphaKey(0f, 1f) }); return val; } } internal static class FinalAscentSpot { private const float FromAbove = 40f; private const float Clearance = 0.5f; internal static bool OnGround(Vector3 hub, float nearest, float furthest, int tries, out Vector3 where) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Toward(hub, Vector3.zero, 180f, nearest, furthest, tries, out where); } internal static bool Toward(Vector3 hub, Vector3 heading, float arc, float nearest, float furthest, int tries, out Vector3 where) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(heading.x, 0f, heading.z); bool flag = ((Vector3)(ref val)).sqrMagnitude > 0.01f; if (flag) { ((Vector3)(ref val)).Normalize(); } float num = (flag ? Mathf.Atan2(val.z, val.x) : 0f); float num2 = Mathf.Clamp(arc, 1f, 180f) * (MathF.PI / 180f); for (int i = 0; i < tries; i++) { float num3 = (flag ? (num + Random.Range(0f - num2, num2)) : (Random.value * MathF.PI * 2f)); float num4 = Random.Range(nearest, furthest); RaycastHit groundPosRaycast = HelperFunctions.GetGroundPosRaycast(hub + new Vector3(Mathf.Cos(num3), 0f, Mathf.Sin(num3)) * num4 + Vector3.up * 40f, (LayerType)1, 0f); if ((Object)(object)((RaycastHit)(ref groundPosRaycast)).transform != (Object)null) { where = ((RaycastHit)(ref groundPosRaycast)).point + Vector3.up * 0.5f; return true; } } where = hub; return false; } } internal static class FinalAscentStartWatch { internal const string Tag = "[FinalAscent]"; internal static float Handed = -1f; internal static IEnumerator LookAgain(Character who) { yield return (object)new WaitForSecondsRealtime(6f); if (!((Object)(object)who == (Object)null) && who.refs != null && !((Object)(object)who.refs.afflictions == (Object)null)) { float currentStatus = who.refs.afflictions.GetCurrentStatus((STATUSTYPE)5); if (Handed > 0f && currentStatus <= 0f) { Plugin.Log.LogWarning((object)(string.Format("{0} STARTFLUCH IST WEG: beim Aufwachen wurden {1:F2} ", "[FinalAscent]", Handed) + "vergeben, sechs Sekunden spaeter steht der Fluch auf 0. Jemand hat Zustaende abgeraeumt - siehe die Abraeum-Meldung darueber.")); } else { Plugin.Log.LogInfo((object)(string.Format("{0} Startfluch nach sechs Sekunden: {1:F2} ", "[FinalAscent]", currentStatus) + "(beim Aufwachen vergeben: " + ((Handed < 0f) ? "gar nicht" : Handed.ToString("F2")) + ").")); } } } } [HarmonyPatch(typeof(Character), "StartPassedOutOnTheBeach")] internal static class FinalAscentWakeupWatch { private static void Postfix(Character __instance) { try { float num = (FinalAscentStartWatch.Handed = Ascents.startingCurse); float num2 = (((Object)(object)__instance != (Object)null && __instance.refs != null && (Object)(object)__instance.refs.afflictions != (Object)null) ? __instance.refs.afflictions.GetCurrentStatus((STATUSTYPE)5) : (-1f)); Plugin.Log.LogInfo((object)("[FinalAscent] Strand-Aufwachen gelaufen: Ascent " + $"{Ascents.currentAscent}, Startfluch laut Regel {num:F2}, " + $"Fluch am Koerper danach {num2:F2}.")); if ((Object)(object)Plugin.Instance != (Object)null && (Object)(object)__instance != (Object)null && __instance.IsLocal) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(FinalAscentStartWatch.LookAgain(__instance)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Aufwach-Sonde: " + ex.Message)); } } } [HarmonyPatch(typeof(SpawnPoint), "GetSpawnPoint")] internal static class FinalAscentSpawnFlavourWatch { private static void Postfix(SpawnPoint __result) { if (FinalAscent.Active && !((Object)(object)__result == (Object)null) && !__result.startPassedOut) { Plugin.Log.LogWarning((object)("[FinalAscent] Spawnpunkt '" + ((Object)__result).name + "' sagt NICHT 'passed out'. Damit spawnt man stehend statt am Strand aufzuwachen - und die Aufwachszene ist die einzige Stelle, die den Startfluch vergibt. Das waere die Ursache.")); } } } [HarmonyPatch(typeof(CharacterSpawner), "SpawnMyPlayerCharacter")] internal static class FinalAscentCurseRepair { private static void Postfix(SpawnFlavor spawnFlavor, Character __result) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) try { if (!FinalAscent.Active || (Object)(object)__result == (Object)null || (int)spawnFlavor == 1) { return; } if (FinalAscentRoom.JoinedLate || FinalAscentRoom.Stage > 0) { Plugin.Detail(string.Format("{0} Spawn als {1} - kein ", "[FinalAscent]", spawnFlavor) + "frischer Start, also auch kein Startfluch."); return; } float startingCurse = Ascents.startingCurse; if (startingCurse <= 0f || __result.refs == null || (Object)(object)__result.refs.afflictions == (Object)null) { return; } float currentStatus = __result.refs.afflictions.GetCurrentStatus((STATUSTYPE)5); if (!(currentStatus >= startingCurse)) { __result.refs.afflictions.AddStatus((STATUSTYPE)5, startingCurse - currentStatus, false, true, true, false); FinalAscentStartWatch.Handed = startingCurse; Plugin.Log.LogWarning((object)("[FinalAscent] STARTFLUCH NACHGEHOLT: die Spawn-Art " + $"war '{spawnFlavor}', also lief die Strand-Aufwachszene nicht - und " + "nur sie vergibt den Fluch. Frischer Start bei Ascent " + $"{Ascents.currentAscent}, deshalb {startingCurse:F2} gesetzt (vorher " + $"{currentStatus:F2}). Die Zeile darueber nennt den Spawnpunkt, an dem es liegt.")); if ((Object)(object)Plugin.Instance != (Object)null && __result.IsLocal) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(FinalAscentStartWatch.LookAgain(__result)); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Startfluch-Nachholung: " + ex.Message)); } } } [HarmonyPatch(typeof(CharacterAfflictions), "ClearAllStatus")] internal static class FinalAscentClearWatch { private static void Prefix(CharacterAfflictions __instance, bool excludeCurse) { if (!(!FinalAscent.Active || excludeCurse) && !((Object)(object)__instance == (Object)null)) { float currentStatus = __instance.GetCurrentStatus((STATUSTYPE)5); if (!(currentStatus <= 0f)) { Plugin.Log.LogWarning((object)("[FinalAscent] ABRAEUMUNG loescht einen Fluch von " + $"{currentStatus:F2}, ausgeloest von {Caller()}.")); } } } private static string Caller() { try { StackTrace stackTrace = new StackTrace(2, fNeedFileInfo: false); for (int i = 0; i < stackTrace.FrameCount && i < 10; i++) { MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod(); Type type = methodBase?.DeclaringType; if (!(type == null)) { string text = type.Namespace ?? ""; if (!text.StartsWith("HarmonyLib", StringComparison.Ordinal) && !text.StartsWith("MonoMod", StringComparison.Ordinal) && !(type == typeof(CharacterAfflictions)) && !type.Name.StartsWith("FinalAscentClearWatch", StringComparison.Ordinal)) { return type.Name + "." + methodBase.Name; } } } } catch { } return "unbekannt"; } } [HarmonyPatch] internal static class FinalAscentStepHeartbeatPatch { private static IEnumerable TargetMethods() { List list = new List(); Type[] types; try { types = typeof(LevelGenStep).Assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { types = ex.Types; } Type[] array = types; foreach (Type type in array) { if (!(type == null) && !type.IsAbstract && typeof(LevelGenStep).IsAssignableFrom(type)) { MethodInfo methodInfo = AccessTools.DeclaredMethod(type, "ExecuteImmediately", (Type[])null, (Type[])null); if (methodInfo != null && !methodInfo.IsAbstract) { list.Add(methodInfo); } } } Plugin.Log.LogInfo((object)($"[FinalAscent] Herzschlag an {list.Count} Bauarten von Generierungsschritten " + "angesetzt.")); return list; } private static void Prefix(out Stopwatch __state) { FinalAscentKeepAlive.Tick(); __state = (FinalAscentLoadProbe.Running ? Stopwatch.StartNew() : null); } private static void Postfix(LevelGenStep __instance, Stopwatch __state) { if (__state != null) { FinalAscentLoadProbe.Piece(((Object)(object)__instance != (Object)null) ? ("Sofortschritt " + ((Object)__instance).name) : "Sofortschritt", __state.Elapsed.TotalMilliseconds); } } } internal static class FinalAscentStepPrint { private const string Tag = "[FinalAscent]"; private const int NamedAtMost = 25; private static readonly SortedDictionary _now = new SortedDictionary(StringComparer.Ordinal); private static readonly Dictionary _seq = new Dictionary(StringComparer.Ordinal); private static int _at; private static string _key; private static string _loupe; private static readonly List _trace = new List(50000); private static readonly List _boundaries = new List(); private static string _loupeNext; internal static SortedDictionary Fingerprints => _now; private static string TracePath => FinalAscentStore.Note("TrueFinalAscent.Props.txt"); private static string FilePath => FinalAscentStore.Note("TrueFinalAscent.Schritte.txt"); internal static void Boundary(int propsSoFar) { if (_boundaries.Count < 200) { _boundaries.Add(propsSoFar); } } internal static void Begin(string key) { _now.Clear(); _seq.Clear(); _at = 0; _key = key; _loupe = ReadLoupe(); _loupeNext = null; _trace.Clear(); _trace.Add("# " + key); _boundaries.Clear(); if (_loupe != null) { Plugin.Log.LogInfo((object)("[FinalAscent] Unter der Lupe: '" + _loupe + "' - dort ging es im vorigen Lauf zuerst auseinander. Jedes Prop dieses Schritts wird einzeln mitgeschrieben.")); } } internal static void Note(Component owner, string suffix = null) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)owner == (Object)null || _key == null) { return; } try { Transform transform = owner.transform; long num = 0L; long num2 = 0L; int childCount = transform.childCount; Dictionary data = SpawnDataOf(owner); _trace.Add("@" + PathOf(transform) + (suffix ?? string.Empty)); _trace.Add("!bilder nach Prop " + string.Join(",", _boundaries)); _boundaries.Clear(); string text = FinalAscentSpawnAudit.Summary(); if (text != null) { _trace.Add("!werk " + text); } int num3 = 0; int num4 = 0; for (int i = 0; i < childCount; i++) { Transform child = transform.GetChild(i); if (((Object)child).name.StartsWith("MushroomZombieSpawner")) { num4++; continue; } Vector3 val = transform.InverseTransformPoint(child.position); Trace(num3, child, val, data); num3++; num += Mix(Mathf.RoundToInt(val.x * 100f), Mathf.RoundToInt(val.y * 100f), Mathf.RoundToInt(val.z * 100f)); num2 += Mix(Mathf.RoundToInt(val.x), Mathf.RoundToInt(val.y), Mathf.RoundToInt(val.z)); } if (num4 > 0) { _trace.Add("!lebend " + num4 + " Marker nicht gezaehlt (MushroomZombieSpawner)"); } string text2 = PathOf(transform) + (suffix ?? string.Empty); _now[text2] = $"{num3}/{num & 0xFFFFFF:X6}/{num2 & 0xFFFFFF:X6}"; if (!_seq.ContainsKey(text2)) { _seq[text2] = _at++; } if (_loupe != null && text2 == _loupe) { Loupe(owner, transform); } } catch (Exception ex) { Plugin.Detail("[FinalAscent] Abdruck von '" + ((Object)owner).name + "' nicht moeglich: " + ex.Message); } } private static void Trace(int index, Transform kid, Vector3 at, Dictionary data) { //IL_00e2: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) string text = "-;-"; string text2 = "-;-"; if (data != null && data.TryGetValue(((Component)kid).gameObject, out var value) && value != null) { text = $"{value.placement.x:F6};{value.placement.y:F6}"; text2 = Whom(((RaycastHit)(ref value.hit)).collider) + ";" + $"{((RaycastHit)(ref value.hit)).point.x:F2}|{((RaycastHit)(ref value.hit)).point.y:F2}|{((RaycastHit)(ref value.hit)).point.z:F2}"; } _trace.Add($"{index};{((Object)kid).name};{text};{at.x:F2}|{at.y:F2}|{at.z:F2};{text2}"); } private static string Whom(Collider hit) { if ((Object)(object)hit == (Object)null) { return "-"; } Transform transform = ((Component)hit).transform; string text = (((Object)(object)transform.parent != (Object)null) ? (((Object)transform.parent).name + "/" + ((Object)transform).name) : ((Object)transform).name); Biome componentInParent = ((Component)hit).GetComponentInParent(true); return (((Object)(object)componentInParent != (Object)null) ? ((object)Unsafe.As(ref componentInParent.biomeType)/*cast due to .constrained prefix*/).ToString() : "?") + "|" + text; } private static Dictionary SpawnDataOf(Component owner) { PropSpawner val = (PropSpawner)(object)((owner is PropSpawner) ? owner : null); if (val == null) { return null; } try { object obj = AccessTools.Field(typeof(PropSpawner), "_propSpawnData")?.GetValue(val); return AccessTools.Property(obj?.GetType(), "Dict")?.GetValue(obj) as Dictionary; } catch { return null; } } private static void CompareTrace() { List list = null; try { if (File.Exists(TracePath)) { list = new List(File.ReadAllLines(TracePath)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Spur des vorigen Laufs unlesbar: " + ex.Message)); } try { if (!Plugin.Diagnosing) { return; } if (File.Exists(TracePath)) { File.Copy(TracePath, Path.ChangeExtension(TracePath, null) + ".vorher.txt", overwrite: true); } File.WriteAllLines(TracePath, _trace); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[FinalAscent] Spur nicht abgelegt: " + ex2.Message)); } if (list == null || list.Count == 0) { Plugin.Log.LogInfo((object)(string.Format("{0} Spur ueber {1} Zeilen abgelegt. Beim naechsten Lauf ", "[FinalAscent]", _trace.Count) + "steht hier die erste Zeile, in der es auseinandergeht.")); return; } if (list.Count > 0 && _trace.Count > 0 && list[0] != _trace[0]) { Plugin.Log.LogInfo((object)"[FinalAscent] Spur abgelegt - der vorige Lauf hatte andere Einstellungen."); return; } int num = Math.Min(list.Count, _trace.Count); string text = "(noch kein Schritt)"; for (int i = 0; i < num; i++) { if (_trace[i].Length > 0 && _trace[i][0] == '@') { text = _trace[i].Substring(1); } if (!(list[i] == _trace[i])) { Plugin.Log.LogWarning((object)(string.Format("{0} ERSTE ABWEICHUNG in der Spur, Zeile {1} von {2}, ", "[FinalAscent]", i + 1, _trace.Count) + "im Schritt '" + text + "':")); Plugin.Log.LogWarning((object)("[FinalAscent] war " + list[i])); Plugin.Log.LogWarning((object)("[FinalAscent] jetzt " + _trace[i])); Plugin.Log.LogWarning((object)"[FinalAscent] Format: Nr;Prop;Wuerfel x;Wuerfel y;Ort x|y|z;Getroffen;Trefferpunkt x|y|z"); for (int j = Math.Max(0, i - 4); j < i; j++) { Plugin.Log.LogWarning((object)("[FinalAscent] davor " + _trace[j])); } return; } } if (list.Count != _trace.Count) { Plugin.Log.LogWarning((object)(string.Format("{0} Die Spur ist bis Zeile {1} gleich und danach ", "[FinalAscent]", num) + $"verschieden lang ({list.Count} gegen {_trace.Count}).")); } else { Plugin.Log.LogInfo((object)(string.Format("{0} SPUR-TREUE: alle {1} Zeilen gleich - jedes Prop sitzt ", "[FinalAscent]", _trace.Count) + "wie im vorigen Lauf, mit demselben Wuerfelwurf und demselben Treffer.")); } } private static long Mix(int x, int y, int z) { return (((((0x14650FB0739D0383L ^ x) * 1099511628211L) ^ y) * 1099511628211L) ^ z) * 1099511628211L; } private static string PathOf(Transform leaf) { StringBuilder stringBuilder = new StringBuilder(((Object)leaf).name); Transform parent = leaf.parent; while ((Object)(object)parent != (Object)null) { stringBuilder.Insert(0, '/').Insert(0, ((Object)parent).name); parent = parent.parent; } return stringBuilder.ToString(); } internal static void Finish() { if (_key == null) { return; } CompareTrace(); Dictionary dictionary = new Dictionary(StringComparer.Ordinal); string text = null; try { if (File.Exists(FilePath)) { string[] array = File.ReadAllLines(FilePath); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length == 0 || text2.StartsWith("#")) { continue; } if (text == null) { text = text2; continue; } int num = text2.IndexOf('='); if (num > 0) { dictionary[text2.Substring(0, num)] = text2.Substring(num + 1); } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Schritt-Abdruck des vorigen Laufs unlesbar: " + ex.Message)); } if (text == null) { Save(); Plugin.Log.LogInfo((object)(string.Format("{0} Schritt-Abdruck von {1} Schritten abgelegt. Beim naechsten ", "[FinalAscent]", _now.Count) + "Lauf mit denselben Einstellungen steht hier, welche Schritte abweichen.")); return; } if (text != _key) { Save(); Plugin.Log.LogInfo((object)(string.Format("{0} Schritt-Abdruck von {1} Schritten abgelegt - der vorige Lauf ", "[FinalAscent]", _now.Count) + "hatte andere Einstellungen, deshalb kein Vergleich.")); return; } List list = new List(); List list2 = new List(); List list3 = new List(); List list4 = new List(); int num2 = 0; foreach (KeyValuePair item2 in _now) { if (!dictionary.TryGetValue(item2.Key, out var value)) { list4.Add(item2.Key); continue; } if (value == item2.Value) { num2++; continue; } string[] array2 = item2.Value.Split('/'); string[] array3 = value.Split('/'); string item = item2.Key + ": war " + value + ", jetzt " + item2.Value; if (array2.Length != 3 || array3.Length != 3) { list.Add(item); } else if (array2[0] != array3[0]) { list3.Add(item); } else if (array2[2] != array3[2]) { list.Add(item); } else { list2.Add(item); } } List list5 = new List(); foreach (KeyValuePair item3 in dictionary) { if (!_now.ContainsKey(item3.Key)) { list5.Add(item3.Key); } } int num3 = list3.Count + list.Count + list2.Count + list4.Count + list5.Count; if (num3 == 0) { Save(); Plugin.Log.LogInfo((object)string.Format("{0} SCHRITT-TREUE: alle {1} Schritte haben gesetzt wie im vorigen Lauf.", "[FinalAscent]", num2)); return; } Plugin.Log.LogWarning((object)(string.Format("{0} SCHRITT-TREUE VERLETZT: {1} von {2} Schritten gleich. ", "[FinalAscent]", num2, num2 + num3) + $"Andere Anzahl: {list3.Count}. Props verschoben (Meter): {list.Count}. " + $"Nur Zentimeter-Zittern: {list2.Count}. Neu: {list4.Count}. " + $"Weg: {list5.Count}. Format Anzahl/fein/grob.")); List list6 = new List(list3); list6.AddRange(list); ByRun(list6); if (list6.Count > 0) { Plugin.Log.LogWarning((object)(string.Format("{0} ZUERST abgewichen ist Schritt {1} von ", "[FinalAscent]", Rank(list6[0]) + 1) + $"{_now.Count}: {list6[0]}")); Plugin.Log.LogWarning((object)"[FinalAscent] Alles danach kann Folge sein - hier anfangen zu suchen."); int num4 = list6[0].IndexOf(": war", StringComparison.Ordinal); _loupeNext = ((num4 > 0) ? list6[0].Substring(0, num4) : null); } Save(); Name("Andere Anzahl gesetzt", list3); Name("Props stehen woanders (auch auf den Meter)", list); Name("Nur Zentimeter-Zittern - im Spiel nicht zu sehen", list2); Name("Diesmal ueberhaupt gelaufen", list4); Name("Diesmal nicht gelaufen", list5); SortedDictionary sortedDictionary = new SortedDictionary(StringComparer.Ordinal); foreach (string item4 in list3) { Bump(sortedDictionary, Section(item4)); } foreach (string item5 in list) { Bump(sortedDictionary, Section(item5)); } if (sortedDictionary.Count <= 0) { return; } List list7 = new List(); foreach (KeyValuePair item6 in sortedDictionary) { list7.Add($"{item6.Key}: {item6.Value}"); } Plugin.Log.LogWarning((object)("[FinalAscent] Echte Abweichungen je Abschnitt - " + string.Join(", ", list7) + ".")); } private static void Bump(SortedDictionary into, string key) { into.TryGetValue(key, out var value); into[key] = value + 1; } private static void Name(string what, List lines) { if (lines.Count != 0) { Plugin.Log.LogWarning((object)string.Format("{0} {1} ({2}):", "[FinalAscent]", what, lines.Count)); ByRun(lines); for (int i = 0; i < lines.Count && i < 25; i++) { Plugin.Log.LogWarning((object)("[FinalAscent] " + lines[i])); } if (lines.Count > 25) { Plugin.Log.LogWarning((object)(string.Format("{0} ... und {1} weitere ", "[FinalAscent]", lines.Count - 25) + "(vollstaendig in TrueFinalAscent.Schritte.txt).")); } } } private static string Section(string line) { int num = line.IndexOf(": war", StringComparison.Ordinal); string[] array = ((num > 0) ? line.Substring(0, num) : line).Split('/'); if (array.Length < 3) { return "?"; } return array[2]; } private static void ByRun(List lines) { lines.Sort(delegate(string a, string b) { int num = Rank(a).CompareTo(Rank(b)); return (num == 0) ? StringComparer.Ordinal.Compare(a, b) : num; }); } private static int Rank(string line) { int num = line.IndexOf(": war", StringComparison.Ordinal); string key = ((num > 0) ? line.Substring(0, num) : line); if (!_seq.TryGetValue(key, out var value)) { return int.MaxValue; } return value; } private static void Loupe(Component owner, Transform root) { //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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = SpawnDataOf(owner); Plugin.Log.LogWarning((object)(string.Format("{0} LUPE '{1}': {2} Props", "[FinalAscent]", ((Object)root).name, root.childCount) + ((dictionary != null) ? $", {dictionary.Count} Spawndaten." : ", ohne Spawndaten."))); for (int i = 0; i < root.childCount && i < 60; i++) { Transform child = root.GetChild(i); Vector3 val = root.InverseTransformPoint(child.position); string text = $"#{i:D3} {((Object)child).name} bei ({val.x:F2} / {val.y:F2} / {val.z:F2})"; if (dictionary != null && dictionary.TryGetValue(((Component)child).gameObject, out var value) && value != null) { text = text + $" wuerfel=({value.placement.x:F6}|{value.placement.y:F6})" + $" strahl=({value.rayDir.x:F3}|{value.rayDir.y:F3}|{value.rayDir.z:F3})" + " traf '" + Whom(((RaycastHit)(ref value.hit)).collider) + "'" + $" bei ({((RaycastHit)(ref value.hit)).point.x:F2}|{((RaycastHit)(ref value.hit)).point.y:F2}|{((RaycastHit)(ref value.hit)).point.z:F2})" + $" dreieck={((RaycastHit)(ref value.hit)).triangleIndex}"; } Plugin.Log.LogWarning((object)("[FinalAscent] " + text)); } if (root.childCount > 60) { Plugin.Log.LogWarning((object)string.Format("{0} ... {1} weitere Props nicht aufgefuehrt.", "[FinalAscent]", root.childCount - 60)); } } private static string ReadLoupe() { try { if (!File.Exists(FilePath)) { return null; } string[] array = File.ReadAllLines(FilePath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.StartsWith("# lupe=", StringComparison.Ordinal)) { string text2 = text.Substring("# lupe=".Length).Trim(); return (text2.Length > 0) ? text2 : null; } if (text.Length > 0 && !text.StartsWith("#", StringComparison.Ordinal)) { return null; } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Lupenziel nicht lesbar: " + ex.Message)); } return null; } private static void Save() { try { if (File.Exists(FilePath)) { File.Copy(FilePath, Path.ChangeExtension(FilePath, null) + ".vorher.txt", overwrite: true); } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# Abdruck je Generierungsschritt des letzten Final Ascent."); stringBuilder.AppendLine("# Erste Zeile: die Einstellungen. Danach je Schritt:"); stringBuilder.AppendLine("# Pfad=Anzahl/Pruefsumme fein (cm)/Pruefsumme grob (m)"); stringBuilder.AppendLine("# Zwei Laeufe mit gleichem Seed muessen Zeile fuer Zeile gleich sein."); string text = _loupeNext ?? _loupe; if (!string.IsNullOrEmpty(text)) { stringBuilder.AppendLine("# lupe=" + text); } stringBuilder.AppendLine(_key); foreach (KeyValuePair item in _now) { stringBuilder.AppendLine(item.Key + "=" + item.Value); } if (Plugin.Diagnosing) { File.WriteAllText(FilePath, stringBuilder.ToString()); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Schritt-Abdruck nicht abgelegt: " + ex.Message)); } } } internal static class FinalAscentStore { private const string Tag = "[FinalAscent]"; private static string _folder; private static string _notes; internal static string Folder { get { if (_folder != null) { return _folder; } try { string text = Under("LandCrab"); if (text != null) { Directory.CreateDirectory(text); _folder = text; return _folder; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Eigener Ordner in AppData nicht anlegbar (" + ex.Message + ") - es wird auf BepInEx/config ausgewichen.")); } _folder = Paths.ConfigPath; return _folder; } } internal static string Notes { get { if (_notes != null) { return _notes; } try { string text = Path.Combine(Folder, "Diagnose"); Directory.CreateDirectory(text); _notes = text; } catch (Exception) { _notes = Folder; } return _notes; } } internal static string State(string name) { return Path.Combine(Folder, name); } internal static string Note(string name) { return Path.Combine(Notes, name); } private static string Under(string vendor) { string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); if (!string.IsNullOrEmpty(folderPath)) { return Path.Combine(folderPath, vendor, "PEAK", "TrueFinalAscent"); } return null; } private static IEnumerable Elsewhere() { string text; try { text = Under("CptPICHU"); } catch (Exception) { text = null; } if (text != null && !Same(text, Folder)) { yield return text; } if (!Same(Paths.ConfigPath, Folder)) { yield return Paths.ConfigPath; } } private static bool Same(string one, string other) { return string.Equals((one ?? "").TrimEnd('\\', '/'), (other ?? "").TrimEnd('\\', '/'), StringComparison.OrdinalIgnoreCase); } internal static string ReadPath(string name, params string[] older) { string text = State(name); try { if (File.Exists(text)) { return text; } foreach (string item in Elsewhere()) { foreach (string item2 in Names(name, older)) { string text2 = Path.Combine(item, item2); if (File.Exists(text2)) { return text2; } } } } catch (Exception) { } return text; } internal static void Retire(string name, params string[] older) { try { if (!File.Exists(State(name))) { return; } int num = 0; foreach (string item in Elsewhere()) { foreach (string item2 in Names(name, older)) { string path = Path.Combine(item, item2); if (File.Exists(path)) { File.Delete(path); num++; } } } if (num > 0) { Plugin.Log.LogInfo((object)("[FinalAscent] " + name + " liegt jetzt in " + Folder + " und ist damit vor " + $"geteilten Profilcodes sicher. {num} alte Kopie(n) entfernt.")); } } catch (Exception ex) { Plugin.Detail("[FinalAscent] Alte Kopie von " + name + " blieb liegen: " + ex.Message); } } private static IEnumerable Names(string name, string[] older) { yield return name; if (older != null) { for (int i = 0; i < older.Length; i++) { yield return older[i]; } } } } internal static class FinalAscentStuckWatch { private const string Tag = "[FinalAscent]"; private static bool _running; internal static void Begin() { if (!_running && !((Object)(object)Plugin.Instance == (Object)null)) { _running = true; ((MonoBehaviour)Plugin.Instance).StartCoroutine(Watch()); } } private static IEnumerator Watch() { float since = Time.realtimeSinceStartup; float lostAt = -1f; while (Time.realtimeSinceStartup - since < 120f) { yield return (object)new WaitForSecondsRealtime(5f); if ((Object)(object)Character.localCharacter != (Object)null) { Plugin.Log.LogInfo((object)(string.Format("{0} Figur ist da nach {1:F0}s - ", "[FinalAscent]", Time.realtimeSinceStartup - since) + "der Waechter hoert auf.")); _running = false; yield break; } Plugin.Log.LogInfo((object)string.Format("{0} Warte seit {1:F0}s: {2}", "[FinalAscent]", Time.realtimeSinceStartup - since, State())); if (!PhotonNetwork.OfflineMode && !PhotonNetwork.IsConnected) { if (lostAt < 0f) { lostAt = Time.realtimeSinceStartup; } if (Time.realtimeSinceStartup - lostAt >= 12f) { Plugin.Log.LogError((object)(string.Format("{0} Verbindung ist weg ({1}) ", "[FinalAscent]", PhotonNetwork.NetworkClientState) + "und kommt nicht wieder - zurueck zum Titelbildschirm, wie es Vanillas Trennungs-Fenster getan haette.")); _running = false; SceneManager.LoadScene("Title"); yield break; } } else { lostAt = -1f; } } Plugin.Log.LogWarning((object)("[FinalAscent] Nach zwei Minuten ist immer noch keine Figur da. Letzter Stand: " + State())); _running = false; } private static string State() { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("Berg fertig=").Append(FinalAscentBuilder.Done); stringBuilder.Append(", wird erwartet=").Append(FinalAscentBuilder.Awaited); stringBuilder.Append(", Spawnruf gehalten=").Append(FinalAscentSpawnGate.Holding); stringBuilder.Append(", Figur=").Append(((Object)(object)Character.localCharacter != (Object)null) ? "da" : "keine"); if (PhotonNetwork.InRoom) { stringBuilder.Append(", im Raum=ja (").Append(PhotonNetwork.CurrentRoom.PlayerCount).Append(" Spieler, Master=") .Append(PhotonNetwork.IsMasterClient ? "ich" : "anderer") .Append(')'); } else { stringBuilder.Append(", im Raum=NEIN (Zustand ").Append(PhotonNetwork.NetworkClientState).Append(')'); } CharacterSpawner val = Object.FindFirstObjectByType(); stringBuilder.Append(", Spawner=").Append(((Object)(object)val != (Object)null) ? "vorhanden" : "FEHLT"); int num = 0; int num2 = 0; Character[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Character val2 in array) { if (!((Object)(object)val2 == (Object)null)) { PhotonView component = ((Component)val2).GetComponent(); if ((Object)(object)component != (Object)null && component.Owner != null && component.Owner.ActorNumber == PhotonNetwork.LocalPlayer.ActorNumber) { num++; } else { num2++; } } } stringBuilder.Append(", Figuren=").Append(num).Append(" eigen / ") .Append(num2) .Append(" fremd"); stringBuilder.Append(", Spawnpunkte=").Append((SpawnPoint.allSpawnPoints != null) ? SpawnPoint.allSpawnPoints.Count : 0); LoadingScreenHandler val3 = Object.FindFirstObjectByType(); stringBuilder.Append(", Ladebildschirm=").Append(((Object)(object)val3 == (Object)null) ? "keiner" : (((Component)val3).gameObject.activeInHierarchy ? "sichtbar" : "aus")); return stringBuilder.ToString(); } } internal static class FinalAscentText { private const string Tag = "[FinalAscent]"; private const string FileName = "TrueFinalAscent.Texts.cfg"; private static readonly Dictionary BuiltInEn = new Dictionary { { "mode.title", "FINAL ASCENT" }, { "mode.desc", "The final challenge. ALL the biomes in ONE run." }, { "window.title", "FINAL ASCENT" }, { "seed.label", "SEED" }, { "seed.random", "Random" }, { "variants.random", "Random biome variants" }, { "variants.heading", "BIOME VARIANTS" }, { "apo.label", "Apocalypse Mode" }, { "apo.note", "Random weather events. Beware!" }, { "weather.title", "APOCALYPSE - WEATHER" }, { "weather.vanilla", "FROM THE GAME" }, { "weather.custom", "OUR OWN" }, { "weather.none", "nothing here yet" }, { "weather.running", "Running:" }, { "weather.idle", "Nothing running. Click an entry to start it, click it again to stop." }, { "weather.rain", "Rain" }, { "weather.from", "Wind from" }, { "weather.left", "the left" }, { "weather.right", "the right" }, { "weather.snow", "Blizzard" }, { "weather.sand", "Sandstorm" }, { "weather.petrify", "Petrifying Sun" }, { "weather.moon", "Blue Moon" }, { "weather.blood", "Blood Moon" }, { "weather.sleepfog", "Sleeping Fog" }, { "weather.quake", "Earthquake" }, { "weather.dark", "Darkness" }, { "weather.spores", "Spore Cloud" }, { "dark.torch", "Flashlight" }, { "weather.wind", "Windstorm" }, { "weather.storm", "Windstorm" }, { "weather.sun", "Burning Sun" }, { "weather.on", "ON" }, { "weather.strength", "MAXIMUM INTENSITY" }, { "weather.pushonly", "(push only)" }, { "weather.off", "OFF" }, { "weather.bare", "(no gear on this map - effect only)" }, { "variants.none", "no variants" }, { "pick.random", "Random" }, { "ascent.title", "Difficulty" }, { "ascent.tenderfoot", "Tenderfoot" }, { "ascent.peak", "PEAK" }, { "ascent.n", "Ascent" }, { "name.auto", "Automatic" }, { "name.plain", "White" }, { "name.silver", "Silver" }, { "name.gold", "Gold" }, { "name.diamond", "Diamond" }, { "name.rainbow", "Rainbow" }, { "ascent.nadir", "(Nadir only)" }, { "button.start", "START" }, { "button.cancel", "CANCEL" }, { "warning.load", "WARNING: Loading takes significantly longer when starting Final Ascent!" }, { "join.late", "JOINED A FINAL ASCENT IN PROGRESS" }, { "join.building", "The whole mountain has to be rebuilt before you can drop in - that is why this took a while." }, { "biome.Shore", "Shore" }, { "biome.Tropics", "Tropics" }, { "biome.Roots", "Roots" }, { "biome.Alpine", "Alpine" }, { "biome.Mesa", "Mesa" }, { "biome.Volcano", "Caldera" }, { "biome.Swamp", "Gloom" }, { "biome.Caldera", "Caldera" }, { "biome.Gloom", "Gloom" }, { "biome.Temple", "Citadel" }, { "load.prepare", "Preparing the mountain" }, { "load.build", "Building the mountain" }, { "load.gen", "Growing the landscapes" }, { "load.measure", "Measuring the mountain" }, { "load.light", "Working out the light" }, { "load.cpulight", "CPU light calculations" }, { "load.wire", "Connecting the paths" }, { "load.done", "Done" }, { "load.wait", "Waiting for the island" }, { "load.download", "Downloading the island" }, { "load.unpack", "Unpacking the map" } }; private static readonly Dictionary BuiltInDe = new Dictionary { { "mode.title", "FINALER AUFSTIEG" }, { "mode.desc", "Die Finale Herausforderung. ALLE Biome in EINEM Lauf." }, { "window.title", "FINALER AUFSTIEG" }, { "seed.label", "SEED" }, { "seed.random", "Zufällig" }, { "variants.random", "Zufällige Biom-Varianten" }, { "variants.heading", "BIOM-VARIANTEN" }, { "apo.label", "Apokalypse-Modus" }, { "apo.note", "Zufällige Wetterevents. Vorsicht!" }, { "weather.title", "APOKALYPSE - WETTER" }, { "weather.vanilla", "AUS DEM SPIEL" }, { "weather.custom", "EIGENE" }, { "weather.none", "hier steht noch nichts" }, { "weather.running", "Läuft:" }, { "weather.idle", "Nichts aktiv. Klick startet, noch ein Klick beendet." }, { "weather.rain", "Regen" }, { "weather.from", "Wind von" }, { "weather.left", "links" }, { "weather.right", "rechts" }, { "weather.snow", "Schneesturm" }, { "weather.sand", "Sandsturm" }, { "weather.petrify", "Versteinernde Sonne" }, { "weather.moon", "Blauer Mond" }, { "weather.blood", "Blutmond" }, { "weather.sleepfog", "Schlafnebel" }, { "weather.quake", "Erdbeben" }, { "weather.dark", "Finsternis" }, { "weather.spores", "Sporenwolke" }, { "dark.torch", "Taschenlampe" }, { "weather.wind", "Sturm" }, { "weather.storm", "Sturm" }, { "weather.sun", "Brennende Sonne" }, { "weather.on", "AN" }, { "weather.strength", "HÖCHSTSTÄRKE" }, { "weather.pushonly", "(nur Schub)" }, { "weather.off", "AUS" }, { "weather.bare", "(auf dieser Karte ohne Anlage - nur Wirkung)" }, { "variants.none", "keine Varianten" }, { "pick.random", "Zufällig" }, { "ascent.title", "Schwierigkeit" }, { "ascent.tenderfoot", "Tenderfoot" }, { "ascent.peak", "PEAK" }, { "ascent.n", "Aufstieg" }, { "name.auto", "Automatisch" }, { "name.plain", "Weiß" }, { "name.silver", "Silber" }, { "name.gold", "Gold" }, { "name.diamond", "Diamant" }, { "name.rainbow", "Regenbogen" }, { "ascent.nadir", "(nur über Nadir)" }, { "button.start", "STARTEN" }, { "button.cancel", "ABBRECHEN" }, { "warning.load", "ACHTUNG: Das Laden dauert im FINALEN AUFSTIEG deutlich länger!" }, { "join.late", "IN EINEN LAUFENDEN FINALEN AUFSTIEG EINGESTIEGEN" }, { "join.building", "Der ganze Berg musste erst neu gebaut werden - daher die Wartezeit." }, { "biome.Shore", "Küste" }, { "biome.Tropics", "Tropen" }, { "biome.Roots", "Wurzeln" }, { "biome.Alpine", "Alpin" }, { "biome.Mesa", "Mesa" }, { "biome.Volcano", "Caldera" }, { "biome.Swamp", "Düsternis" }, { "biome.Caldera", "Caldera" }, { "biome.Gloom", "Düsternis" }, { "biome.Temple", "Zitadelle" }, { "load.prepare", "Berg wird vorbereitet" }, { "load.build", "Der Berg wird gebaut" }, { "load.gen", "Landschaften werden gebaut" }, { "load.wait", "Auf Insel warten" }, { "load.download", "Insel herunterladen" }, { "load.unpack", "Karte auspacken" }, { "load.measure", "Berg wird vermessen" }, { "load.light", "Licht wird berechnet" }, { "load.cpulight", "CPU-Lichtberechnung" }, { "load.wire", "Wege werden verbunden" }, { "load.done", "Fertig" } }; private static readonly Dictionary FileEn = new Dictionary(); private static readonly Dictionary FileDe = new Dictionary(); private static DateTime _shippedStamp = DateTime.MinValue; private static DateTime _localStamp = DateTime.MinValue; internal static bool German => (int)LocalizedText.CURRENT_LANGUAGE == 3; private static string ShippedPath { get { try { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); return string.IsNullOrEmpty(directoryName) ? null : Path.Combine(directoryName, "TrueFinalAscent.Texts.cfg"); } catch (Exception) { return null; } } } private static string LocalPath => Path.Combine(Paths.ConfigPath, "TrueFinalAscent.Texts.cfg"); internal static string Get(string key) { if (German) { if (FileDe.TryGetValue(key, out var value) && value.Length > 0) { return value; } if (BuiltInDe.TryGetValue(key, out var value2)) { return value2; } } if (FileEn.TryGetValue(key, out var value3) && value3.Length > 0) { return value3; } if (!BuiltInEn.TryGetValue(key, out var value4)) { return key; } return value4; } internal static string VariantKey(FinalAscentSetup.BiomeVariants biome, string sceneName) { StringBuilder stringBuilder = new StringBuilder("variant."); stringBuilder.Append(biome.Key.Substring("biome.".Length)).Append('.'); foreach (char c in sceneName) { if (char.IsLetterOrDigit(c)) { stringBuilder.Append(c); } } return stringBuilder.ToString(); } internal static string VariantLabel(FinalAscentSetup.BiomeVariants biome, int index) { string key = VariantKey(biome, biome.Names[index]); if (German && FileDe.TryGetValue(key, out var value) && value.Length > 0) { return value; } if (FileEn.TryGetValue(key, out var value2) && value2.Length > 0) { return value2; } return biome.Labels[index]; } internal static bool Changed() { if (!(Stamp(ShippedPath) != _shippedStamp)) { return Stamp(LocalPath) != _localStamp; } return true; } private static DateTime Stamp(string path) { try { return (!string.IsNullOrEmpty(path) && File.Exists(path)) ? File.GetLastWriteTimeUtc(path) : DateTime.MinValue; } catch (Exception) { return DateTime.MinValue; } } internal static void Load() { FileEn.Clear(); FileDe.Clear(); int num = Read(ShippedPath); EnsureLocalTemplate(); int num2 = Read(LocalPath); _shippedStamp = Stamp(ShippedPath); _localStamp = Stamp(LocalPath); Plugin.Log.LogInfo((object)(string.Format("{0} Texte: {1} Zeilen aus dem Mod", "[FinalAscent]", num) + ((num2 > 0) ? $", {num2} vom Rechner daruebergelegt" : "") + $" ({FileEn.Count} englisch, {FileDe.Count} deutsch).")); } private static int Read(string path) { if (string.IsNullOrEmpty(path) || !File.Exists(path)) { return 0; } try { Dictionary dictionary = FileEn; int num = 0; string[] array = File.ReadAllLines(path, Encoding.UTF8); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length == 0 || text[0] == '#') { continue; } if (text[0] == '[') { dictionary = (text.ToLowerInvariant().Contains("de") ? FileDe : FileEn); continue; } int num2 = text.IndexOf('='); if (num2 > 0) { string key = text.Substring(0, num2).Trim(); string text2 = text.Substring(num2 + 1).Trim().Replace("\\n", "\n"); if (text2.Length > 0) { dictionary[key] = text2; } num++; } } return num; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] " + Path.GetFileName(path) + " liess sich nicht lesen (" + ex.Message + ") - diese Lage wird uebersprungen.")); return 0; } } private static void EnsureLocalTemplate() { try { if (!File.Exists(LocalPath)) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# TrueFinalAscent - eigene Texte, nur fuer diesen Rechner"); stringBuilder.AppendLine("# TrueFinalAscent - your own texts, this machine only"); stringBuilder.AppendLine("#"); stringBuilder.AppendLine("# Diese Datei ist ABSICHTLICH leer. Was hier steht, uebersteuert"); stringBuilder.AppendLine("# den mitgelieferten Text; alles andere bleibt, wie der Mod es"); stringBuilder.AppendLine("# ausliefert. Waere sie vorbelegt, kaemen Aenderungen am Mod nie an."); stringBuilder.AppendLine("#"); stringBuilder.AppendLine("# This file is intentionally empty. Anything here overrides the"); stringBuilder.AppendLine("# text shipped with the mod; everything else stays as delivered."); stringBuilder.AppendLine("#"); stringBuilder.AppendLine("# Alle Schluessel stehen in TrueFinalAscent.Texts.cfg im Ordner des Mods."); stringBuilder.AppendLine("# All keys are listed in TrueFinalAscent.Texts.cfg in the mod folder."); stringBuilder.AppendLine("#"); stringBuilder.AppendLine("# Beispiel / example:"); stringBuilder.AppendLine("# [de]"); stringBuilder.AppendLine("# mode.title = LETZTER AUFSTIEG"); stringBuilder.AppendLine(); stringBuilder.AppendLine("[en]"); stringBuilder.AppendLine(); stringBuilder.AppendLine("[de]"); stringBuilder.AppendLine(); Directory.CreateDirectory(Paths.ConfigPath); File.WriteAllText(LocalPath, stringBuilder.ToString(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: true)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] TrueFinalAscent.Texts.cfg liess sich nicht anlegen: " + ex.Message)); } } } [HarmonyPatch(typeof(GUIManager), "SetHeroTitle")] internal static class FinalAscentTitleOnce { private const string Tag = "[FinalAscent]"; private static readonly FieldInfo SphereField = AccessTools.Field(typeof(OrbFogHandler), "sphere"); private static string _last; private static float _at; private static string _pending; private static bool _replaying; private static bool Prefix(string text, AudioClip stinger) { if (!FinalAscent.Active || string.IsNullOrEmpty(text)) { return true; } if (!_replaying && (Object)(object)Plugin.Instance != (Object)null) { FogSphere val = Ball(); if ((Object)(object)val != (Object)null && val.ENABLE > 0.01f && val.REVEAL_AMOUNT < 0.5f) { if (text == _pending) { return false; } _pending = text; Plugin.Log.LogInfo((object)("[FinalAscent] Titel '" + text + "' wartet auf den Vorhang " + $"(Enthuellung bei {val.REVEAL_AMOUNT:P0}).")); ((MonoBehaviour)Plugin.Instance).StartCoroutine(WhenOpen(text, stinger)); return false; } } if (text == _last && Time.realtimeSinceStartup - _at < 90f) { Plugin.Log.LogInfo((object)("[FinalAscent] Titel '" + text + "' war gerade schon zu sehen - die Wiederholung entfaellt.")); return false; } _last = text; _at = Time.realtimeSinceStartup; return true; } private static FogSphere Ball() { OrbFogHandler instance = Singleton.Instance; if (!((Object)(object)instance != (Object)null)) { return null; } object? obj = SphereField?.GetValue(instance); return (FogSphere)((obj is FogSphere) ? obj : null); } private static IEnumerator WhenOpen(string text, AudioClip stinger) { float waited = 0f; while (waited < 12f) { FogSphere val = Ball(); if ((Object)(object)val == (Object)null || val.ENABLE <= 0.01f || val.REVEAL_AMOUNT >= 0.5f) { break; } waited += Time.deltaTime; yield return null; } _pending = null; _replaying = true; try { if ((Object)(object)GUIManager.instance != (Object)null) { GUIManager.instance.SetHeroTitle(text, stinger, false); } } finally { _replaying = false; } } } [HarmonyPatch] internal static class FinalAscentTombEntrance { private const string Tag = "[FinalAscent]"; private static bool _said; private static MethodBase TargetMethod() { return AccessTools.EnumeratorMoveNext((MethodBase)AccessTools.Method(typeof(DesertRockSpawner), "Execute", (Type[])null, (Type[])null)); } private static IEnumerable Transpiler(IEnumerable code) { List list = new List(code); int num = 0; foreach (CodeInstruction item in list) { if (IsHalf(item)) { num++; } } if (num != 1) { Plugin.Log.LogWarning((object)(string.Format("{0} Gruft-Eingang: {1} Stellen mit 0,5 statt genau einer - ", "[FinalAscent]", num) + "es wird NICHTS getauscht, der Muenzwurf bleibt wie in Vanilla.")); foreach (CodeInstruction item2 in list) { yield return item2; } yield break; } foreach (CodeInstruction item3 in list) { if (IsHalf(item3)) { yield return new CodeInstruction(OpCodes.Ldc_R4, (object)1.1f); } else { yield return item3; } } } private static bool IsHalf(CodeInstruction one) { if (one.opcode == OpCodes.Ldc_R4 && one.operand is float num) { return Mathf.Approximately(num, 0.5f); } return false; } private static void Postfix() { if (!_said) { _said = true; Plugin.Log.LogInfo((object)"[FinalAscent] Gruft-Eingang: der Muenzwurf ist ausgehebelt, der Mesa-Tempel hat immer einen offenen Zugang. Welcher es ist, bleibt gewuerfelt."); } } internal static void Reset() { _said = false; } } [HarmonyPatch(typeof(TombTrigger), "TriggerTomb")] internal static class FinalAscentTombGate { private const string Tag = "[FinalAscent]"; internal const string RoomKey = "FAtomb"; private static void Postfix() { if (FinalAscent.Active) { FinalAscentBuilder.DropMesaBandBottom("Gruft betreten"); Publish(); } } private static void Publish() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0045: Expected O, but got Unknown if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null || Known()) { return; } try { Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"FAtomb", (object)FinalAscent.Seed.ToString(CultureInfo.InvariantCulture)); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)(string.Format("{0} Gruft-Trenner: im Raum vermerkt (Seed {1}) - ", "[FinalAscent]", FinalAscent.Seed) + "damit faellt er auch bei allen anderen und bei jedem Nachzuegler.")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[FinalAscent] Gruft-Trenner liess sich nicht im Raum vermerken: " + ex.Message + ". Er faellt dann nur auf diesem Rechner.")); } } private static bool Known() { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return false; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties != null && ((Dictionary)(object)customProperties).TryGetValue((object)"FAtomb", out object value) && value is string text) { return text == FinalAscent.Seed.ToString(CultureInfo.InvariantCulture); } return false; } internal static void ApplyFromRoom() { if (FinalAscent.Active && Known()) { FinalAscentBuilder.DropMesaBandBottom("der Raum meldet: Gruft war schon betreten"); } } } internal sealed class FinalAscentTorches : MonoBehaviour { private sealed class Torch { internal Light Beam; internal Vector3 Aim; internal Vector3 Sway; } private const string Tag = "[FinalAscent]"; private const float Reach = 55f; private const float Wide = 55f; private const float Core = 24f; private const float Bright = 85f; private const float Stiff = 85f; private const float Damp = 9f; private const float Ahead = 0.25f; private static readonly Color Glow = new Color(1f, 0.95f, 0.86f, 1f); private readonly Dictionary _beams = new Dictionary(); private readonly List _gone = new List(); private static FinalAscentTorches _instance; private bool _told; internal static void Install() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("FA_Torches"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } } private void LateUpdate() { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) float lift = FinalAscentDarkSky.Lift; if (lift <= 0f) { Douse(); return; } List allPlayerCharacters = PlayerHandler.GetAllPlayerCharacters(); 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.refs == null || val.data.dead) { continue; } Torch torch = Lamp(val); if (torch == null || (Object)(object)torch.Beam == (Object)null) { continue; } if (!FinalAscentFlashlight.Burning(val)) { ((Behaviour)torch.Beam).enabled = false; torch.Aim = Vector3.zero; torch.Sway = Vector3.zero; continue; } if (!val.refs.ragdoll.partDict.TryGetValue((BodypartType)4, out var value) || (Object)(object)value == (Object)null) { ((Behaviour)torch.Beam).enabled = false; continue; } Vector3 look = val.data.lookDirection; if (((Vector3)(ref look)).sqrMagnitude < 0.001f) { look = value.transform.forward; } torch.Aim = Wobble(torch, look); ((Component)torch.Beam).transform.position = value.transform.position + torch.Aim * 0.25f; ((Component)torch.Beam).transform.rotation = Quaternion.LookRotation(torch.Aim); torch.Beam.intensity = 85f * lift; ((Behaviour)torch.Beam).enabled = true; } Sweep(allPlayerCharacters); } internal static Vector3 AimOf(Character who) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_instance != (Object)null && (Object)(object)who != (Object)null && _instance._beams.TryGetValue(who, out var value) && value != null && ((Vector3)(ref value.Aim)).sqrMagnitude > 0.001f) { return value.Aim; } if (!((Object)(object)who != (Object)null) || !((Object)(object)who.data != (Object)null)) { return Vector3.forward; } return who.data.lookDirection; } private static Vector3 Wobble(Torch torch, Vector3 look) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref torch.Aim)).sqrMagnitude < 0.001f) { torch.Sway = Vector3.zero; return look; } float num = Mathf.Min(Time.deltaTime, 0.05f); torch.Sway += (look - torch.Aim) * (85f * num); torch.Sway *= Mathf.Exp(-9f * num); Vector3 val = torch.Aim + torch.Sway * num; return ((Vector3)(ref val)).normalized; } private Torch Lamp(Character who) { //IL_0028: 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_00ef: Unknown result type (might be due to invalid IL or missing references) if (_beams.TryGetValue(who, out var value) && value != null && (Object)(object)value.Beam != (Object)null) { return value; } Light val = new GameObject("FA_Torch").AddComponent(); val.type = (LightType)0; val.range = 55f; val.spotAngle = 55f; val.innerSpotAngle = 24f; val.color = Glow; val.intensity = 0f; val.shadows = (LightShadows)2; val.shadowStrength = 1f; val.shadowNearPlane = 0.3f; Torch torch = new Torch { Beam = val }; _beams[who] = torch; if (!_told) { _told = true; Plugin.Log.LogInfo((object)(string.Format("{0} Finsternis: Lampen an - Kegel {1:0}/{2:0} Grad, ", "[FinalAscent]", 55f, 24f) + $"{55f:0}m, Schatten {val.shadows}.")); } return torch; } private void Sweep(List all) { _gone.Clear(); foreach (KeyValuePair beam in _beams) { if ((Object)(object)beam.Key == (Object)null || (Object)(object)beam.Key.data == (Object)null || beam.Key.data.dead || !all.Contains(beam.Key)) { _gone.Add(beam.Key); } } for (int i = 0; i < _gone.Count; i++) { if (_beams.TryGetValue(_gone[i], out var value) && value != null && (Object)(object)value.Beam != (Object)null) { Object.Destroy((Object)(object)((Component)value.Beam).gameObject); } _beams.Remove(_gone[i]); } } private void Douse() { if (_beams.Count == 0) { return; } foreach (Torch value in _beams.Values) { if (value != null && (Object)(object)value.Beam != (Object)null) { Object.Destroy((Object)(object)((Component)value.Beam).gameObject); } } _beams.Clear(); _told = false; } } [HarmonyPatch] internal static class FinalAscentTouchProbe { private const string Tag = "[FinalAscent]"; private const int Limit = 60; private static int _said; internal static void Reset() { _said = 0; } private static IEnumerable TargetMethods() { List list = new List(); Type typeFromHandle = typeof(IInteractible); Type[] types; try { types = typeFromHandle.Assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { types = ex.Types; } Type[] array = types; foreach (Type type in array) { if (type == null || type.IsAbstract || type.IsInterface || !typeFromHandle.IsAssignableFrom(type)) { continue; } try { MethodInfo methodInfo = AccessTools.DeclaredMethod(type, "Interact", new Type[1] { typeof(Character) }, (Type[])null); if (methodInfo != null && !methodInfo.IsAbstract) { list.Add(methodInfo); } } catch { } } Plugin.Log.LogInfo((object)string.Format("{0} Beruehrungs-Sonde an {1} Interact-Umsetzungen.", "[FinalAscent]", list.Count)); return list; } private static void Prefix(object __instance, Character interactor) { if (_said >= 60) { return; } _said++; Component val = (Component)((__instance is Component) ? __instance : null); string text = "?"; if ((Object)(object)val != (Object)null) { try { text = FinalAscentDelivery.ScenePathOf(val.transform); } catch { text = ((Object)val.gameObject).name; } } bool flag = (Object)(object)interactor != (Object)null && interactor.IsLocal; Plugin.Log.LogWarning((object)("[FinalAscent] BERUEHRT (" + (PhotonNetwork.IsMasterClient ? "HOST" : "GAST") + "): " + ((__instance != null) ? __instance.GetType().Name : "?") + " an '" + text + "' durch " + (((Object)(object)interactor != (Object)null) ? ((Object)interactor).name : "?") + (flag ? " (ich selbst)" : " (ein anderer)") + "." + ((_said == 60) ? $" Ab hier still - {60} Zeilen erreicht." : string.Empty))); } } [HarmonyPatch(typeof(TowerStacker), "Execute")] internal static class FinalAscentTowerStackerPatch { internal static List> WakeSink; private const string Tag = "[FinalAscent]"; private static void WakeOrDefer(GameObject piece) { if (WakeSink != null) { WakeSink.Add(new KeyValuePair(piece, value: true)); } else { piece.SetActive(true); } } private static bool Prefix(TowerStacker __instance, ref IEnumerator __result) { if (!FinalAscent.Active) { return true; } __result = Stack(__instance); return false; } private static IEnumerator Stack(TowerStacker stacker) { if (stacker.stack == null) { stacker.stack = new List(); } for (int num = stacker.stack.Count - 1; num >= 0; num--) { if ((Object)(object)stacker.stack[num] != (Object)null) { Object.DestroyImmediate((Object)(object)stacker.stack[num]); } } stacker.stack.Clear(); if (stacker.parts == null || stacker.parts.Count == 0 || stacker.stackHeight <= 0) { Plugin.Log.LogWarning((object)("[FinalAscent] Stapler '" + ((Object)stacker).name + "' hat nichts zu stapeln " + $"({((stacker.parts != null) ? stacker.parts.Count : 0)} Teile, " + $"Hoehe {stacker.stackHeight}).")); yield break; } Vector3 step = stacker.direction * stacker.offset; int built = 0; for (int i = 0; i < stacker.stackHeight; i++) { GameObject val = stacker.parts[i % stacker.parts.Count]; if (!((Object)(object)val == (Object)null)) { bool activeSelf = val.activeSelf; GameObject val2; try { val.SetActive(false); val2 = Object.Instantiate(val, ((Component)stacker).transform); } finally { val.SetActive(activeSelf); } ((Object)val2).name = ((Object)val).name; val2.transform.localPosition = step * (float)i; val2.transform.localRotation = Quaternion.Euler(0f, (Random.value < 0.5f) ? 0f : 180f, 0f); WakeOrDefer(val2); stacker.stack.Add(val2); built++; yield return null; } } Plugin.Detail(string.Format("{0} Stapler '{1}': {2} Stockwerke aus ", "[FinalAscent]", ((Object)stacker).name, built) + $"{stacker.parts.Count} Teilen, Abstand {stacker.offset:F1} entlang " + FinalAscentBuilder.Fmt(stacker.direction) + "."); } internal static int StackWith(TowerStacker stacker, string turns) { //IL_007c: 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_008c: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) if (stacker.stack == null) { stacker.stack = new List(); } for (int num = stacker.stack.Count - 1; num >= 0; num--) { if ((Object)(object)stacker.stack[num] != (Object)null) { Object.DestroyImmediate((Object)(object)stacker.stack[num]); } } stacker.stack.Clear(); if (stacker.parts == null || stacker.parts.Count == 0 || stacker.stackHeight <= 0) { return 0; } Vector3 val = stacker.direction * stacker.offset; int num2 = 0; for (int i = 0; i < stacker.stackHeight; i++) { GameObject val2 = stacker.parts[i % stacker.parts.Count]; if (!((Object)(object)val2 == (Object)null)) { bool activeSelf = val2.activeSelf; GameObject val3; try { val2.SetActive(false); val3 = Object.Instantiate(val2, ((Component)stacker).transform); } finally { val2.SetActive(activeSelf); } ((Object)val3).name = ((Object)val2).name; val3.transform.localPosition = val * (float)i; bool flag = num2 < turns.Length && turns[num2] == '1'; val3.transform.localRotation = Quaternion.Euler(0f, flag ? 180f : 0f, 0f); WakeOrDefer(val3); stacker.stack.Add(val3); num2++; } } Plugin.Log.LogInfo((object)(string.Format("{0} Stapler '{1}': {2} Stockwerke nach der ", "[FinalAscent]", ((Object)stacker).name, num2) + "Drehfolge des Hosts (" + turns + ").")); return num2; } } [HarmonyPatch(typeof(TowerStacker), "delete")] internal static class FinalAscentTowerStackerClearPatch { private static void Prefix(TowerStacker __instance) { if (__instance.stack == null) { __instance.stack = new List(); } } } internal static class FinalAscentUiKit { internal static readonly Color Navy = new Color(0.14f, 0.19f, 0.5f, 1f); internal static readonly Color Ink = new Color(0.07f, 0.07f, 0.08f, 1f); internal static readonly Color InkDim = new Color(0.47f, 0.47f, 0.49f, 1f); internal static readonly Color Card = new Color(0.945f, 0.937f, 0.915f, 1f); internal static readonly Color Band = new Color(0.32f, 0.5f, 1f, 1f); internal static readonly Color Blue = new Color(0.19f, 0.29f, 0.98f, 1f); internal static readonly Color Accent = new Color(0.8f, 0.11f, 0.13f, 1f); internal static readonly Color Orange = new Color(1f, 0.48f, 0.06f, 1f); internal static readonly Color Chalk = new Color(0.96f, 0.96f, 0.97f, 1f); internal static readonly Color ChalkDim = new Color(0.72f, 0.72f, 0.75f, 1f); internal static readonly Color Inset = new Color(0.868f, 0.86f, 0.845f, 1f); internal static readonly Color InsetOff = new Color(0.76f, 0.752f, 0.74f, 1f); internal static readonly Color Rule = new Color(0.07f, 0.07f, 0.08f, 0.2f); internal static readonly Color Hover = new Color(0.9f, 0.92f, 1f, 1f); internal static readonly Color Press = new Color(0.78f, 0.82f, 0.95f, 1f); internal static TMP_FontAsset Font; internal static Material FontMaterial; internal static Sprite CardSprite; internal static Sprite BorderSprite; internal static Sprite CheckSprite; private static Sprite FindSprite(params string[] names) { Sprite[] array = Resources.FindObjectsOfTypeAll(); foreach (string text in names) { Sprite[] array2 = array; foreach (Sprite val in array2) { if ((Object)(object)val != (Object)null && ((Object)val).name == text) { return val; } } } return null; } internal static void Sample(BoardingPass pass) { if ((Object)(object)pass == (Object)null) { return; } if ((Object)(object)Font == (Object)null) { TMP_Text val = (((Object)(object)pass.ascentTitle != (Object)null) ? pass.ascentTitle : ((Component)pass).GetComponentInChildren(true)); if ((Object)(object)val != (Object)null) { Font = val.font; FontMaterial = val.fontSharedMaterial; } } if ((Object)(object)CardSprite == (Object)null) { CardSprite = SpriteOfChild(((Component)pass).transform, "Panel"); BorderSprite = SpriteOfChild(((Component)pass).transform, "Border"); CheckSprite = FindSprite("UICheckMark", "Check"); Plugin.Log.LogInfo((object)("[FinalAscent] Haken: " + (((Object)(object)CheckSprite != (Object)null) ? ("'" + ((Object)CheckSprite).name + "' aus dem Spiel.") : "keiner gefunden, wird gezeichnet."))); } } private static Sprite SpriteOfChild(Transform root, string name) { Transform val = root.Find(name); Image val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if (!((Object)(object)val2 != (Object)null)) { return null; } return val2.sprite; } internal static ColorBlock Tint() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) ColorBlock defaultColorBlock = ColorBlock.defaultColorBlock; ((ColorBlock)(ref defaultColorBlock)).normalColor = Color.white; ((ColorBlock)(ref defaultColorBlock)).highlightedColor = Hover; ((ColorBlock)(ref defaultColorBlock)).selectedColor = Hover; ((ColorBlock)(ref defaultColorBlock)).pressedColor = Press; ((ColorBlock)(ref defaultColorBlock)).disabledColor = new Color(1f, 1f, 1f, 0.6f); ((ColorBlock)(ref defaultColorBlock)).fadeDuration = 0.08f; return defaultColorBlock; } internal static void PutOnTop(Canvas mine) { if ((Object)(object)mine == (Object)null) { return; } int num = 0; Canvas[] array = Resources.FindObjectsOfTypeAll(); foreach (Canvas val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)mine) && ((Behaviour)val).isActiveAndEnabled && val.sortingOrder > num) { num = val.sortingOrder; } } mine.sortingOrder = num + 10; } internal static RectTransform Rect(GameObject go) { return go.GetComponent() ?? go.AddComponent(); } internal static GameObject Node(string name, Transform parent) { //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_0027: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); return val; } internal static RectTransform Place(GameObject go, float x, float y, float w, float h) { //IL_0019: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) RectTransform obj = Rect(go); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 0.5f); obj.anchorMax = val; obj.anchorMin = val; obj.pivot = new Vector2(0.5f, 0.5f); obj.anchoredPosition = new Vector2(x, y); obj.sizeDelta = new Vector2(w, h); return obj; } internal static RectTransform Stretch(GameObject go, float left = 0f, float bottom = 0f, float right = 0f, float top = 0f) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) RectTransform obj = Rect(go); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = new Vector2(left, bottom); obj.offsetMax = new Vector2(0f - right, 0f - top); return obj; } internal static Image Box(GameObject go, Color color, Sprite sprite = null) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) Image val = go.AddComponent(); ((Graphic)val).color = color; if ((Object)(object)sprite != (Object)null && sprite.border != Vector4.zero) { val.sprite = sprite; val.type = (Type)1; } return val; } internal static TextMeshProUGUI Label(Transform parent, string text, float size, TextAlignmentOptions align, Color color) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = Node("Label", parent).AddComponent(); if ((Object)(object)Font != (Object)null) { ((TMP_Text)val).font = Font; ((TMP_Text)val).fontSharedMaterial = FontMaterial; } ((TMP_Text)val).text = text; ((TMP_Text)val).fontSize = size; ((TMP_Text)val).alignment = align; ((Graphic)val).color = color; ((Graphic)val).raycastTarget = false; ((TMP_Text)val).textWrappingMode = (TextWrappingModes)1; return val; } internal static TMP_InputField Input(Transform parent, float x, float y, float w, float h) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) GameObject val = Node("Input", parent); Place(val, x, y, w, h); Box(val, Inset); Edge(val.transform); GameObject obj = Node("TextArea", val.transform); RectTransform textViewport = Stretch(obj, 16f, 6f, 16f, 6f); obj.AddComponent(); TextMeshProUGUI val2 = Label(obj.transform, "", h * 0.52f, (TextAlignmentOptions)513, Ink); Stretch(((Component)val2).gameObject); TMP_InputField obj2 = val.AddComponent(); obj2.textViewport = textViewport; obj2.textComponent = (TMP_Text)(object)val2; obj2.contentType = (ContentType)2; obj2.characterLimit = 9; obj2.pointSize = h * 0.52f; ((Selectable)obj2).targetGraphic = (Graphic)(object)val.GetComponent(); obj2.caretWidth = 5; obj2.caretBlinkRate = 0.6f; obj2.caretColor = Accent; obj2.customCaretColor = true; ColorBlock defaultColorBlock = ColorBlock.defaultColorBlock; ((ColorBlock)(ref defaultColorBlock)).normalColor = Color.white; ((ColorBlock)(ref defaultColorBlock)).highlightedColor = new Color(1.05f, 1.05f, 1.1f, 1f); ((ColorBlock)(ref defaultColorBlock)).selectedColor = new Color(1.25f, 1.25f, 1.45f, 1f); ((ColorBlock)(ref defaultColorBlock)).pressedColor = new Color(1.25f, 1.25f, 1.45f, 1f); ((ColorBlock)(ref defaultColorBlock)).fadeDuration = 0.05f; ((Selectable)obj2).colors = defaultColorBlock; obj2.selectionColor = new Color(Blue.r, Blue.g, Blue.b, 0.35f); FinalAscentCaret.Attach(obj2, Accent); return obj2; } internal static Toggle Check(Transform parent, float x, float y, float w, float h, string caption, float fontSize) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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) GameObject val = Node("Toggle", parent); Place(val, x, y, w, h); ((Graphic)Box(val, new Color(1f, 1f, 1f, 0f))).raycastTarget = true; float num = h * 0.72f; GameObject val2 = Node("Box", val.transform); Place(val2, (0f - w) * 0.5f + num * 0.5f + 2f, 0f, num, num); Image targetGraphic = Box(val2, Inset); Edge(val2.transform); GameObject mark = Tick(val2.transform, num); Stretch(((Component)Label(val.transform, caption, fontSize, (TextAlignmentOptions)513, Ink)).gameObject, num + 18f); Toggle val3 = val.AddComponent(); ((Selectable)val3).targetGraphic = (Graphic)(object)targetGraphic; ((Selectable)val3).colors = Tint(); val3.isOn = true; ((UnityEvent)(object)val3.onValueChanged).AddListener((UnityAction)delegate(bool on) { mark.SetActive(on); }); mark.SetActive(val3.isOn); return val3; } private static GameObject Tick(Transform box, float side) { //IL_008c: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)CheckSprite != (Object)null) { GameObject obj = Node("Mark", box); Stretch(obj, side * 0.12f, side * 0.12f, side * 0.12f, side * 0.12f); Image obj2 = obj.AddComponent(); obj2.sprite = CheckSprite; ((Graphic)obj2).color = Blue; obj2.preserveAspect = true; ((Graphic)obj2).raycastTarget = false; return obj; } GameObject val = Node("Mark", box); RectTransform obj3 = Stretch(val); obj3.offsetMin = Vector2.zero; obj3.offsetMax = Vector2.zero; float h = Mathf.Max(3f, side * 0.14f); GameObject go = Node("Short", val.transform); ((Transform)Place(go, (0f - side) * 0.17f, (0f - side) * 0.1f, side * 0.4f, h)).localRotation = Quaternion.Euler(0f, 0f, 45f); ((Graphic)Box(go, Blue)).raycastTarget = false; GameObject go2 = Node("Long", val.transform); ((Transform)Place(go2, side * 0.08f, side * 0.04f, side * 0.66f, h)).localRotation = Quaternion.Euler(0f, 0f, -45f); ((Graphic)Box(go2, Blue)).raycastTarget = false; return val; } internal static Slider Slide(Transform parent, float x, float y, float w, float h) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) GameObject val = Node("Slider", parent); Place(val, x, y, w, h); float num = h * 0.32f; GameObject go = Node("Background", val.transform); Stretch(go, 0f, num, 0f, num); Box(go, InsetOff); GameObject val2 = Node("Fill Area", val.transform); Stretch(val2, 0f, num, 0f, num); GameObject go2 = Node("Fill", val2.transform); RectTransform val3 = Rect(go2); val3.anchorMin = Vector2.zero; val3.anchorMax = new Vector2(0f, 1f); val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; Box(go2, Blue); GameObject val4 = Node("Handle Slide Area", val.transform); Stretch(val4, h * 0.4f, 0f, h * 0.4f); GameObject go3 = Node("Handle", val4.transform); RectTransform val5 = Rect(go3); val5.anchorMin = new Vector2(0f, 0f); val5.anchorMax = new Vector2(0f, 1f); val5.sizeDelta = new Vector2(h * 0.8f, 0f); Image targetGraphic = Box(go3, Card); Slider obj = val.AddComponent(); obj.fillRect = val3; obj.handleRect = val5; ((Selectable)obj).targetGraphic = (Graphic)(object)targetGraphic; obj.direction = (Direction)0; ((Selectable)obj).colors = Tint(); return obj; } internal static TMP_Dropdown Drop(Transform parent, float x, float y, float w, float h) { //IL_0019: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0441: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Unknown result type (might be due to invalid IL or missing references) GameObject val = Node("Dropdown", parent); Place(val, x, y, w, h); Box(val, Inset); Edge(val.transform); TextMeshProUGUI val2 = Label(val.transform, "", h * 0.48f, (TextAlignmentOptions)513, Ink); Stretch(((Component)val2).gameObject, 14f, 0f, 30f); Stretch(((Component)Label(val.transform, "▾", h * 0.48f, (TextAlignmentOptions)516, InkDim)).gameObject, 0f, 0f, 12f); GameObject val3 = Node("Template", val.transform); RectTransform val4 = Rect(val3); val4.anchorMin = new Vector2(0f, 0f); val4.anchorMax = new Vector2(1f, 0f); val4.pivot = new Vector2(0.5f, 1f); val4.anchoredPosition = new Vector2(0f, 2f); val4.sizeDelta = new Vector2(0f, 230f); Box(val3, Inset); Outline(val3.transform); GameObject val5 = Node("Viewport", val3.transform); RectTransform val6 = Stretch(val5, 4f, 4f, 4f, 4f); val6.pivot = new Vector2(0f, 1f); ((Graphic)val5.AddComponent()).color = Color.white; val5.AddComponent().showMaskGraphic = false; GameObject val7 = Node("Content", val5.transform); RectTransform val8 = Rect(val7); val8.anchorMin = new Vector2(0f, 1f); val8.anchorMax = new Vector2(1f, 1f); val8.pivot = new Vector2(0.5f, 1f); val8.anchoredPosition = Vector2.zero; val8.sizeDelta = new Vector2(0f, h); GameObject val9 = Node("Item", val7.transform); RectTransform obj = Rect(val9); obj.anchorMin = new Vector2(0f, 0.5f); obj.anchorMax = new Vector2(1f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); obj.sizeDelta = new Vector2(0f, h); GameObject val10 = Node("Item Background", val9.transform); Stretch(val10); Box(val10, Color.white); GameObject val11 = Node("Item Checkmark", val9.transform); RectTransform obj2 = Rect(val11); obj2.anchorMin = Vector2.zero; obj2.anchorMax = new Vector2(0f, 1f); obj2.pivot = new Vector2(0f, 0.5f); obj2.sizeDelta = new Vector2(6f, 0f); obj2.anchoredPosition = Vector2.zero; Box(val11, Blue); TextMeshProUGUI val12 = Label(val9.transform, "Option", h * 0.46f, (TextAlignmentOptions)513, Ink); Stretch(((Component)val12).gameObject, 18f, 0f, 8f); Toggle obj3 = val9.AddComponent(); ((Selectable)obj3).targetGraphic = (Graphic)(object)val10.GetComponent(); obj3.graphic = (Graphic)(object)val11.GetComponent(); ColorBlock defaultColorBlock = ColorBlock.defaultColorBlock; ((ColorBlock)(ref defaultColorBlock)).normalColor = new Color(1f, 1f, 1f, 0f); ((ColorBlock)(ref defaultColorBlock)).highlightedColor = new Color(Blue.r, Blue.g, Blue.b, 0.2f); ((ColorBlock)(ref defaultColorBlock)).selectedColor = new Color(Blue.r, Blue.g, Blue.b, 0.12f); ((ColorBlock)(ref defaultColorBlock)).pressedColor = new Color(Blue.r, Blue.g, Blue.b, 0.34f); ((ColorBlock)(ref defaultColorBlock)).fadeDuration = 0.08f; ((Selectable)obj3).colors = defaultColorBlock; ScrollRect obj4 = val3.AddComponent(); obj4.content = val8; obj4.viewport = val6; obj4.horizontal = false; obj4.movementType = (MovementType)2; obj4.scrollSensitivity = 24f; val3.SetActive(false); TMP_Dropdown obj5 = val.AddComponent(); ((Selectable)obj5).targetGraphic = (Graphic)(object)val.GetComponent(); ((Selectable)obj5).colors = Tint(); obj5.template = val4; obj5.captionText = (TMP_Text)(object)val2; obj5.itemText = (TMP_Text)(object)val12; return obj5; } internal static void Edge(Transform parent, float thickness = 4f) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) Color color = default(Color); ((Color)(ref color))..ctor(Navy.r, Navy.g, Navy.b, 0.85f); Bar(parent, color, thickness, new Vector2(0f, 1f), new Vector2(1f, 1f), Vector2.up); Bar(parent, color, thickness, new Vector2(0f, 0f), new Vector2(1f, 0f), Vector2.zero); Bar(parent, color, thickness, new Vector2(0f, 0f), new Vector2(0f, 1f), Vector2.zero); Bar(parent, color, thickness, new Vector2(1f, 0f), new Vector2(1f, 1f), Vector2.right); } private static void Bar(Transform parent, Color color, float thickness, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot) { //IL_0012: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Node("Edge", parent); RectTransform obj2 = Rect(obj); obj2.anchorMin = anchorMin; obj2.anchorMax = anchorMax; obj2.pivot = new Vector2(0.5f, 0.5f); bool flag = Mathf.Approximately(anchorMin.y, anchorMax.y); obj2.sizeDelta = (flag ? new Vector2(0f, thickness) : new Vector2(thickness, 0f)); obj2.anchoredPosition = Vector2.zero; Image obj3 = obj.AddComponent(); ((Graphic)obj3).color = color; ((Graphic)obj3).raycastTarget = false; } internal static void Outline(Transform parent, float w = 0f, float h = 0f) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)BorderSprite == (Object)null) && !(BorderSprite.border == Vector4.zero)) { GameObject go = Node("Outline", parent); if (w > 0f && h > 0f) { Place(go, 0f, 0f, w, h); } else { Stretch(go); } Image obj = Box(go, Navy, BorderSprite); obj.fillCenter = false; ((Graphic)obj).raycastTarget = false; } } internal static Button Push(Transform parent, float x, float y, float w, float h, string caption, Color face, Color ink, float fontSize) { //IL_0018: 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_0067: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Node("Button", parent); Place(obj, x, y, w, h); Image targetGraphic = Box(obj, face, CardSprite); Stretch(((Component)Label(obj.transform, caption, fontSize, (TextAlignmentOptions)514, ink)).gameObject); Button obj2 = obj.AddComponent