Decompiled source of SoulSaviorLogbook v0.1.0
SoulSaviorLogbook.Plugin.dll
Decompiled 13 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using HarmonyLib; using I2.Loc; using Microsoft.CodeAnalysis; using ShinyShoe; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [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("SoulSaviorLogbook.Plugin")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+ff9eb3ec1a9b739abeb1237276d1a877ff3ecc88")] [assembly: AssemblyProduct("SoulSaviorLogbook.Plugin")] [assembly: AssemblyTitle("SoulSaviorLogbook.Plugin")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SoulSaviorLogbook.Plugin { [BepInPlugin("frutos.SoulSaviorLogbook", "Soul Savior Logbook", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "frutos.SoulSaviorLogbook"; public const string Version = "0.1.0"; internal const string LegacyGuid = "mt2_custom_clan_ui_fixes.Plugin"; internal static ManualLogSource Logger = new ManualLogSource("frutos.SoulSaviorLogbook"); private Harmony? harmony; public void Awake() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; LogbookSoulSavior.Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("SoulSavior", "Enabled", true, "Show the Soul Savior logbook with Souls and Clans. Reads ExpandedWinTracker records without modifying them.").Value; if (LogbookSoulSavior.Enabled) { harmony = new Harmony("frutos.SoulSaviorLogbook"); DisableLegacyLogbook(harmony); harmony.PatchAll(typeof(Plugin).Assembly); Logger.LogInfo((object)"Soul Savior Logbook 0.1.0 loaded (Souls and Clans)."); } } internal static void DisableLegacyLogbook(Harmony patches) { if (Chainloader.PluginInfos.TryGetValue("mt2_custom_clan_ui_fixes.Plugin", out var value)) { DisableLegacyLogbook(patches, ((object)value.Instance).GetType().Assembly); } } internal static void DisableLegacyLogbook(Harmony patches, Assembly assembly) { Type type = assembly.GetType("mt2_custom_clan_ui_fixes.Plugin.SoulSaviorTabRegistration"); Type type2 = assembly.GetType("mt2_custom_clan_ui_fixes.Plugin.LogbookSoulSavior"); if (!(type == null) || !(type2 == null)) { RemoveLegacyPatch(patches, type, "Register", typeof(CompendiumScreen), "Awake"); RemoveLegacyPatch(patches, type2, "AddPages", typeof(CompendiumSectionChecklist), "InitializeImpl"); Logger.LogInfo((object)"Legacy Soul Savior tab disabled in CustomClanUIFixes; UI fixes remain active."); } } private static void RemoveLegacyPatch(Harmony patches, Type? type, string patchName, Type target, string method) { if (!(type == null)) { MethodInfo methodInfo = AccessTools.Method(type, patchName, (Type[])null, (Type[])null) ?? throw new InvalidOperationException("Unsupported legacy logbook patch: " + type.FullName + "." + patchName); patches.Unpatch((MethodBase)AccessTools.Method(target, method, (Type[])null, (Type[])null), methodInfo); } } } [HarmonyPatch] public static class LogbookSoulSavior { public static bool Enabled = true; internal static readonly string SavePath = Path.Combine(Paths.ConfigPath, "ExpandedWinTracker.Plugin", "extraMetagameSave.json"); [HarmonyPatch(typeof(CompendiumSectionChecklist), "InitializeImpl")] [HarmonyPostfix] [HarmonyPriority(0)] private static void AddPages(CompendiumSectionChecklist __instance) { //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Expected O, but got Unknown //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Expected O, but got Unknown //IL_0270: Expected O, but got Unknown //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Expected O, but got Unknown //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Expected O, but got Unknown //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Expected O, but got Unknown //IL_0360: Expected O, but got Unknown //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Expected O, but got Unknown if (!Enabled) { return; } List<ChecklistPage> checklistPages = __instance.ChecklistPages; CompendiumScreen componentInParent = ((Component)__instance).GetComponentInParent<CompendiumScreen>(); SoulSaviorSection soulSaviorSection = ((componentInParent != null) ? ((Component)componentInParent).GetComponentInChildren<SoulSaviorSection>(true) : null); if ((Object)(object)soulSaviorSection == (Object)null || soulSaviorSection.Pages.Count != 0) { return; } List<ChecklistPage> list = new List<ChecklistPage>(); try { SaveManager save = default(SaveManager); ref SaveManager reference = ref save; object? value = AccessTools.Field(typeof(CompendiumSection), "saveManager").GetValue(__instance); reference = (SaveManager)((value is SaveManager) ? value : null); StandardChecklistPage val = checklistPages.OfType<StandardChecklistPage>().FirstOrDefault(); if ((Object)(object)save == (Object)null || (Object)(object)val == (Object)null) { return; } LayoutGroup layout = default(LayoutGroup); ref LayoutGroup reference2 = ref layout; object? value2 = AccessTools.Field(typeof(StandardChecklistPage), "clanSectionsLayoutAllClans").GetValue(val); reference2 = (LayoutGroup)((value2 is LayoutGroup) ? value2 : null); if ((Object)(object)layout == (Object)null || !((Component)layout).gameObject.activeSelf) { ref LayoutGroup reference3 = ref layout; object? value3 = AccessTools.Field(typeof(StandardChecklistPage), "clanSectionsLayoutStartingClans").GetValue(val); reference3 = (LayoutGroup)((value3 is LayoutGroup) ? value3 : null); } ClanChecklistSection val2 = ((IEnumerable<ClanChecklistSection>)((Component)val).GetComponentsInChildren<ClanChecklistSection>(true)).FirstOrDefault((Func<ClanChecklistSection, bool>)delegate(ClanChecklistSection s) { Transform parent = ((Component)s).transform.parent; LayoutGroup obj = layout; return (Object)(object)parent == (Object)(object)((obj != null) ? ((Component)obj).transform : null); }); if ((Object)(object)layout == (Object)null || (Object)(object)val2 == (Object)null) { return; } List<ClassData> list2 = (from c in save.GetBalanceData().GetClassDatas() where (Object)(object)c != (Object)null && (Object)(object)c.GetChampionData(0) != (Object)null && ((int)c.GetRequiredDlc() == 0 || save.IsDlcInstalled(c.GetRequiredDlc())) && (!c.IsCrew() || save.GetMetagameSave().IsFeatureUnlocked((UnlockedFeature)8)) select c).ToList(); List<SoulData> list3 = (from g in (from s in save.GetAllGameData().GetAllSoulDatas() where (Object)(object)s != (Object)null && !((RelicData)s).IsHidden && ((int)s.GetRequiredDLC() == 0 || save.IsDlcInstalled(s.GetRequiredDLC())) select s).GroupBy<SoulData, string>((SoulData s) => SoulSaviorRecords.SoulKey(((Object)s).name), StringComparer.Ordinal) select g.OrderBy((SoulData s) => s.GetTierLevel()).First()).OrderBy<SoulData, string>((SoulData s) => ((RelicData)s).GetName(), StringComparer.CurrentCulture).ToList(); for (int num = 0; num * 15 < list3.Count; num++) { GameObject val3 = new GameObject("Soul Savior souls " + (num + 1), new Type[1] { typeof(RectTransform) }); val3.SetActive(false); val3.transform.SetParent(((Component)soulSaviorSection).transform, false); CopyRect((RectTransform)((Component)val).transform, (RectTransform)val3.transform); SoulSaviorSoulsPage soulSaviorSoulsPage = val3.AddComponent<SoulSaviorSoulsPage>(); list.Add((ChecklistPage)(object)soulSaviorSoulsPage); soulSaviorSoulsPage.Build((RectTransform)((Component)layout).transform, Field<TMP_Text>(val2, "clanNameLabel"), list3.Skip(num * 15).Take(15).ToList()); } soulSaviorSection.SoulCatalog.AddRange(list3); int num2 = (list2.Count + 5 - 1) / 5; for (int num3 = 0; num3 < num2; num3++) { GameObject val4 = new GameObject("Soul Savior checklist " + (num3 + 1), new Type[1] { typeof(RectTransform) }); val4.SetActive(false); val4.transform.SetParent(((Component)soulSaviorSection).transform, false); CopyRect((RectTransform)((Component)val).transform, (RectTransform)val4.transform); SoulSaviorChecklistPage soulSaviorChecklistPage = val4.AddComponent<SoulSaviorChecklistPage>(); list.Add((ChecklistPage)(object)soulSaviorChecklistPage); soulSaviorChecklistPage.Build(save, val2, (RectTransform)((Component)layout).transform, list2.Skip(num3 * 5).Take(5).ToList(), num3 + 1, num2); } foreach (ChecklistPage item in list) { soulSaviorSection.Pages.Add(item); } soulSaviorSection.BuildSidebar(list2, Field<TMP_Text>(val2, "clanNameLabel")); soulSaviorSection.SetIcon(save); AccessTools.Method(typeof(PaginatedCompendiumSection), "RefreshPagination", (Type[])null, (Type[])null)?.Invoke(__instance, null); ((PaginatedCompendiumSection)__instance).PageCountChangedSignal.Dispatch(); Plugin.Logger.LogInfo((object)("[SoulSavior] " + list2.Count + " clanes, " + list.Count + " paginas; lectura de " + SavePath)); } catch (Exception ex) { foreach (ChecklistPage item2 in list) { soulSaviorSection.Pages.Remove(item2); if ((Object)(object)item2 != (Object)null) { Object.Destroy((Object)(object)((Component)item2).gameObject); } } Plugin.Logger.LogWarning((object)("[SoulSavior] No se pudieron crear las paginas: " + ex)); } } internal static void CopyRect(RectTransform from, RectTransform to) { //IL_0002: 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_001a: 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_0032: 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_004a: Unknown result type (might be due to invalid IL or missing references) to.anchorMin = from.anchorMin; to.anchorMax = from.anchorMax; to.pivot = from.pivot; to.sizeDelta = from.sizeDelta; to.anchoredPosition = from.anchoredPosition; ((Transform)to).localScale = ((Transform)from).localScale; ((Transform)to).localRotation = ((Transform)from).localRotation; } internal static T? Field<T>(object owner, string name) where T : class { return AccessTools.Field(owner.GetType(), name)?.GetValue(owner) as T; } } public sealed class SoulSaviorChecklistPage : ChecklistPage { private SaveManager? save; private readonly List<ClanChecklistSection> rows = new List<ClanChecklistSection>(); private readonly List<ClassData> classes = new List<ClassData>(); private RectTransform? grid; private TMP_Text? title; private TMP_Text? note; private int number; private int total; internal void Build(SaveManager manager, ClanChecklistSection template, RectTransform sourceLayout, List<ClassData> clans, int page, int count) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //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_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_00b4: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) save = manager; classes.AddRange(clans); number = page; total = count; GameObject val = new GameObject("Soul Savior rows", new Type[2] { typeof(RectTransform), typeof(GridLayoutGroup) }); val.transform.SetParent(((Component)this).transform, false); grid = (RectTransform)val.transform; LogbookSoulSavior.CopyRect(sourceLayout, grid); GridLayoutGroup component = val.GetComponent<GridLayoutGroup>(); Rect rect = sourceLayout.rect; float num; if (!(((Rect)(ref rect)).width > 1f)) { num = 1440f; } else { rect = sourceLayout.rect; num = ((Rect)(ref rect)).width; } component.cellSize = new Vector2(num, 157f); component.spacing = new Vector2(0f, 14f); component.constraint = (Constraint)1; component.constraintCount = 1; ((LayoutGroup)component).padding = new RectOffset(0, 0, 0, 0); ((LayoutGroup)component).childAlignment = (TextAnchor)0; TMP_Text template2 = LogbookSoulSavior.Field<TMP_Text>(template, "clanNameLabel"); title = Label(template2, (Transform)(object)grid, "Soul Savior title", 0f, 10f, 1400f, 28f, 24f); note = Label(template2, (Transform)(object)grid, "Soul Savior note", 0f, -860f, 1400f, 28f, 20f); ((Component)title).gameObject.SetActive(false); note.text = SoulSaviorText.Get(0); foreach (ClassData @class in classes) { ClanChecklistSection val2 = Object.Instantiate<ClanChecklistSection>(template, (Transform)(object)grid, false); ((Object)((Component)val2).gameObject).name = "Soul Savior " + @class.GetTitle(); ((Component)val2).gameObject.AddComponent<SoulSaviorClanFocus>().Clan = @class; GameUISelectableButton obj = ((Component)val2).gameObject.GetComponent<GameUISelectableButton>() ?? ((Component)val2).gameObject.AddComponent<GameUISelectableButton>(); ((Selectable)obj).targetGraphic = (Graphic)(object)LogbookSoulSavior.Field<Image>(val2, "clanIcon"); Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)3; obj.SetNavigation(navigation); LayoutGroup val3 = LogbookSoulSavior.Field<LayoutGroup>(val2, "subclanVictoryLayout"); SubclanVictoryItem[] componentsInChildren = ((Component)val2).GetComponentsInChildren<SubclanVictoryItem>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).transform.SetParent(((Component)val3).transform, false); } ((Component)val2).gameObject.AddComponent<SoulSaviorRowLayout>(); rows.Add(val2); AccessTools.Field(typeof(ClanChecklistSection), "includeDlcContent").SetValue(val2, true); ((Component)val2).gameObject.SetActive(true); } } public override IGameUIComponent? GetDefaultGameUISelectable() { object obj = (from f in rows.SelectMany((ClanChecklistSection r) => ((Component)r).GetComponentsInChildren<SubclanVictoryItem>()) where ((Component)f).gameObject.activeInHierarchy select ((Component)f).GetComponent<IGameUIComponent>()).FirstOrDefault(); if (obj == null) { ClanChecklistSection? obj2 = rows.FirstOrDefault(); if (obj2 == null) { return null; } obj = ((Component)obj2).GetComponent<GameUISelectableButton>(); } return (IGameUIComponent?)obj; } public override void Open() { ((CompendiumPage)this).Open(); try { RefreshRecords(); ((Component)this).GetComponentInParent<SoulSaviorSection>()?.EnsureSelectedClan(classes); Adjust(); ((MonoBehaviour)this).StartCoroutine(Settle()); } catch (Exception ex) { foreach (ClanChecklistSection row in rows) { ((Component)row).gameObject.SetActive(false); } if ((Object)(object)note != (Object)null) { note.text = SoulSaviorText.Get(3); } Plugin.Logger.LogWarning((object)("[SoulSavior] Error al abrir la pagina: " + ex)); } } private void RefreshRecords() { //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: 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_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Expected O, but got Unknown //IL_01a2: 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_01c8: Expected O, but got Unknown if ((Object)(object)save == (Object)null) { return; } SoulSaviorRecords soulSaviorRecords; try { using FileStream input = File.Open(LogbookSoulSavior.SavePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); soulSaviorRecords = SoulSaviorRecords.Read(input); } catch (Exception ex) { foreach (ClanChecklistSection row in rows) { ((Component)row).gameObject.SetActive(false); } if ((Object)(object)note != (Object)null) { note.text = SoulSaviorText.Get(2); } Plugin.Logger.LogWarning((object)("[SoulSavior] Guardado no disponible: " + ex.Message)); return; } if ((Object)(object)note != (Object)null) { note.text = ((soulSaviorRecords.Count == 0) ? SoulSaviorText.Get(1) : SoulSaviorText.Get(0)); } for (int i = 0; i < rows.Count; i++) { ClanChecklistSection val = rows[i]; SoulSaviorRowLayout.Restore(val); val.Set(classes[i], save, 0); SubclanVictoryItem[] componentsInChildren = ((Component)val).GetComponentsInChildren<SubclanVictoryItem>(true); foreach (SubclanVictoryItem val2 in componentsInChildren) { if (((Component)val2).gameObject.activeSelf && val2.data != null) { ClassData mainClassData = val2.data.mainClassData; ClassData subClassData = val2.data.subClassData; Data val3 = new Data { mainClassData = mainClassData, subClassData = subClassData, covenantLevels = new List<ClassCombinationWinData>() }; for (int k = 0; k < 2; k++) { val3.covenantLevels.Add(new ClassCombinationWinData { highestAscensionLevel = soulSaviorRecords.Get(((GameData)mainClassData).GetID(), ((GameData)subClassData).GetID(), k) }); } val2.Set(val3, 0); ShowFlag(val2, soulSaviorRecords); } } val.ReparentCrewVictoryItems(); LevelIndicator val4 = LogbookSoulSavior.Field<LevelIndicator>(val, "levelIndicator"); if ((Object)(object)val4 != (Object)null) { ((Component)val4).gameObject.SetActive(false); } List<ClanChecklistChampionUI> list = LogbookSoulSavior.Field<List<ClanChecklistChampionUI>>(val, "championPortraits"); if (list != null) { foreach (ClanChecklistChampionUI item in list) { item.SetMastered(false); } } ShowSummary(val, classes[i], soulSaviorRecords); SoulSaviorSection componentInParent = ((Component)this).GetComponentInParent<SoulSaviorSection>(); if (componentInParent == null || !componentInParent.ShowPendingOnly) { continue; } componentsInChildren = ((Component)val).GetComponentsInChildren<SubclanVictoryItem>(); foreach (SubclanVictoryItem val5 in componentsInChildren) { if (val5.data != null && soulSaviorRecords.Best(((GameData)classes[i]).GetID(), ((GameData)val5.data.subClassData).GetID()) >= 0) { ((Component)val5).gameObject.SetActive(false); } } } } private static void ShowFlag(SubclanVictoryItem flag, SoulSaviorRecords records) { Data data = flag.data; int num = records.Best(((GameData)data.mainClassData).GetID(), ((GameData)data.subClassData).GetID()); List<GameObjectSwapper> list = LogbookSoulSavior.Field<List<GameObjectSwapper>>(flag, "maxVictoryCrowns"); if (list != null) { foreach (GameObjectSwapper item in list) { ((Component)item).gameObject.SetActive(false); } } Animator val = LogbookSoulSavior.Field<Animator>(flag, "bannerSheen"); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(false); } Image val2 = LogbookSoulSavior.Field<Image>(flag, "covenantIcon"); if ((Object)(object)val2 != (Object)null) { ((Behaviour)val2).enabled = false; } TMP_Text val3 = LogbookSoulSavior.Field<TMP_Text>(flag, "covenantLevelLabel"); if ((Object)(object)val3 != (Object)null) { ((Behaviour)val3).enabled = true; val3.text = ((num < 0) ? "—" : ("S" + num)); } StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < 2; i++) { CardData val4 = data.mainClassData.GetChampionData(i)?.championCardData; if (!((Object)(object)val4 == (Object)null)) { int num2 = records.Get(((GameData)data.mainClassData).GetID(), ((GameData)data.subClassData).GetID(), i); stringBuilder.Append(val4.GetName()).Append(": ").Append((num2 < 0) ? SoulSaviorText.Get(4) : SoulSaviorText.Get(5, num2)) .AppendLine(); } } TooltipProviderComponent val5 = LogbookSoulSavior.Field<TooltipProviderComponent>(flag, "tooltipProvider"); if ((Object)(object)val5 != (Object)null) { val5.SetTooltipLocalized("Soul Savior · " + data.mainClassData.GetTitle() + " / " + data.subClassData.GetTitle(), stringBuilder.ToString(), (TooltipDesignType)3, false); } } private static void ShowSummary(ClanChecklistSection row, ClassData main, SoulSaviorRecords records) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) CardMasteryMeter val = LogbookSoulSavior.Field<CardMasteryMeter>(row, "cardMasteryMeter"); if ((Object)(object)val == (Object)null) { return; } foreach (Transform item in ((Component)val).transform) { ((Component)item).gameObject.SetActive(false); } GridLayoutGroup component = ((Component)val).GetComponent<GridLayoutGroup>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } Transform val2 = ((Component)val).transform.Find("Soul Savior summary"); TMP_Text val3; if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(true); val3 = ((Component)val2).GetComponent<TMP_Text>(); } else { val3 = Label(LogbookSoulSavior.Field<TMP_Text>(row, "clanNameLabel"), ((Component)val).transform, "Soul Savior summary", 0f, -10f, 190f, 105f, 22f); } List<SubclanVictoryItem> list = (from f in ((Component)row).GetComponentsInChildren<SubclanVictoryItem>(true) where ((Component)f).gameObject.activeSelf && f.data != null select f).ToList(); int num = IEnumerableUtility.Count<SubclanVictoryItem>(list, (Func<SubclanVictoryItem, bool>)((SubclanVictoryItem f) => records.Best(((GameData)main).GetID(), ((GameData)f.data.subClassData).GetID()) >= 0)); val3.text = SoulSaviorText.Get(6, num, list.Count); } internal static TMP_Text Label(TMP_Text template, Transform parent, string name, float x, float y, float width, float height, float size) { //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_0060: 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_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_009f: 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_00b0: 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_00c8: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val.transform.SetParent(parent, false); TMP_Text component = (TMP_Text)(object)val.GetComponent<TextMeshProUGUI>(); component.font = template.font; component.fontSharedMaterial = template.fontSharedMaterial; ((Graphic)component).color = ((Graphic)template).color; ((Object)component).name = name; ((Component)component).gameObject.SetActive(true); RectTransform rectTransform = component.rectTransform; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0f, 1f); rectTransform.pivot = val2; Vector2 anchorMin = (rectTransform.anchorMax = val2); rectTransform.anchorMin = anchorMin; rectTransform.sizeDelta = new Vector2(width, height); rectTransform.anchoredPosition = new Vector2(x, y); ((Transform)rectTransform).localScale = Vector3.one; (((Component)component).GetComponent<LayoutElement>() ?? ((Component)component).gameObject.AddComponent<LayoutElement>()).ignoreLayout = true; component.enableAutoSizing = false; component.fontSize = size; component.alignment = (TextAlignmentOptions)257; ((Graphic)component).raycastTarget = false; component.overflowMode = (TextOverflowModes)1; return component; } private void Adjust() { //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) if (!((Object)(object)grid == (Object)null)) { LayoutRebuilder.ForceRebuildLayoutImmediate(grid); List<Component> lista = rows.Cast<Component>().ToList(); Rect rect = grid.rect; SoulSaviorRowLayout.Widen(lista, ((Rect)(ref rect)).width); LayoutRebuilder.ForceRebuildLayoutImmediate(grid); } } private IEnumerator Settle() { for (int frame = 0; frame < 5; frame++) { yield return null; if (!((Behaviour)this).isActiveAndEnabled) { break; } Adjust(); } } } public sealed class SoulSaviorFocusRelay : MonoBehaviour { private void OnEnable() { UISignals.GameUITriggered.AddListener((Action<CoreInputControlMapping, IGameUIComponent>)Focus); } private void OnDisable() { UISignals.GameUITriggered.RemoveListener((Action<CoreInputControlMapping, IGameUIComponent>)Focus); } private void Focus(CoreInputControlMapping mapping, IGameUIComponent target) { object obj; if (target == null) { obj = null; } else { Component component = target.component; obj = ((component != null) ? component.GetComponentInParent<SoulSaviorClanFocus>() : null); } SoulSaviorClanFocus soulSaviorClanFocus = (SoulSaviorClanFocus)obj; if ((Object)(object)soulSaviorClanFocus != (Object)null && ((Behaviour)soulSaviorClanFocus).isActiveAndEnabled && (Object)(object)((Component)soulSaviorClanFocus).GetComponentInParent<SoulSaviorSection>() == (Object)(object)((Component)this).GetComponent<SoulSaviorSection>()) { ((Component)this).GetComponent<SoulSaviorSection>().SelectClan(soulSaviorClanFocus.Clan); } } } public sealed class SoulSaviorClanFocus : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, ISelectHandler { internal ClassData? Clan; private void Focus() { ((Component)this).GetComponentInParent<SoulSaviorSection>()?.SelectClan(Clan); } public void OnPointerEnter(PointerEventData data) { Focus(); } public void OnSelect(BaseEventData data) { Focus(); } } public sealed class SoulSaviorSoulsPage : ChecklistPage { private readonly List<(SoulData Soul, Image Icon, TMP_Text Name, TMP_Text Record, GameUISelectableButton Button, TooltipProviderComponent Tooltip)> items = new List<(SoulData, Image, TMP_Text, TMP_Text, GameUISelectableButton, TooltipProviderComponent)>(); private RectTransform? grid; private GridLayoutGroup? layout; private TMP_Text? heading; private TMP_Text? note; private float measuredSoulWidth = -1f; internal void Build(RectTransform sourceLayout, TMP_Text template, List<SoulData> souls) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //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_0075: 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_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Expected O, but got Unknown //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0208: 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_0241: 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_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0298: 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_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Soul Savior rows", new Type[2] { typeof(RectTransform), typeof(GridLayoutGroup) }); val.transform.SetParent(((Component)this).transform, false); grid = (RectTransform)val.transform; LogbookSoulSavior.CopyRect(sourceLayout, grid); RectTransform? obj = grid; obj.anchoredPosition += new Vector2(0f, -48f); layout = val.GetComponent<GridLayoutGroup>(); layout.constraint = (Constraint)1; layout.constraintCount = 3; layout.spacing = new Vector2(16f, 14f); ((LayoutGroup)layout).childAlignment = (TextAnchor)0; layout.startCorner = (Corner)0; layout.startAxis = (Axis)0; heading = SoulSaviorChecklistPage.Label(template, (Transform)(object)grid, "Soul catalog heading", 0f, 48f, 1400f, 42f, 30f); note = SoulSaviorChecklistPage.Label(template, (Transform)(object)grid, "Soul catalog note", 0f, -755f, 1400f, 62f, 20f); LogbookProgressTheme.Ink(heading, heading: true); LogbookProgressTheme.Ink(note); foreach (SoulData soul in souls) { GameObject val2 = new GameObject("Soul " + ((Object)soul).name, new Type[2] { typeof(RectTransform), typeof(Image) }); val2.transform.SetParent((Transform)(object)grid, false); Image component = val2.GetComponent<Image>(); ((Graphic)component).color = new Color(0.1f, 0.08f, 0.04f, 0.16f); ((Graphic)component).raycastTarget = true; GameUISelectableButton val3 = val2.AddComponent<GameUISelectableButton>(); ((Selectable)val3).targetGraphic = (Graphic)(object)component; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)3; val3.SetNavigation(navigation); TooltipProviderComponent item = LogbookProgressTheme.Tooltip(val2); GameObject val4 = new GameObject("Soul icon", new Type[2] { typeof(RectTransform), typeof(Image) }); val4.transform.SetParent(val2.transform, false); Image component2 = val4.GetComponent<Image>(); component2.sprite = ((RelicData)soul).GetIcon(); component2.preserveAspect = true; ((Graphic)component2).raycastTarget = false; RectTransform rectTransform = ((Graphic)component2).rectTransform; Vector2 val5 = (rectTransform.pivot = new Vector2(0f, 1f)); Vector2 anchorMin = (rectTransform.anchorMax = val5); rectTransform.anchorMin = anchorMin; rectTransform.anchoredPosition = new Vector2(12f, -16f); rectTransform.sizeDelta = new Vector2(60f, 60f); TMP_Text val8 = SoulSaviorChecklistPage.Label(template, val2.transform, "Soul name", 86f, -10f, 330f, 64f, 26f); val8.enableAutoSizing = true; val8.fontSizeMin = 18f; val8.fontSizeMax = 26f; TMP_Text val9 = SoulSaviorChecklistPage.Label(template, val2.transform, "Soul record", 86f, -77f, 330f, 52f, 20f); val9.enableAutoSizing = true; val9.fontSizeMin = 14f; val9.fontSizeMax = 20f; LogbookProgressTheme.Button(val3, val8, row: true); val8.alignment = (TextAlignmentOptions)4097; LogbookProgressTheme.Ink(val8, heading: true); LogbookProgressTheme.Ink(val9); LogbookProgressTheme.Status(((Component)val3).transform, complete: false); items.Add((soul, component2, val8, val9, val3, item)); } Resize(); } private void Resize() { //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_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_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_0093: 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_011f: 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) if ((Object)(object)grid == (Object)null || (Object)(object)layout == (Object)null) { return; } Rect rect = grid.rect; if (Math.Abs(((Rect)(ref rect)).width - measuredSoulWidth) < 0.5f) { return; } rect = grid.rect; measuredSoulWidth = ((Rect)(ref rect)).width; rect = grid.rect; float num = Mathf.Max(120f, (((Rect)(ref rect)).width - 32f) / 3f); layout.cellSize = new Vector2(num, 136f); foreach (var item in items) { item.Name.rectTransform.SetSizeWithCurrentAnchors((Axis)0, num - 98f); item.Record.rectTransform.SetSizeWithCurrentAnchors((Axis)0, num - 98f); } if ((Object)(object)heading != (Object)null) { RectTransform rectTransform = heading.rectTransform; rect = grid.rect; rectTransform.SetSizeWithCurrentAnchors((Axis)0, ((Rect)(ref rect)).width); } if ((Object)(object)note != (Object)null) { RectTransform rectTransform2 = note.rectTransform; rect = grid.rect; rectTransform2.SetSizeWithCurrentAnchors((Axis)0, ((Rect)(ref rect)).width); } } public override IGameUIComponent? GetDefaultGameUISelectable() { return (IGameUIComponent?)(object)items.FirstOrDefault().Button; } private void LateUpdate() { Resize(); } public override void Open() { //IL_020e: 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) //IL_0173: Unknown result type (might be due to invalid IL or missing references) ((CompendiumPage)this).Open(); if ((Object)(object)heading != (Object)null) { heading.text = "Soul Savior · " + SoulSaviorText.Get(13); } if ((Object)(object)note != (Object)null) { note.text = SoulSaviorText.Get(15); } try { using FileStream input = File.Open(LogbookSoulSavior.SavePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); SoulSaviorRecords soulSaviorRecords = SoulSaviorRecords.Read(input); foreach (var item in items) { item.Name.text = ((RelicData)item.Soul).GetName(); (int, int) tuple = soulSaviorRecords.Soul(SoulSaviorRecords.SoulKey(((Object)item.Soul).name)); item.Record.text = ((tuple.Item2 < 0) ? SoulSaviorText.Get(4) : SoulSaviorText.Get(14, tuple.Item1, "S" + tuple.Item2)); item.Tooltip.SetTooltipLocalized(((RelicData)item.Soul).GetName(), ((RelicData)item.Soul).GetDescription() + "\n\n" + item.Record.text, (TooltipDesignType)3, false); LogbookProgressTheme.Status(((Component)item.Button).transform, tuple.Item2 >= 0); ((Graphic)item.Icon).color = (Color)((tuple.Item2 < 0) ? new Color(0.55f, 0.55f, 0.55f, 0.75f) : Color.white); } } catch (Exception ex) { foreach (var item2 in items) { item2.Name.text = ((RelicData)item2.Soul).GetName(); item2.Record.text = "—"; ((Graphic)item2.Icon).color = Color.gray; LogbookProgressTheme.Status(((Component)item2.Button).transform, complete: false); item2.Tooltip.SetTooltipLocalized(((RelicData)item2.Soul).GetName(), SoulSaviorText.Get(2), (TooltipDesignType)3, false); } if ((Object)(object)note != (Object)null) { note.text = SoulSaviorText.Get(2); } Plugin.Logger.LogWarning((object)("[SoulSavior] Almas no disponibles: " + ex.Message)); } Resize(); } } public sealed class SoulSaviorSection : PaginatedCompendiumSection { internal readonly List<ChecklistPage> Pages = new List<ChecklistPage>(); internal readonly List<SoulData> SoulCatalog = new List<SoulData>(); internal CompendiumTab? Tab; private readonly List<ClassData> sidebarClasses = new List<ClassData>(); internal ClassData? SelectedClan; internal int PendingPage; internal int PendingPageCount = 1; private RectTransform? sidebar; private TMP_Text? sidebarBody; private RectTransform? sidebarDetail; private float measuredSidebarWidth = -1f; private float measuredSidebarHeight = -1f; private TMP_Text? sidebarLegend; private TMP_Text? sidebarCredit; private GameUISelectableButton? nextPending; private GameUISelectableButton? pendingFilter; private TMP_Text? pendingFilterLabel; internal bool ShowPendingOnly; private TMP_Text? nextPendingLabel; private TMP_Text? fontReference; private string sidebarLanguage = ""; private readonly SoulSaviorViewState viewState = new SoulSaviorViewState(); private bool compactNavigation; private GameUISelectableButton? soulsViewButton; private GameUISelectableButton? clansViewButton; private TMP_Text? soulsViewLabel; private TMP_Text? clansViewLabel; private List<ChecklistPage> CurrentPages { get { if (!compactNavigation) { return Pages.Where((ChecklistPage p) => p is SoulSaviorSoulsPage == viewState.ViewingSouls).ToList(); } return Pages; } } protected override int PageCount { get { if (!compactNavigation) { return viewState.PageCount; } return viewState.SoulPages + viewState.ClanPages; } } private void UpdateViewCounts() { viewState.UpdateCounts(IEnumerableUtility.Count<ChecklistPage>(Pages, (Func<ChecklistPage, bool>)((ChecklistPage p) => p is SoulSaviorSoulsPage)), IEnumerableUtility.Count<ChecklistPage>(Pages, (Func<ChecklistPage, bool>)((ChecklistPage p) => p is SoulSaviorChecklistPage))); } protected override int GetInitialPage() { UpdateViewCounts(); return viewState.DisplayIndex(compactNavigation); } private void SwitchView(bool souls) { UpdateViewCounts(); viewState.RememberDisplayed(base.currentPageIndex, compactNavigation); viewState.SwitchView(souls, viewState.InitialPage); base.currentPageIndex = viewState.DisplayIndex(compactNavigation); ((PaginatedCompendiumSection)this).RefreshPage(); ((PaginatedCompendiumSection)this).PageCountChangedSignal.Dispatch(); } public override bool ApplyScreenInput(CoreInputControlMapping mapping, IGameUIComponent? target, Controls control) { //IL_0041: 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) SoulSaviorButtonAction[] componentsInChildren = ((Component)this).GetComponentsInChildren<SoulSaviorButtonAction>(); foreach (SoulSaviorButtonAction soulSaviorButtonAction in componentsInChildren) { GameUISelectableButton component = ((Component)soulSaviorButtonAction).GetComponent<GameUISelectableButton>(); if ((Object)(object)component != (Object)null && component.TryTrigger(mapping, target, control, false, false)) { soulSaviorButtonAction.Activate(); return true; } } return ((CompendiumSection)this).ApplyScreenInput(mapping, target, control); } protected override void InitializeImpl() { } internal void Configure(CompendiumSectionChecklist source) { //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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown ((CompendiumSection)this)._section = SoulSaviorTabRegistration.SectionId; ((CompendiumSection)this).mainNavLayer = ((Component)this).gameObject.AddComponent<BaseNavigationLayer>(); ((Component)this).gameObject.AddComponent<SoulSaviorFocusRelay>(); base.pageCountLabel = (TextMeshProUGUI)AccessTools.Field(typeof(PaginatedCompendiumSection), "pageCountLabel").GetValue(source); base.pageCountKey = (string)AccessTools.Field(typeof(PaginatedCompendiumSection), "pageCountKey").GetValue(source); } protected override void RefreshPage() { UpdateViewCounts(); List<ChecklistPage> currentPages = CurrentPages; base.currentPageIndex = Mathf.Clamp(base.currentPageIndex, 0, Math.Max(0, currentPages.Count - 1)); ChecklistPage val = ((currentPages.Count == 0) ? null : currentPages[base.currentPageIndex]); viewState.RememberDisplayed(base.currentPageIndex, compactNavigation); ((PaginatedCompendiumSection)this).RefreshPage(); foreach (ChecklistPage page in Pages) { ((CompendiumPage)page).Toggle((Object)(object)page == (Object)(object)val); } ((CompendiumSection)this).mainNavLayer.SetDefaultGameSelectable(((CompendiumSection)this).GetDefaultGameUISelectable()); if ((Object)(object)fontReference != (Object)null) { TMP_Text[] componentsInChildren = ((Component)this).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val2 in componentsInChildren) { LogbookInkLabel component = ((Component)val2).GetComponent<LogbookInkLabel>(); bool flag = (Object)(object)val2.font != (Object)(object)fontReference.font; if (flag) { val2.font = fontReference.font; } if ((Object)(object)component == (Object)null || flag) { val2.fontSharedMaterial = fontReference.fontSharedMaterial; } if ((Object)(object)component != (Object)null && flag) { LogbookProgressTheme.Ink(val2, component.Heading); } } } RefreshSidebar(); RefreshTabTooltip(); } public override IGameUIComponent? GetDefaultGameUISelectable() { List<ChecklistPage> currentPages = CurrentPages; if (currentPages.Count != 0) { return ((CompendiumPage)currentPages[Mathf.Clamp(base.currentPageIndex, 0, currentPages.Count - 1)]).GetDefaultGameUISelectable(); } return null; } internal void SetIcon(SaveManager manager) { if (!((Object)(object)Tab == (Object)null)) { SoulData val = (from s in SoulCatalog.Concat(Resources.FindObjectsOfTypeAll<SoulData>()) where !((RelicData)s).IsHidden && (Object)(object)((RelicData)s).GetIcon() != (Object)null select s).OrderBy<SoulData, string>((SoulData s) => ((Object)s).name, StringComparer.Ordinal).FirstOrDefault(); (((Component)Tab).GetComponent<SoulSaviorTabIcon>() ?? ((Component)Tab).gameObject.AddComponent<SoulSaviorTabIcon>()).Configure(Tab, (val != null) ? ((RelicData)val).GetIcon() : null); RefreshTabTooltip(); } } private void RefreshTabTooltip() { CompendiumTab? tab = Tab; TooltipProviderComponent val = ((tab != null) ? ((Component)tab).GetComponentInChildren<TooltipProviderComponent>(true) : null); if ((Object)(object)val != (Object)null) { val.SetTooltipLocalized("Soul Savior", SoulSaviorText.Get(7), (TooltipDesignType)3, false); } } internal void BuildSidebar(List<ClassData> clans, TMP_Text labelTemplate) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0077: 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_0093: 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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_016c: 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_0196: 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_01ca: 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_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Expected O, but got Unknown //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Expected O, but got Unknown //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Expected O, but got Unknown //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Expected O, but got Unknown UpdateViewCounts(); sidebarClasses.AddRange(clans); fontReference = labelTemplate; GameObject val = new GameObject("Soul Savior overview", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(((Component)this).transform, false); sidebar = (RectTransform)val.transform; RectTransform? obj = sidebar; RectTransform? obj2 = sidebar; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); obj2.anchorMax = val2; obj.anchorMin = val2; sidebar.pivot = new Vector2(0f, 1f); sidebar.sizeDelta = new Vector2(340f, 720f); TMP_Text obj3 = SoulSaviorChecklistPage.Label(labelTemplate, (Transform)(object)sidebar, "Soul Savior overview title", 0f, 0f, 340f, 44f, 32f); obj3.text = "Soul Savior"; obj3.alignment = (TextAlignmentOptions)514; LogbookProgressTheme.Ink(obj3, heading: true); LogbookProgressTheme.Divider((Transform)(object)sidebar, -43f); GameObject val3 = new GameObject("Soul Savior detail frame", new Type[2] { typeof(RectTransform), typeof(Image) }); val3.transform.SetParent((Transform)(object)sidebar, false); sidebarDetail = (RectTransform)val3.transform; sidebarDetail.anchorMin = new Vector2(0f, 1f); sidebarDetail.anchorMax = Vector2.one; sidebarDetail.pivot = new Vector2(0.5f, 1f); sidebarDetail.anchoredPosition = new Vector2(0f, -98f); sidebarDetail.sizeDelta = new Vector2(0f, 440f); ((Graphic)val3.GetComponent<Image>()).color = new Color(0.66f, 0.48f, 0.25f, 0.1f); ((Graphic)val3.GetComponent<Image>()).raycastTarget = false; LogbookProgressTheme.Frame(val3.transform); soulsViewButton = SidebarButton(labelTemplate, "Souls view", -50f, (UnityAction)delegate { SwitchView(souls: true); }, out soulsViewLabel); clansViewButton = SidebarButton(labelTemplate, "Clans view", -50f, (UnityAction)delegate { SwitchView(souls: false); }, out clansViewLabel); LayoutViewButton(soulsViewButton, soulsViewLabel, 0f, 166f); LayoutViewButton(clansViewButton, clansViewLabel, 174f, 166f); sidebarBody = SoulSaviorChecklistPage.Label(labelTemplate, (Transform)(object)sidebar, "Soul Savior overview totals", 14f, -110f, 312f, 416f, 22f); LogbookProgressTheme.Ink(sidebarBody); sidebarBody.enableAutoSizing = true; sidebarBody.fontSizeMin = 14f; sidebarBody.fontSizeMax = 22f; ((Component)sidebarBody).gameObject.AddComponent<GameUISelectable>(); LogbookProgressTheme.Tooltip(((Component)sidebarBody).gameObject); ((Graphic)sidebarBody).raycastTarget = true; nextPending = SidebarButton(labelTemplate, "Next pending allies", -545f, (UnityAction)delegate { PendingPage = (PendingPage + 1) % PendingPageCount; RefreshSidebar(); }, out nextPendingLabel); pendingFilter = SidebarButton(labelTemplate, "Pending combination filter", -595f, (UnityAction)delegate { ShowPendingOnly = !ShowPendingOnly; ((PaginatedCompendiumSection)this).RefreshPage(); }, out pendingFilterLabel); sidebarLegend = SoulSaviorChecklistPage.Label(labelTemplate, (Transform)(object)sidebar, "Soul Savior overview legend", 0f, -460f, 340f, 170f, 20f); sidebarCredit = SoulSaviorChecklistPage.Label(labelTemplate, (Transform)(object)sidebar, "Soul Savior overview credit", 0f, -665f, 340f, 80f, 16f); LogbookProgressTheme.Ink(sidebarLegend); LogbookProgressTheme.Ink(sidebarCredit); LogbookProgressTheme.Divider(sidebarCredit.transform, 10f); } private GameUISelectableButton SidebarButton(TMP_Text template, string name, float y, UnityAction action, out TMP_Text caption) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0074: 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_007d: 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_0084: 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_00a6: 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_00e9: 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) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(Image), typeof(GameUISelectableButton) }); val.transform.SetParent((Transform)(object)sidebar, false); RectTransform val2 = (RectTransform)val.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 1f); val2.pivot = val3; Vector2 anchorMin = (val2.anchorMax = val3); val2.anchorMin = anchorMin; val2.anchoredPosition = new Vector2(0f, y); val2.sizeDelta = new Vector2(340f, 44f); GameUISelectableButton component = val.GetComponent<GameUISelectableButton>(); ((Selectable)component).targetGraphic = (Graphic)(object)val.GetComponent<Image>(); ((Selectable)component).targetGraphic.color = new Color(0.45f, 0.33f, 0.18f, 0.35f); Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)3; component.SetNavigation(navigation); val.AddComponent<SoulSaviorButtonAction>().Action = delegate { action.Invoke(); }; caption = SoulSaviorChecklistPage.Label(template, (Transform)(object)val2, name + " text", 8f, -5f, 324f, 34f, 22f); caption.enableAutoSizing = true; caption.fontSizeMin = 16f; caption.fontSizeMax = 22f; LogbookProgressTheme.Button(component, caption); return component; } internal void EnsureSelectedClan(List<ClassData> visible) { if ((Object)(object)SelectedClan == (Object)null || !visible.Contains(SelectedClan)) { SelectClan(visible.FirstOrDefault()); } } internal void SelectClan(ClassData? clan) { if (!((Object)(object)SelectedClan == (Object)(object)clan)) { SelectedClan = clan; PendingPage = 0; RefreshSidebar(); } } private void RefreshSidebar() { sidebarLanguage = LocalizationManager.CurrentLanguageCode; measuredSidebarWidth = -1f; if ((Object)(object)sidebarBody == (Object)null) { return; } if ((Object)(object)soulsViewLabel != (Object)null) { soulsViewLabel.text = SoulSaviorText.Get(13); } if ((Object)(object)clansViewLabel != (Object)null) { clansViewLabel.text = SoulSaviorText.Extra("Clans"); } if ((Object)(object)soulsViewButton != (Object)null) { ((Selectable)soulsViewButton).interactable = viewState.SoulPages > 0; } if ((Object)(object)clansViewButton != (Object)null) { ((Selectable)clansViewButton).interactable = viewState.ClanPages > 0; } if ((Object)(object)sidebarLegend != (Object)null) { sidebarLegend.text = SoulSaviorText.Get(viewState.ViewingSouls ? 15 : 11); } if ((Object)(object)sidebarCredit != (Object)null) { sidebarCredit.text = SoulSaviorText.Get(12); } LogbookProgressTheme.Select(soulsViewButton, viewState.ViewingSouls); LogbookProgressTheme.Select(clansViewButton, !viewState.ViewingSouls); LogbookProgressTheme.Select(pendingFilter, ShowPendingOnly); try { using FileStream input = File.Open(LogbookSoulSavior.SavePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); SoulSaviorRecords records = SoulSaviorRecords.Read(input); (int Won, int Possible, int ClansWon, int ClanCount, int Best) tuple = records.Overview(sidebarClasses.Select((ClassData c) => ((GameData)c).GetID())); int item = tuple.Won; int item2 = tuple.Possible; int item3 = tuple.ClansWon; int item4 = tuple.ClanCount; int item5 = tuple.Best; bool viewingSouls = viewState.ViewingSouls; if ((Object)(object)pendingFilter != (Object)null) { ((Component)pendingFilter).gameObject.SetActive(!viewingSouls); } if ((Object)(object)pendingFilterLabel != (Object)null) { pendingFilterLabel.text = SoulSaviorText.Extra(ShowPendingOnly ? "Missing" : "All"); } if (viewingSouls && (Object)(object)nextPending != (Object)null) { ((Component)nextPending).gameObject.SetActive(false); } int num = IEnumerableUtility.Count<SoulData>(SoulCatalog, (Func<SoulData, bool>)((SoulData s) => records.Soul(SoulSaviorRecords.SoulKey(((Object)s).name)).Difficulty >= 0)); sidebarBody.text = (viewingSouls ? (SoulSaviorText.Get(16) + "\n<size=38>" + num + " / " + SoulCatalog.Count + "</size>") : (SoulSaviorText.Get(8) + "\n<size=38>" + item + " / " + item2 + "</size>\n\n" + SoulSaviorText.Get(9) + "\n<size=34>" + item3 + " / " + item4 + "</size>\n\n" + SoulSaviorText.Get(10) + "\n<size=34>" + ((item5 < 0) ? "—" : ("S" + item5)) + "</size>")); if (!viewingSouls && (Object)(object)SelectedClan != (Object)null) { List<ClassData> list = sidebarClasses.Where((ClassData c) => ((GameData)c).GetID() != ((GameData)SelectedClan).GetID()).ToList(); List<ClassData> list2 = list.Where((ClassData c) => records.Best(((GameData)SelectedClan).GetID(), ((GameData)c).GetID()) < 0).ToList(); PendingPageCount = Math.Max(1, (list2.Count + 7) / 8); PendingPage = Mathf.Clamp(PendingPage, 0, PendingPageCount - 1); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("<color=#611C13><size=28>").Append(SelectedClan.GetTitle()).Append("</size></color>\n") .Append(list.Count - list2.Count) .Append(" / ") .Append(list.Count) .Append("\n\n"); for (int num2 = 0; num2 < 2; num2++) { CardData val = SelectedClan.GetChampionData(num2)?.championCardData; if (!((Object)(object)val == (Object)null)) { int num3 = records.ChampionBest(((GameData)SelectedClan).GetID(), num2, list.Select((ClassData c) => ((GameData)c).GetID())); stringBuilder.Append(val.GetName()).Append(": ").Append((num3 < 0) ? "—" : ("S" + num3)) .Append("\n"); } } stringBuilder.Append("\n").Append(SoulSaviorText.Extra("Pending")).Append(": ") .Append(list2.Count) .Append("\n"); foreach (ClassData item6 in list2.Skip(PendingPage * 8).Take(8)) { stringBuilder.Append("• ").Append(item6.GetTitle()).Append("\n"); } if (list2.Count == 0) { stringBuilder.Append(SoulSaviorText.Extra("Complete")); } sidebarBody.text = stringBuilder.ToString(); if ((Object)(object)nextPending != (Object)null) { ((Component)nextPending).gameObject.SetActive(PendingPageCount > 1); } if ((Object)(object)nextPendingLabel != (Object)null) { nextPendingLabel.text = SoulSaviorText.Extra("Next") + " (" + (PendingPage + 1) + "/" + PendingPageCount + ")"; } } TooltipProviderComponent component = ((Component)sidebarBody).GetComponent<TooltipProviderComponent>(); if ((Object)(object)component != (Object)null) { component.SetTooltipLocalized("Soul Savior", sidebarBody.text, (TooltipDesignType)3, false); } } catch (Exception ex) { sidebarBody.text = SoulSaviorText.Get(2); if ((Object)(object)nextPending != (Object)null) { ((Component)nextPending).gameObject.SetActive(false); } TooltipProviderComponent component2 = ((Component)sidebarBody).GetComponent<TooltipProviderComponent>(); if (component2 != null) { component2.SetTooltipLocalized("Soul Savior", sidebarBody.text, (TooltipDesignType)3, false); } Plugin.Logger.LogWarning((object)("[SoulSavior] Resumen no disponible: " + ex.Message)); } } private void LateUpdate() { //IL_0091: 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_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_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_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: 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_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: 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) //IL_027f: 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_02ce: 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_02db: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)sidebar == (Object)null || (Object)(object)((CompendiumSection)this).compendiumScreen == (Object)null) { return; } if (sidebarLanguage != LocalizationManager.CurrentLanguageCode) { ((PaginatedCompendiumSection)this).RefreshPage(); } Transform transform = ((Component)((CompendiumSection)this).compendiumScreen).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); GridLayoutGroup val2 = ((IEnumerable<GridLayoutGroup>)((Component)this).GetComponentsInChildren<GridLayoutGroup>()).FirstOrDefault((Func<GridLayoutGroup, bool>)((GridLayoutGroup g) => ((Object)g).name == "Soul Savior rows")); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return; } Vector3[] array = (Vector3[])(object)new Vector3[4]; ((RectTransform)((Component)val2).transform).GetWorldCorners(array); float x = ((Transform)val).InverseTransformPoint(array[0]).x; Rect rect = val.rect; float num = x - ((Rect)(ref rect)).xMin - 48f; int num2; if (!(num < 220f)) { rect = val.rect; num2 = ((((Rect)(ref rect)).height < 680f) ? 1 : 0); } else { num2 = 1; } bool flag = (byte)num2 != 0; if (compactNavigation != flag) { viewState.RememberDisplayed(base.currentPageIndex, compactNavigation); compactNavigation = flag; base.currentPageIndex = viewState.DisplayIndex(compactNavigation); ((PaginatedCompendiumSection)this).RefreshPage(); ((PaginatedCompendiumSection)this).PageCountChangedSignal.Dispatch(); } ((Component)sidebar).gameObject.SetActive(!flag); if (flag) { return; } float num3 = Mathf.Min(360f, num); RectTransform? obj = sidebar; rect = val.rect; float num4 = ((Rect)(ref rect)).xMin + 24f; rect = val.rect; ((Transform)obj).position = ((Transform)val).TransformPoint(new Vector3(num4, ((Rect)(ref rect)).yMax - 150f, 0f)); rect = val.rect; float num5 = Mathf.Clamp(((Rect)(ref rect)).height - 560f, 140f, 500f); if (Math.Abs(num3 - measuredSidebarWidth) < 0.5f && Math.Abs(num5 - measuredSidebarHeight) < 0.5f) { return; } measuredSidebarWidth = num3; measuredSidebarHeight = num5; sidebar.SetSizeWithCurrentAnchors((Axis)0, num3); float num6 = -110f - num5; if ((Object)(object)sidebarDetail != (Object)null) { sidebarDetail.SetSizeWithCurrentAnchors((Axis)1, num5); } if ((Object)(object)sidebarBody != (Object)null) { sidebarBody.rectTransform.SetSizeWithCurrentAnchors((Axis)1, num5 - 24f); } if ((Object)(object)nextPending != (Object)null) { RectTransform val3 = (RectTransform)((Component)nextPending).transform; val3.anchoredPosition = new Vector2(0f, num6); val3.SetSizeWithCurrentAnchors((Axis)0, num3); if (((Component)nextPending).gameObject.activeSelf) { num6 -= 50f; } } if ((Object)(object)pendingFilter != (Object)null) { RectTransform val4 = (RectTransform)((Component)pendingFilter).transform; val4.anchoredPosition = new Vector2(0f, num6); val4.SetSizeWithCurrentAnchors((Axis)0, num3); if (((Component)pendingFilter).gameObject.activeSelf) { num6 -= 50f; } } if ((Object)(object)pendingFilterLabel != (Object)null) { pendingFilterLabel.rectTransform.SetSizeWithCurrentAnchors((Axis)0, num3 - 16f); } if ((Object)(object)nextPendingLabel != (Object)null) { nextPendingLabel.rectTransform.SetSizeWithCurrentAnchors((Axis)0, num3 - 16f); } if ((Object)(object)sidebarLegend != (Object)null) { sidebarLegend.rectTransform.anchoredPosition = new Vector2(0f, num6); sidebarLegend.rectTransform.SetSizeWithCurrentAnchors((Axis)1, 100f); sidebarLegend.enableAutoSizing = true; sidebarLegend.fontSizeMin = 14f; sidebarLegend.fontSizeMax = 20f; } if ((Object)(object)sidebarCredit != (Object)null) { sidebarCredit.rectTransform.anchoredPosition = new Vector2(0f, num6 - 114f); sidebarCredit.rectTransform.SetSizeWithCurrentAnchors((Axis)1, 50f); } TMP_Text[] componentsInChildren = ((Component)sidebar).GetComponentsInChildren<TMP_Text>(); foreach (TMP_Text val5 in componentsInChildren) { val5.rectTransform.SetSizeWithCurrentAnchors((Axis)0, ((Object)(object)((Component)val5).GetComponentInParent<GameUISelectableButton>() != (Object)null) ? (num3 - 16f) : (((Object)(object)val5 == (Object)(object)sidebarBody) ? (num3 - 28f) : num3)); } float num8 = (num3 - 8f) / 2f; LayoutViewButton(soulsViewButton, soulsViewLabel, 0f, num8); LayoutViewButton(clansViewButton, clansViewLabel, num8 + 8f, num8); } private static void LayoutViewButton(GameUISelectableButton? button, TMP_Text? label, float x, float width) { //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_0035: 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) if (!((Object)(object)button == (Object)null) && !((Object)(object)label == (Object)null)) { RectTransform val = (RectTransform)((Component)button).transform; val.anchoredPosition = new Vector2(x, -56f); val.sizeDelta = new Vector2(width, 36f); label.rectTransform.sizeDelta = new Vector2(width - 16f, 26f); label.fontSizeMax = 20f; label.fontSizeMin = 12f; } } } [HarmonyPatch] public static class SoulSaviorTabRegistration { internal static Section SectionId = (Section)8; [HarmonyPatch(typeof(CompendiumScreen), "Awake")] [HarmonyPostfix] private static void Register(CompendiumScreen __instance) { //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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00c4: 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: Expected O, but got Unknown //IL_00da: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0183: 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_01a5: Unknown result type (might be due to invalid IL or missing references) if (!LogbookSoulSavior.Enabled) { return; } Dictionary<Section, CompendiumSection> dictionary = LogbookSoulSavior.Field<Dictionary<Section, CompendiumSection>>(__instance, "pagesBySection"); Dictionary<Section, CompendiumTab> dictionary2 = LogbookSoulSavior.Field<Dictionary<Section, CompendiumTab>>(__instance, "tabsBySection"); if (dictionary == null || dictionary2 == null || (Object)(object)((Component)__instance).GetComponentInChildren<SoulSaviorSection>(true) != (Object)null) { return; } int i; for (i = 8; dictionary.ContainsKey((Section)i) || dictionary2.ContainsKey((Section)i); i++) { } int num = i; SectionId = (Section)num; Section val = (Section)num; CompendiumSection obj = dictionary[(Section)1]; CompendiumSectionChecklist val2 = (CompendiumSectionChecklist)(object)((obj is CompendiumSectionChecklist) ? obj : null); if (!((Object)(object)val2 == (Object)null) && dictionary2.TryGetValue((Section)5, out var value)) { GameObject val3 = new GameObject("Soul Savior section", new Type[1] { typeof(RectTransform) }); val3.SetActive(false); val3.transform.SetParent(((Component)val2).transform.parent, false); LogbookSoulSavior.CopyRect((RectTransform)((Component)val2).transform, (RectTransform)val3.transform); SoulSaviorSection soulSaviorSection = val3.AddComponent<SoulSaviorSection>(); soulSaviorSection.Configure(val2); List<CompendiumTab> originals = dictionary2.Values.OrderBy((CompendiumTab t) => ((Component)t).transform.GetSiblingIndex()).ToList(); CompendiumTab val4 = Object.Instantiate<CompendiumTab>(value, ((Component)value).transform.parent, false); ((Object)val4).name = "Soul Savior tab"; AccessTools.Field(typeof(CompendiumTab), "section").SetValue(val4, val); ((Component)val4).transform.SetAsLastSibling(); ((Component)val4).gameObject.SetActive(true); soulSaviorSection.Tab = val4; dictionary.Add(val, (CompendiumSection)(object)soulSaviorSection); dictionary2.Add(val, val4); LogbookSoulSavior.Field<List<Section>>(__instance, "sectionOrder")?.Add(val); List<PaginatedCompendiumSection> list = new List<PaginatedCompendiumSection>(LogbookSoulSavior.Field<PaginatedCompendiumSection[]>(__instance, "paginatedSections")); list.Add((PaginatedCompendiumSection)(object)soulSaviorSection); AccessTools.Field(typeof(CompendiumScreen), "paginatedSections").SetValue(__instance, list.ToArray()); Action action = (Action)Delegate.CreateDelegate(typeof(Action), __instance, AccessTools.Method(typeof(CompendiumScreen), "RefreshPageTurnZones", (Type[])null, (Type[])null)); ((PaginatedCompendiumSection)soulSaviorSection).PageCountChangedSignal.AddListener(action); SoulSaviorTabPlacement soulSaviorTabPlacement = ((Component)val4).gameObject.AddComponent<SoulSaviorTabPlacement>(); soulSaviorTabPlacement.Originals = originals; soulSaviorTabPlacement.Added = val4; Plugin.Logger.LogInfo((object)"[SoulSavior] Pestaña independiente registrada."); } } } public sealed class SoulSaviorTabIcon : MonoBehaviour { private Image[] images = Array.Empty<Image>(); private readonly Dictionary<Image, bool> trophyStates = new Dictionary<Image, bool>(); private Sprite? soulIcon; private bool logged; internal void Configure(CompendiumTab tab, Sprite? soulIcon) { images = ((Component)tab).GetComponentsInChildren<Image>(true); this.soulIcon = soulIcon; Apply(); } private void OnEnable() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown Canvas.willRenderCanvases += new WillRenderCanvases(Apply); } private void OnDisable() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown Canvas.willRenderCanvases -= new WillRenderCanvases(Apply); } private void LateUpdate() { Apply(); } private void Apply() { Image[] array = images; foreach (Image val in array) { if (!((Object)(object)val == (Object)null)) { string text = (((Object)(object)val.sprite != (Object)null) ? ((Object)val.sprite).name : ""); if (text == "CMP_Icon_Trophy_Normal") { trophyStates[val] = false; } else if (text == "CMP_Icon_Trophy_Selected") { trophyStates[val] = true; } if (trophyStates.TryGetValue(val, out var value) && !((Object)(object)soulIcon == (Object)null)) { val.overrideSprite = null; val.sprite = soulIcon; val.type = (Type)0; val.preserveAspect = true; float num = (value ? 48f : 42f); ((Graphic)val).rectTransform.SetSizeWithCurrentAnchors((Axis)0, num); ((Graphic)val).rectTransform.SetSizeWithCurrentAnchors((Axis)1, num); } } } if (!logged && images.Length != 0) { logged = true; Plugin.Logger.LogInfo((object)("[SoulSavior] Iconos sustituidos por sprite: " + trophyStates.Count + "; alma=" + (((Object)(object)soulIcon != (Object)null) ? ((Object)soulIcon).name : "sin icono") + "; gráficos=" + string.Join("; ", images.Select((Image val2) => ((Object)val2).name + "/" + (((Object)(object)val2.sprite != (Object)null) ? ((Object)val2.sprite).name : "sin sprite"))))); } } } public sealed class SoulSaviorTabPlacement : MonoBehaviour { internal List<CompendiumTab> Originals = new List<CompendiumTab>(); internal CompendiumTab? Added; private readonly List<RectTransform> tabs = new List<RectTransform>(); private readonly List<RectTransform> graphics = new List<RectTransform>(); private RectTransform? parent; private float left; private float right; private float baseline; private float measuredWidth; private bool ready; private bool warned; private void OnEnable() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown Canvas.willRenderCanvases += new WillRenderCanvases(Apply); } private void OnDisable() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown Canvas.willRenderCanvases -= new WillRenderCanvases(Apply); } private static RectTransform VisibleAnchor(CompendiumTab tab) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown Graphic targetGraphic = ((Selectable)tab.Button).targetGraphic; Image val = ((Component)tab.Button).GetComponentsInChildren<Image>(true).Where(delegate(Image i) { //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_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_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_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) if ((Object)(object)i.sprite != (Object)null && ((Behaviour)i).enabled && ((Component)i).gameObject.activeInHierarchy) { Rect rect = ((Graphic)i).rectTransform.rect; if (((Rect)(ref rect)).width > 1f) { rect = ((Graphic)i).rectTransform.rect; if (((Rect)(ref rect)).height > 1f) { rect = ((Graphic)i).rectTransform.rect; if (((Rect)(ref rect)).width < 300f) { rect = ((Graphic)i).rectTransform.rect; return ((Rect)(ref rect)).height < 300f; } } } } return false; }).OrderByDescending(delegate(Image i) { //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_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) Rect rect = ((Graphic)i).rectTransform.rect; float width = ((Rect)(ref rect)).width; rect = ((Graphic)i).rectTransform.rect; return width * ((Rect)(ref rect)).height; }) .FirstOrDefault(); if (!((Object)(object)val != (Object)null)) { if (!((Object)(object)targetGraphic != (Object)null)) { return (RectTransform)((Component)tab.Button).transform; } return targetGraphic.rectTransform; } return ((Graphic)val).rectTransform; } private static Vector3 Center(RectTransform graphic) { //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_0014: Unknown result type (might be due to invalid IL or missing references) Rect rect = graphic.rect; return ((Transform)graphic).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).center)); } internal static bool ValidSpan(float start, float end, int count) { if (count > 1) { return end - start > (float)(count - 1) * 1f; } return false; } private bool Capture() { //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_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_0102: 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_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_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_0182: 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) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Expected O, but got Unknown //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Expected O, but got Unknown if ((Object)(object)Added == (Object)null || Originals.Count < 2 || !((Component)Added).gameObject.activeInHierarchy) { return false; } ref RectTransform? reference = ref parent; Transform obj = ((Component)Added).transform.parent; reference = (RectTransform?)(object)((obj is RectTransform) ? obj : null); if (!((Object)(object)parent == (Object)null)) { Rect rect = parent.rect; if (!(((Rect)(ref rect)).width <= 1f)) { var list = (from t in Originals where (Object)(object)t != (Object)null select new { Tab = t, Graphic = VisibleAnchor(t) } into t orderby ((Transform)parent).InverseTransformPoint(Center(t.Graphic)).x select t).ToList(); if (list.Count < 2) { return false; } Vector3 val = ((Transform)parent).InverseTransformPoint(Center(list[0].Graphic)); Vector3 val2 = ((Transform)parent).InverseTransformPoint(Center(list[list.Count - 1].Graphic)); if (!ValidSpan(val.x, val2.x, list.Count)) { if (!warned) { warned = true; Plugin.Logger.LogWarning((object)("[SoulSavior] Esperando geometría válida del encabezado: " + string.Join("; ", list.Select(t => { //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_004a: 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) string[] obj2 = new string[7] { ((Object)t.Tab).name, " / ", ((Object)t.Graphic).name, " x=", ((Transform)parent).InverseTransformPoint(Center(t.Graphic)).x.ToString(), " ancho=", null }; Rect rect2 = t.Graphic.rect; obj2[6] = ((Rect)(ref rect2)).width.ToString(); return string.Concat(obj2); })))); } return false; } left = val.x; right = val2.x; baseline = val.y; rect = parent.rect; measuredWidth = ((Rect)(ref rect)).width; ContentSizeFitter component = ((Component)parent).GetComponent<ContentSizeFitter>(); if ((Object)(object)component != (Object)null) { component.horizontalFit = (FitMode)0; } foreach (var item in list) { tabs.Add((RectTransform)((Component)item.Tab).transform); graphics.Add(item.Graphic); } tabs.Add((RectTransform)((Component)Added).transform); graphics.Add(VisibleAnchor(Added)); foreach (RectTransform tab in tabs) { (((Component)tab).GetComponent<LayoutElement>() ?? ((Component)tab).gameObject.AddComponent<LayoutElement>()).ignoreLayout = true; } ready = true; Plugin.Logger.LogInfo((object)("[SoulSavior] Ocho gráficos visibles entre " + left + " y " + right + "; separación " + (right - left) / (float)(tabs.Count - 1))); return true; } } return false; } internal static float CenterX(float start, float end, int index, int count) { return start + (end - start) * (float)index / (float)Mathf.Max(1, count - 1); } private void LateUpdate() { Apply(); } private void Apply() { //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_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_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_00e6: 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_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) if ((!ready && !Capture()) || (Object)(object)parent == (Object)null || (Object)(object)Added == (Object)null) { return; } Rect rect = parent.rect; if (((Rect)(ref rect)).width <= 1f) { return; } float num; if (!(measuredWidth > 1f)) { num = 1f; } else { rect = parent.rect; num = ((Rect)(ref rect)).width / measuredWidth; } float num2 = num; for (int i = 0; i < tabs.Count; i++) { RectTransform val = tabs[i]; RectTransform val2 = graphics[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null)) { Vector3 val3 = ((Transform)parent).TransformPoint(new Vector3(CenterX(left, right, i, tabs.Count) * num2, baseline, 0f)); ((Transform)val).position = ((Transform)val).position + (val3 - Center(val2)); } } } } public sealed class LogbookInkLabel : MonoBehaviour { internal bool Heading; private Material? ownedMaterial; internal void ApplyMaterial(TMP_Text text) { //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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ownedMaterial != (Object)null && (Object)(object)text.fontSharedMaterial == (Object)(object)ownedMaterial) { return; } Material val = ownedMaterial; ownedMaterial = new Material(text.fontSharedMaterial) { name = ((Object)text.fontSharedMaterial).name + " (Logbook ink)", hideFlags = (HideFlags)52 }; string[] array = new string[9] { "_FaceDilate", "_OutlineWidth", "_OutlineSoftness", "_WeightNormal", "_WeightBold", "_UnderlayDilate", "_UnderlaySoftness", "_UnderlayOffsetX", "_UnderlayOffsetY" }; foreach (string text2 in array) { if (ownedMaterial.HasProperty(text2)) { ownedMaterial.SetFloat(text2, 0f); } } array = new string[4] { "OUTLINE_ON", "UNDERLAY_ON", "UNDERLAY_INNER", "GLOW_ON" }; foreach (string text3 in array) { ownedMaterial.DisableKeyword(text3); } if (ownedMaterial.HasProperty("_FaceColor")) { ownedMaterial.SetColor("_FaceColor", Color.white); } text.fontSharedMaterial = ownedMaterial; text.UpdateMeshPadding(); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } private void OnDestroy() { if ((Object)(object)ownedMaterial != (Object)null) { Object.Destroy((Object)(object)ownedMaterial); } } } internal static class LogbookProgressTheme { private static readonly Color InkColor = new Color(0.23f, 0.13f, 0.07f, 1f); internal static void Ink(TMP_Text text, bool heading = false) { //IL_003b: 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) LogbookInkLabel obj = ((Component)text).GetComponent<LogbookInkLabel>() ?? ((Component)text).gameObject.AddComponent<LogbookInkLabel>(); obj.Heading = heading; ((Graphic)text).color = (Color)(heading ? new Color(0.38f, 0.09f, 0.07f, 1f) : InkColor); text.fontStyle = (FontStyles)0; text.fontWeight = (FontWeight)400; obj.ApplyMaterial(text); text.characterSpacing = 2f; text.wordSpacing = 3f; text.lineSpacing = 8f; text.paragraphSpacing = 4f; } private static Image Graphic(Transform parent, string name, Color color, Vector2 min, Vector2 max, Vector2 offsetMin, Vector2 offsetMax) { //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_0040: 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_0066: 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_0075: 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) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(Image), typeof(LayoutElement) }); val.transform.SetParent(parent, false); val.GetComponent<LayoutElement>().ignoreLayout = true; Image component = val.GetComponent<Image>(); ((Graphic)component).color = color; ((Graphic)component).raycastTarget = false; RectTransform rectTransform = ((Graphic)component).rectTransform; rectTransform.anchorMin = min; rectTransform.anchorMax = max; rectTransform.offsetMin = offsetMin; rectTransform.offsetMax = offsetMax; return component; } internal static void Frame(Transform parent) { //IL_0021: 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_0040: 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_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_007f: 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_009f: 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_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_00c3: 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_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_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_011d: 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_0140: 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) Color color = default(Color); ((Color)(ref color))..ctor(0.48f, 0.34f, 0.18f, 0.9f); Graphic(parent, "Book frame top", color, new Vector2(0f, 1f), Vector2.one, new Vector2(2f, -2f), new Vector2(-2f, 0f)); Graphic(parent, "Book frame bottom", color, Vector2.zero, new Vector2(1f, 0f), new Vector2(2f, 0f), new Vector2(-2f, 2f)); Graphic(parent, "Book frame left", color, Vector2.zero, new Vector2(0f, 1f), Vector2.zero, new Vector2(2f, 0f)); Graphic(parent, "Book frame right", color, new Vector2(1f, 0f), Vector2.one, new Vector2(-2f, 0f), Vector2.zero); Graphic(parent, "Book frame glint", new Color(0.94f, 0.82f, 0.55f, 0.5f), new Vector2(0f, 1f), Vector2.one, new Vector2(3f, -3f), new Vector2(-3f, -2f)); } internal static void Button(GameUISelectableButton button, TMP_Text caption, bool row = false) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) Frame(((Component)button).transform); caption.alignment = (TextAlignmentOptions)(row ? 4097 : 514); if (row) { Ink(caption); } else { ((Graphic)caption).color = new Color(1f, 0.94f, 0.79f, 1f); caption.fontSizeMax = 22f; } Select(button, selected: false, row); } internal static void Select(GameUISelectableButton? button, bool selected, bool row = false) { //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_0066: 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_0079: 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_00a3: 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_00e3: 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_003f: 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) if (!((Object)(object)button == (Object)null)) { Color normalColor = (row ? new Color(0.76f, 0.63f, 0.4f, 0.22f) : (selected ? new Color(0.57f, 0.32f, 0.09f, 0.96f) : new Color(0.34f, 0.17f, 0.11f, 0.94f))); ((Selectable)button).targetGraphic.color = Color.white; ColorBlock colors = ((Selectable)button).colors; ((ColorBlock)(ref colors)).normalColor = normalColor; ((ColorBlock)(ref colors)).highlightedColor = new Color(0.67f, 0.47f, 0.2f, 1f); ((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).highlightedColor; ((ColorBlock)(ref colors)).pressedColor = new Color(0.4f, 0.23f, 0.1f, 1f); ((ColorBlock)(ref colors)).disabledColor = new Color(0.48f, 0.41f, 0.31f, 0.4f); ((ColorBlock)(ref colors)).fadeDuration = 0.12f; ((Selectable)button).transition = (Transition)1; ((Selectable)button).colors = colors; } } internal static TooltipProviderComponent Tooltip(GameObject obj) { if (obj.GetComponent<IGameUIComponent>() == null) { obj.AddComponent<GameUISelectable>(); } return obj.GetComponent<TooltipProviderComponent>() ?? obj.AddComponent<TooltipProviderComponent>(); } internal static void Status(Transform parent, bool complete) { //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_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_0055: 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_0076: Unknown result type (might be due to invalid IL or missing references) Transform val = parent.Find("Progress status"); ((Graphic)(((Object)(object)val == (Object)null) ? ((object)Graphic(parent, "Progress status", Color.white, Vector2.zero, new Vector2(0f, 1f), new Vector2(3f, 4f), new Vector2(7f, -4f))) : ((object)((Component)val).GetComponent<Image>()))).color = (complete ? new Color(0.68f, 0.43f, 0.08f, 0.95f) : new Color(0.48f, 0.34f, 0.18f, 0.28f)); } internal static RectTransform Divider(Transform parent, float y) { //IL_004b: 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_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_0085: 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_00bb: 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_00e8: Unknown result type (might be due to invalid IL or missing references) Image val = ((IEnumerable<Image>)((Component)parent.root).GetComponentsInChildren<Image>(true)).FirstOrDefault((Func<Image, bool>)((Image i) => (Object)(object)i.sprite != (Object)null && ((Object)i).name.IndexOf("divider", StringComparison.OrdinalIgnoreCase) >= 0)); Image val2 = Graphic(parent, "Progress book divider", new Color(0.44f, 0.26f, 0.12f, 0.65f), new Vector2(0f, 1f), Vector2.one, Vector2.zero, Vector2.zero); RectTransform rectTransform = ((Graphic)val2).rectTransform; rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.sizeDelta = new Vector2(0f, ((Object)(object)val == (Object)null) ? 2f : 18f); rectTransform.anchoredPosition = new Vector2(0f, y); if ((Object)(object)val != (Object)null) { val2.sprite = val.sprite; val2.type = val.type; ((Graphic)val2).color = ((Graphic)val).color; } return rectTransform; } } public sealed class SoulSaviorButtonAction : MonoBehaviour { internal Action? Action; private int lastFrame = -1; internal void Activate() { if (lastFrame != Time.frameCount && ((Behaviour)this).isActiveAndEnabled) { lastFrame = Time.frameCount; Action?.Invoke(); } } } internal sealed class SoulSaviorViewState { private int soulPage; private int clanPage; internal bool ViewingSouls { get; private set; } = true; internal int SoulPages { get; private set; } internal int ClanPages { get; private set; } internal int PageCount { get { if (!ViewingSouls) { return ClanPages; } return SoulPages; } } internal int InitialPage { get { if (!ViewingSouls) { return clanPage; } return soulPage; } } internal int DisplayIndex(bool compact) { return InitialPage + ((compact && !ViewingSouls) ? SoulPages : 0); } internal void RememberDisplayed(int index, bool compact) { if (!compact) { Remember(index); return; } index = Clamp(index, SoulPages + ClanPages); ViewingSouls = index < SoulPages || ClanPages == 0; Remember(ViewingSouls ? index : (index - SoulPages)); } private static int Clamp(int page, int count) { return Math.Max(0, Math.Min(page, count - 1)); } internal void UpdateCounts(int souls, int clans) { SoulPages = Math.Max(0, souls); ClanPages = Math.Max(0, clans); soulPage = Clamp(soulPage, SoulPages); clanPage = Clamp(clanPage, ClanPages); if (PageCount == 0 && SoulPages + ClanPages > 0) { ViewingSouls = !ViewingSouls; } } internal void Remember(int page) { if (ViewingSouls) { soulPage = Clamp(page, SoulPages); } else { clanPage = Clamp(page, ClanPages); } } internal int SwitchView(bool souls, int outgoingPage) { Remember(outgoingPage); if ((souls ? SoulPages : ClanPages) > 0) { ViewingSouls = souls; } return InitialPage; } } [DataContract] public sealed class SoulSaviorRecord { [DataMember(Name = "classID")] public string? ClassId; [DataMember(Name = "subclassID")] public string? SubclassId; [DataMember(Name = "championIndex")] public int? ChampionIndex; [DataMember(Name = "highestGameLevel")] public int? HighestGameLevel; } [DataContract] public sealed class SoulSaviorSoulRecord { [DataMember(Name = "name")] public string? Name; [DataMember(Name = "tier")] public int? Tier; [DataMember(Name = "highestGameLevel")] public int? HighestGameLevel; } [DataContract] public sealed class SoulSaviorSave { [DataMember(Name = "soulSaviorClassWins")] public List<SoulSaviorRecord>? Wins; [DataMember(Name = "soulWins")] public List<SoulSaviorSoulRecord>? Souls; } public sealed class SoulSaviorRecords { private readonly