using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Norntastic.Auras; using Norntastic.Brawler; using Norntastic.Combat; using Norntastic.Commands; using Norntastic.Config; using Norntastic.Content; using Norntastic.Core; using Norntastic.Creatures; using Norntastic.Data; using Norntastic.Effects; using Norntastic.Effects.Handlers; using Norntastic.Emotes; using Norntastic.Kitchen; using Norntastic.Martial; using Norntastic.Progression; using Norntastic.Safety; using Norntastic.Styles; using Norntastic.UI; using Norntastic.Util; 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("Norntastic")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.7.0.0")] [assembly: AssemblyInformationalVersion("0.7.0")] [assembly: AssemblyProduct("Norntastic")] [assembly: AssemblyTitle("Norntastic")] [assembly: AssemblyVersion("0.7.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Norntastic { [BepInPlugin("dafini.norntastic", "Norntastic", "0.14.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "dafini.norntastic"; public const string PluginName = "Norntastic"; public const string PluginVersion = "0.14.2"; private Harmony _harmony; private const float PatchMapDelaySeconds = 8f; internal static string ConfigDirectory { get; private set; } private void Awake() { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) Log.Init(((BaseUnityPlugin)this).Logger); ConfigDirectory = Path.Combine(Paths.ConfigPath, "Norntastic"); ModConfig.Bind(((BaseUnityPlugin)this).Config); Log.Warn("Built without ServerSync: settings are local only and will not be pushed from the server. Fine for testing, not for the group."); PerkPanelInput.Bind(((BaseUnityPlugin)this).Config); BrawlerInput.Bind(((BaseUnityPlugin)this).Config); OffhandPicker.Bind(((BaseUnityPlugin)this).Config); MartialInput.Bind(((BaseUnityPlugin)this).Config); AbilityInput.Bind(((BaseUnityPlugin)this).Config); PerkDatabase.Load(ConfigDirectory); CustomSkills.Register(); Handlers.RegisterAll(); BrawlerModifiers.DeclareImplemented(); PerkEffectDriver.Init(); EffectAggregator.ReportCoverage(); DatabaseGuard.Arm(); Norntastic.Emotes.Emotes.Init(ConfigDirectory); DerivedSeal.Load(ConfigDirectory); Bakery.Arm(); PieCounter.Arm(); Pies.Arm(); Crops.Arm(); Arsenal.Arm(); Pantry.Arm(); SmokeHook.Arm(); Fryer.Arm(); Stations.Arm(); PerkPanel.Init(); PerkConsole.Register(); _harmony = new Harmony("dafini.norntastic"); _harmony.PatchAll(); ((MonoBehaviour)this).Invoke("WritePatchMap", 8f); Log.Info("Norntastic 0.14.2 loaded. " + $"Perk interval {PerkDatabase.PointInterval}, " + "prestige " + (ModConfig.PrestigeEnabled.Value ? "on" : "off") + " " + $"(cap {ModConfig.PrestigeCap.Value}), " + "free respec " + (ModConfig.FreeRespec.Value ? "on" : "off") + ". " + $"Press {PerkPanelInput.Hotkey.Value} for the perk panel."); } private void WritePatchMap() { string text = PatchMap.WriteToDisk(ConfigDirectory, "dafini.norntastic"); if (text != null) { Log.Info("Patch map written to " + text + ". nsg.patches reads the same thing live."); } } private void OnDestroy() { PerkPanel.Shutdown(); PerkEffectDriver.Forget(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } } namespace Norntastic.Util { internal static class Equipment { private struct Snapshot { internal bool Unarmored; internal bool EmptyHanded; internal bool Shield; internal bool Torch; internal bool TwoHanded; internal bool OneHanded; internal bool MatchedSet; internal bool Trinket; } private const float CacheSeconds = 0.2f; private static Snapshot _snap; private static float _takenAt = -1f; internal static void Invalidate() { _takenAt = -1f; } private static Snapshot Current(Player player) { float time = Time.time; if (_takenAt >= 0f && time - _takenAt < 0.2f) { return _snap; } _snap = Compute(player); _takenAt = time; return _snap; } internal static bool IsUnarmored(Player player) { if ((Object)(object)player != (Object)null) { return Current(player).Unarmored; } return false; } internal static bool IsEmptyHanded(Player player) { if ((Object)(object)player != (Object)null) { return Current(player).EmptyHanded; } return false; } internal static bool HasShield(Player player) { if ((Object)(object)player != (Object)null) { return Current(player).Shield; } return false; } internal static bool HasTorch(Player player) { if ((Object)(object)player != (Object)null) { return Current(player).Torch; } return false; } internal static bool IsTwoHanded(Player player) { if ((Object)(object)player != (Object)null) { return Current(player).TwoHanded; } return false; } internal static bool IsOneHanded(Player player) { if ((Object)(object)player != (Object)null) { return Current(player).OneHanded; } return false; } internal static bool IsFullMatchedSet(Player player) { if ((Object)(object)player != (Object)null) { return Current(player).MatchedSet; } return false; } internal static bool HasTrinket(Player player) { if ((Object)(object)player != (Object)null) { return Current(player).Trinket; } return false; } private static bool TrainsUnarmed(ItemData item) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 if (item?.m_shared != null) { return (int)item.m_shared.m_skillType == 11; } return false; } private static Snapshot Compute(Player player) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected I4, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Invalid comparison between Unknown and I4 //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Invalid comparison between Unknown and I4 Snapshot result = new Snapshot { Unarmored = true, EmptyHanded = true }; Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return result; } List allItems = inventory.GetAllItems(); if (allItems == null) { return result; } string helmet = null; string chest = null; string legs = null; foreach (ItemData item in allItems) { if (item == null || !item.m_equipped || item.m_shared == null) { continue; } ItemType itemType = item.m_shared.m_itemType; if (IsArmorSlot(itemType)) { result.Unarmored = false; } if (IsHeldSlot(itemType) && !TrainsUnarmed(item)) { result.EmptyHanded = false; } switch (itemType - 3) { default: if ((int)itemType != 22) { if ((int)itemType == 24) { result.Trinket = true; } break; } goto case 1; case 2: result.Shield = true; break; case 12: result.Torch = true; break; case 3: helmet = item.m_shared.m_name; break; case 4: chest = item.m_shared.m_name; break; case 8: legs = item.m_shared.m_name; break; case 1: case 11: result.TwoHanded = true; break; case 0: result.OneHanded = true; break; case 5: case 6: case 7: case 9: case 10: break; } } result.MatchedSet = Matched(helmet, chest, legs); return result; } private static bool Matched(string helmet, string chest, string legs) { if (helmet == null || chest == null || legs == null) { return false; } string text = Letters(helmet); string text2 = Letters(chest); string text3 = Letters(legs); if (text.Length < 4 || text2.Length < 4 || text3.Length < 4) { return false; } for (int num = Math.Min(text.Length, Math.Min(text2.Length, text3.Length)); num >= 4; num--) { for (int i = 0; i + num <= text.Length; i++) { string value = text.Substring(i, num); if (text2.IndexOf(value, StringComparison.Ordinal) >= 0 && text3.IndexOf(value, StringComparison.Ordinal) >= 0) { return true; } } } return false; } private static string Letters(string raw) { char[] array = new char[raw.Length]; int length = 0; foreach (char c in raw) { if (char.IsLetter(c)) { array[length++] = char.ToLowerInvariant(c); } } return new string(array, 0, length); } private static bool IsHeldSlot(ItemType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected I4, but got Unknown if (type - 3 > 2) { switch (type - 14) { case 0: case 1: case 5: case 6: case 8: break; default: return false; } } return true; } private static bool IsArmorSlot(ItemType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 if (type - 6 <= 1 || (int)type == 11 || (int)type == 17) { return true; } return false; } } internal static class Json { internal static object Parse(string text) { int i = 0; object result = ParseValue(text, ref i); SkipWhitespace(text, ref i); if (i < text.Length) { throw new FormatException("Trailing content at offset " + i); } return result; } internal static Dictionary Obj(object o) { return o as Dictionary; } internal static List Arr(object o) { return o as List; } internal static object Get(object o, string key) { if (!(o is Dictionary dictionary)) { return null; } if (!dictionary.TryGetValue(key, out var value)) { return null; } return value; } internal static string Str(object o, string key, string fallback = "") { return (Get(o, key) as string) ?? fallback; } internal static float Num(object o, string key, float fallback = 0f) { if (!(Get(o, key) is double num)) { return fallback; } return (float)num; } internal static int Int(object o, string key, int fallback = 0) { if (!(Get(o, key) is double a)) { return fallback; } return (int)Math.Round(a); } internal static bool Bool(object o, string key, bool fallback = false) { object obj = Get(o, key); if (obj is bool) { return (bool)obj; } return fallback; } internal static List StrList(object o, string key) { List list = new List(); if (!(Get(o, key) is List list2)) { return list; } foreach (object item2 in list2) { if (item2 is string item) { list.Add(item); } } return list; } private static void SkipWhitespace(string s, ref int i) { while (i < s.Length && (s[i] == ' ' || s[i] == '\t' || s[i] == '\n' || s[i] == '\r')) { i++; } } private static object ParseValue(string s, ref int i) { SkipWhitespace(s, ref i); if (i >= s.Length) { throw new FormatException("Unexpected end of input"); } switch (s[i]) { case '{': return ParseObject(s, ref i); case '[': return ParseArray(s, ref i); case '"': return ParseString(s, ref i); case 't': Expect(s, ref i, "true"); return true; case 'f': Expect(s, ref i, "false"); return false; case 'n': Expect(s, ref i, "null"); return null; default: return ParseNumber(s, ref i); } } private static void Expect(string s, ref int i, string literal) { if (i + literal.Length > s.Length || string.CompareOrdinal(s, i, literal, 0, literal.Length) != 0) { throw new FormatException("Expected '" + literal + "' at offset " + i); } i += literal.Length; } private static Dictionary ParseObject(string s, ref int i) { Dictionary dictionary = new Dictionary(); i++; SkipWhitespace(s, ref i); if (i < s.Length && s[i] == '}') { i++; return dictionary; } while (true) { SkipWhitespace(s, ref i); if (i >= s.Length || s[i] != '"') { throw new FormatException("Expected object key at offset " + i); } string key = ParseString(s, ref i); SkipWhitespace(s, ref i); if (i >= s.Length || s[i] != ':') { throw new FormatException("Expected ':' at offset " + i); } i++; dictionary[key] = ParseValue(s, ref i); SkipWhitespace(s, ref i); if (i >= s.Length) { throw new FormatException("Unterminated object"); } if (s[i] != ',') { break; } i++; } if (s[i] == '}') { i++; return dictionary; } throw new FormatException("Expected ',' or '}' at offset " + i); } private static List ParseArray(string s, ref int i) { List list = new List(); i++; SkipWhitespace(s, ref i); if (i < s.Length && s[i] == ']') { i++; return list; } while (true) { list.Add(ParseValue(s, ref i)); SkipWhitespace(s, ref i); if (i >= s.Length) { throw new FormatException("Unterminated array"); } if (s[i] != ',') { break; } i++; } if (s[i] == ']') { i++; return list; } throw new FormatException("Expected ',' or ']' at offset " + i); } private static string ParseString(string s, ref int i) { StringBuilder stringBuilder = new StringBuilder(); i++; while (i < s.Length) { char c = s[i++]; switch (c) { case '"': return stringBuilder.ToString(); default: stringBuilder.Append(c); continue; case '\\': break; } if (i >= s.Length) { break; } char c2 = s[i++]; switch (c2) { case '"': stringBuilder.Append('"'); break; case '\\': stringBuilder.Append('\\'); break; case '/': stringBuilder.Append('/'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'n': stringBuilder.Append('\n'); break; case 'r': stringBuilder.Append('\r'); break; case 't': stringBuilder.Append('\t'); break; case 'u': if (i + 4 > s.Length) { throw new FormatException("Bad \\u escape"); } stringBuilder.Append((char)Convert.ToInt32(s.Substring(i, 4), 16)); i += 4; break; default: throw new FormatException("Unknown escape '\\" + c2 + "'"); } } throw new FormatException("Unterminated string"); } private static object ParseNumber(string s, ref int i) { int num = i; if (i < s.Length && (s[i] == '-' || s[i] == '+')) { i++; } while (i < s.Length && (char.IsDigit(s[i]) || s[i] == '.' || s[i] == 'e' || s[i] == 'E' || s[i] == '+' || s[i] == '-')) { i++; } string text = s.Substring(num, i - num); if (double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return result; } throw new FormatException("Bad number '" + text + "' at offset " + num); } } internal static class Log { private static ManualLogSource _log; internal static void Init(ManualLogSource source) { _log = source; } internal static void Info(string msg) { ManualLogSource log = _log; if (log != null) { log.LogInfo((object)msg); } } internal static void Warn(string msg) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)msg); } } internal static void Error(string msg) { ManualLogSource log = _log; if (log != null) { log.LogError((object)msg); } } internal static void Debug(string msg) { if (ModConfig.Verbose != null && ModConfig.Verbose.Value) { ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("[dbg] " + msg)); } } } } internal static class PatchMap { internal sealed class Entry { internal string Type = "?"; internal string Method = "?"; internal readonly List Owners = new List(); internal int Prefixes; internal int Postfixes; internal int Transpilers; internal int Finalizers; internal readonly List Detail = new List(); internal string Where => Type + "." + Method; internal bool Shared => Owners.Count > 1; internal string Counts => $"pre {Prefixes} post {Postfixes} trans {Transpilers} fin {Finalizers}"; internal bool OwnedBy(string id) { if (id != null) { return Owners.Contains(id); } return false; } } internal const string FileName = "patchmap.txt"; internal static List Collect() { List list = new List(); IEnumerable allPatchedMethods; try { allPatchedMethods = Harmony.GetAllPatchedMethods(); } catch (Exception ex) { Log.Warn("Patch map unavailable: " + ex.Message); return list; } if (allPatchedMethods == null) { return list; } foreach (MethodBase item in allPatchedMethods) { if (item == null) { continue; } Patches patchInfo; try { patchInfo = Harmony.GetPatchInfo(item); } catch { continue; } if (patchInfo == null) { continue; } Entry entry = new Entry { Type = ((item.DeclaringType != null) ? item.DeclaringType.Name : "?"), Method = (item.Name ?? "?") }; if (patchInfo.Owners != null) { foreach (string owner in patchInfo.Owners) { if (!string.IsNullOrEmpty(owner) && !entry.Owners.Contains(owner)) { entry.Owners.Add(owner); } } } entry.Prefixes = Count(patchInfo.Prefixes); entry.Postfixes = Count(patchInfo.Postfixes); entry.Transpilers = Count(patchInfo.Transpilers); entry.Finalizers = Count(patchInfo.Finalizers); AddDetail(patchInfo, entry); list.Add(entry); } list.Sort((Entry a, Entry b) => string.Compare(a.Where, b.Where, StringComparison.Ordinal)); return list; } private static int Count(ICollection patches) { return patches?.Count ?? 0; } private static void AddDetail(Patches info, Entry entry) { try { Describe(info.Prefixes, "prefix", entry); Describe(info.Postfixes, "postfix", entry); Describe(info.Transpilers, "TRANSPILER", entry); Describe(info.Finalizers, "finalizer", entry); } catch { entry.Detail.Clear(); } } private static void Describe(IEnumerable patches, string kind, Entry entry) { if (patches == null) { return; } foreach (Patch patch in patches) { if (patch != null) { entry.Detail.Add(patch.owner + " (" + kind + ")"); } } } internal static List Report(string ourId, string filter) { List list = new List(); List list2 = Collect(); if (list2.Count == 0) { list.Add("No patches visible. Either Harmony has not run yet or it is not the Harmony this mod is talking to."); return list; } string text = (string.IsNullOrEmpty(filter) ? null : filter.ToLowerInvariant()); List list3 = new List(); foreach (Entry item in list2) { if (text == null || Matches(item, text)) { list3.Add(item); } } int num = 0; foreach (Entry item2 in list2) { if (item2.Shared && item2.OwnedBy(ourId)) { num++; } } list.Add($"--- patch map --- {list2.Count} patched method(s), " + $"{num} of them shared with Norntastic" + ((text == null) ? "" : $" filter '{filter}' -> {list3.Count}")); if (list3.Count == 0) { list.Add("Nothing matches '" + filter + "'. Nobody has patched it, which for a crash in that method means the cause is somewhere else."); return list; } foreach (Entry item3 in list3) { string text2 = (item3.Shared ? ">>" : " "); string text3 = (item3.OwnedBy(ourId) ? " [us]" : ""); list.Add(text2 + " " + item3.Where + text3); list.Add(" " + item3.Counts); if (item3.Detail.Count > 0) { foreach (string item4 in item3.Detail) { list.Add(" " + item4); } continue; } foreach (string owner in item3.Owners) { list.Add(" " + owner); } } return list; } private static bool Matches(Entry entry, string needle) { if (entry.Where.ToLowerInvariant().Contains(needle)) { return true; } foreach (string owner in entry.Owners) { if (owner != null && owner.ToLowerInvariant().Contains(needle)) { return true; } } return false; } internal static string WriteToDisk(string directory, string ourId) { try { if (string.IsNullOrEmpty(directory)) { return null; } Directory.CreateDirectory(directory); string text = Path.Combine(directory, "patchmap.txt"); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Norntastic patch map"); stringBuilder.AppendLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); stringBuilder.AppendLine(); stringBuilder.AppendLine("Every method Harmony has patched this session and which mod did it."); stringBuilder.AppendLine(">> marks a method more than one mod touches. [us] marks ours."); stringBuilder.AppendLine("A crash inside a patched method names neither the mod nor the patch;"); stringBuilder.AppendLine("this file is how you get from the method in the stack trace to a GUID."); stringBuilder.AppendLine(); foreach (string item in Report(ourId, null)) { stringBuilder.AppendLine(item); } File.WriteAllText(text, stringBuilder.ToString()); return text; } catch (Exception ex) { Log.Warn("Could not write the patch map: " + ex.Message); return null; } } } internal static class SkillKeys { private static readonly Dictionary ToKey; private static readonly Dictionary FromKey; private static readonly Dictionary Custom; static SkillKeys() { //IL_0176: Unknown result type (might be due to invalid IL or missing references) ToKey = new Dictionary { { (SkillType)1, "swords" }, { (SkillType)2, "knives" }, { (SkillType)3, "clubs" }, { (SkillType)4, "polearms" }, { (SkillType)5, "spears" }, { (SkillType)6, "blocking" }, { (SkillType)7, "axes" }, { (SkillType)8, "bows" }, { (SkillType)9, "elemental" }, { (SkillType)10, "bloodmagic" }, { (SkillType)11, "unarmed" }, { (SkillType)12, "pickaxes" }, { (SkillType)13, "woodcutting" }, { (SkillType)14, "crossbows" }, { (SkillType)100, "jump" }, { (SkillType)101, "sneak" }, { (SkillType)102, "run" }, { (SkillType)103, "swim" }, { (SkillType)104, "fishing" }, { (SkillType)105, "cooking" }, { (SkillType)106, "farming" }, { (SkillType)107, "crafting" }, { (SkillType)108, "dodge" }, { (SkillType)110, "riding" } }; FromKey = new Dictionary(StringComparer.OrdinalIgnoreCase); Custom = new Dictionary(); foreach (KeyValuePair item in ToKey) { FromKey[item.Value] = item.Key; } } internal static bool IsRealSkill(SkillType t) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 if ((int)t != 0) { return (int)t != 999; } return false; } internal static string Key(SkillType t) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected I4, but got Unknown if (ToKey.TryGetValue(t, out var value)) { return value; } if (Custom.TryGetValue(t, out var value2)) { return value2; } return "skill_" + (int)t; } internal static bool TryResolve(string key, out SkillType type) { return FromKey.TryGetValue(key, out type); } internal static void RegisterCustomKey(SkillType type, string key) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) Custom[type] = key; FromKey[key] = type; } internal static void RegisterCustom(SkillType type, string readableName) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!ToKey.ContainsKey(type)) { string text = "x_" + Sanitise(readableName); Custom[type] = text; FromKey[text] = type; } } private static string Sanitise(string s) { if (string.IsNullOrEmpty(s)) { return "unknown"; } StringBuilder stringBuilder = new StringBuilder(s.Length); string text = s.Trim().ToLowerInvariant(); foreach (char c in text) { if (char.IsLetterOrDigit(c)) { stringBuilder.Append(c); } else if (c == ' ' || c == '_' || c == '-') { stringBuilder.Append('_'); } } if (stringBuilder.Length != 0) { return stringBuilder.ToString(); } return "unknown"; } } } namespace Norntastic.UI { internal static class Favourites { private static readonly List Pinned = new List(); private static bool _loaded; internal static IReadOnlyList All { get { Load(); return Pinned; } } internal static int Count { get { Load(); return Pinned.Count; } } internal static bool Has(string key) { Load(); if (!string.IsNullOrEmpty(key)) { return Pinned.Contains(key); } return false; } internal static bool Toggle(string key) { Load(); if (string.IsNullOrEmpty(key)) { return false; } if (Pinned.Contains(key)) { Pinned.Remove(key); } else { Pinned.Add(key); } Save(); return Pinned.Contains(key); } private static void Load() { if (_loaded) { return; } _loaded = true; Pinned.Clear(); string text = ModConfig.FavouriteTrees?.Value; if (string.IsNullOrEmpty(text)) { return; } string[] array = text.Split(','); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length > 0 && !Pinned.Contains(text2) && PerkDatabase.Trees.ContainsKey(text2)) { Pinned.Add(text2); } } } private static void Save() { if (ModConfig.FavouriteTrees != null) { ModConfig.FavouriteTrees.Value = string.Join(",", Pinned.ToArray()); } } internal static void ResetForTests() { Pinned.Clear(); _loaded = false; } } internal static class Palette { internal static readonly Color Ground = Color32.op_Implicit(new Color32((byte)11, (byte)14, (byte)18, (byte)242)); internal static readonly Color Panel = Color32.op_Implicit(new Color32((byte)20, (byte)26, (byte)33, byte.MaxValue)); internal static readonly Color Panel2 = Color32.op_Implicit(new Color32((byte)27, (byte)35, (byte)44, byte.MaxValue)); internal static readonly Color Panel3 = Color32.op_Implicit(new Color32((byte)34, (byte)44, (byte)55, byte.MaxValue)); internal static readonly Color Line = Color32.op_Implicit(new Color32((byte)42, (byte)54, (byte)65, byte.MaxValue)); internal static readonly Color Ink = Color32.op_Implicit(new Color32((byte)216, (byte)224, (byte)232, byte.MaxValue)); internal static readonly Color Ink2 = Color32.op_Implicit(new Color32((byte)168, (byte)182, (byte)194, byte.MaxValue)); internal static readonly Color InkDim = Color32.op_Implicit(new Color32((byte)117, (byte)133, (byte)143, byte.MaxValue)); internal static readonly Color Ember = Color32.op_Implicit(new Color32((byte)222, (byte)116, (byte)48, byte.MaxValue)); internal static readonly Color Gold = Color32.op_Implicit(new Color32((byte)233, (byte)180, (byte)95, byte.MaxValue)); internal static readonly Color Frost = Color32.op_Implicit(new Color32((byte)111, (byte)169, (byte)196, byte.MaxValue)); internal static readonly Color Blood = Color32.op_Implicit(new Color32((byte)168, (byte)65, (byte)63, byte.MaxValue)); internal static Color NodeFill(NodeVisualState state) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_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_006b: Unknown result type (might be due to invalid IL or missing references) return (Color)(state switch { NodeVisualState.Max => Color32.op_Implicit(new Color32((byte)168, (byte)114, (byte)31, byte.MaxValue)), NodeVisualState.Taken => Color32.op_Implicit(new Color32((byte)200, (byte)98, (byte)31, byte.MaxValue)), NodeVisualState.Held => Color32.op_Implicit(new Color32((byte)200, (byte)98, (byte)31, byte.MaxValue)), NodeVisualState.Available => Panel3, _ => Panel2, }); } internal static Color NodeBorder(NodeVisualState state) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_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) return (Color)(state switch { NodeVisualState.Max => Gold, NodeVisualState.Taken => Ember, NodeVisualState.Held => Gold, NodeVisualState.Available => Frost, _ => Line, }); } internal static Color NodeLabel(NodeVisualState state) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) switch (state) { case NodeVisualState.Taken: case NodeVisualState.Max: case NodeVisualState.Held: return Gold; case NodeVisualState.Available: return Ink; default: return new Color(InkDim.r, InkDim.g, InkDim.b, 0.5f); } } } internal enum NodeVisualState { Locked, Available, Taken, Max, Held } internal sealed class PerkDetailPane { private readonly RectTransform _root; private readonly Text _title; private readonly Text _meta; private readonly Text _flavour; private readonly Text _ranks; private readonly Text _gate; private readonly Button _buy; private readonly Text _buyLabel; private readonly Button _refund; private readonly Text _refundLabel; private PerkNode _node; internal event Action Changed; internal PerkDetailPane(Transform parent) { //IL_0017: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00d6: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: 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_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Expected O, but got Unknown //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Expected O, but got Unknown _root = UiFactory.Rect("detail", parent, new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(-330f, 12f), new Vector2(-12f, -12f)); UiFactory.Fill(_root, Palette.Panel); _title = UiFactory.Label("title", (Transform)(object)_root, "", 22, Palette.Ink, (TextAnchor)0, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(16f, -50f), new Vector2(-16f, -14f)); _meta = UiFactory.Label("meta", (Transform)(object)_root, "", 11, Palette.InkDim, (TextAnchor)0, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(16f, -70f), new Vector2(-16f, -50f)); _flavour = UiFactory.Label("flavour", (Transform)(object)_root, "", 13, Palette.Ink2, (TextAnchor)0, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(18f, -118f), new Vector2(-16f, -74f)); _flavour.fontStyle = (FontStyle)2; _ranks = UiFactory.Label("ranks", (Transform)(object)_root, "", 13, Palette.Ink2, (TextAnchor)0, new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(16f, 108f), new Vector2(-16f, -122f)); _gate = UiFactory.Label("gate", (Transform)(object)_root, "", 12, Palette.Blood, (TextAnchor)6, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(16f, 60f), new Vector2(-16f, 104f)); RectTransform val = UiFactory.Rect("buy", (Transform)(object)_root, new Vector2(0f, 0f), new Vector2(0.62f, 0f), new Vector2(16f, 16f), new Vector2(-4f, 52f)); _buy = UiFactory.Clickable(val, Color32.op_Implicit(new Color32((byte)90, (byte)46, (byte)20, byte.MaxValue))); _buyLabel = UiFactory.Label("t", (Transform)(object)val, "TAKE PERK", 13, Palette.Gold, (TextAnchor)4, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); ((UnityEvent)_buy.onClick).AddListener(new UnityAction(Buy)); RectTransform val2 = UiFactory.Rect("refund", (Transform)(object)_root, new Vector2(0.62f, 0f), new Vector2(1f, 0f), new Vector2(4f, 16f), new Vector2(-16f, 52f)); _refund = UiFactory.Clickable(val2, Palette.Panel3); _refundLabel = UiFactory.Label("t", (Transform)(object)val2, "REFUND", 13, Palette.InkDim, (TextAnchor)4, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); ((UnityEvent)_refund.onClick).AddListener(new UnityAction(Refund)); } internal void Show(PerkNode node) { _node = node; Refresh(); } private void Buy() { if (_node != null) { if (PointMath.TryBuy(PerkState.Current, _node, out var message)) { Toast(message); } Refresh(); this.Changed?.Invoke(); } } private void Refund() { if (_node != null) { if (Respec.TryRefund(PerkState.Current, _node, out var message)) { Toast(message); } Refresh(); this.Changed?.Invoke(); } } private static void Toast(string message) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)1, message, 0, (Sprite)null, false); } } internal void Refresh() { //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) if (_node == null) { _title.text = ""; _meta.text = "Pick a perk."; Text flavour = _flavour; Text ranks = _ranks; string text = (_gate.text = ""); string text3 = (ranks.text = text); flavour.text = text3; Button buy = _buy; bool interactable = (((Selectable)_refund).interactable = false); ((Selectable)buy).interactable = interactable; return; } PerkState current = PerkState.Current; PerkTree perkTree = PerkDatabase.Tree(_node.TreeKey); int rank = current.GetRank(_node.Id); NodeVisualState nodeVisualState = PerkTreeView.Visual(current, _node); _title.text = _node.Name; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append((perkTree != null) ? perkTree.Name : _node.TreeKey); stringBuilder.Append(" lv ").Append(_node.RequiresLevel).Append("+"); stringBuilder.Append(" ").Append(rank).Append(" / ") .Append(_node.MaxRank) .Append(" ranks"); if (_node.Requires.Count > 0 && perkTree != null) { List list = new List(); foreach (string require in _node.Requires) { PerkNode perkNode = perkTree.Node(require); if (perkNode != null) { list.Add(perkNode.Name); } } if (list.Count > 0) { stringBuilder.Append(" after ").Append(string.Join(", ", list.ToArray())); } } _meta.text = stringBuilder.ToString(); _flavour.text = (string.IsNullOrEmpty(_node.Flavour) ? "" : ("“" + _node.Flavour + "”")); StringBuilder stringBuilder2 = new StringBuilder(); for (int i = 1; i <= _node.MaxRank; i++) { bool flag2 = i <= rank; stringBuilder2.Append(flag2 ? "" : "").Append(i).Append(" ") .Append(flag2 ? "" : "") .Append(_node.RankText(i)) .Append("\n\n"); } _ranks.supportRichText = true; _ranks.text = stringBuilder2.ToString(); List list2 = new List(); if (nodeVisualState == NodeVisualState.Held) { list2.Add("Held. Bought above this level and still applying — gates are checked at purchase only."); } if (_node.IsExclusive) { PerkNode perkNode2 = PointMath.ExclusiveBlocker(current, perkTree, _node); list2.Add((perkNode2 == null) ? "An exclusive fork. Taking it locks the others until refunded." : ("Locked: you committed to " + perkNode2.Name + ".")); } if (!_node.IsImplemented) { list2.Add("Not yet implemented: " + _node.PendingNote + ""); } else if (_node.IsPartial) { list2.Add("Partly implemented. What is missing: " + _node.PendingNote + ""); } else if (!string.IsNullOrEmpty(_node.ImplementedNote)) { list2.Add("" + _node.ImplementedNote + ""); } string reason; PointMath.Gate gate = PointMath.CanBuy(current, _node, out reason); if (gate != PointMath.Gate.Ok && nodeVisualState != NodeVisualState.Held) { list2.Add("" + reason + ""); } _gate.supportRichText = true; _gate.text = string.Join("\n", list2.ToArray()); ((Selectable)_buy).interactable = gate == PointMath.Gate.Ok; _buyLabel.text = ((rank > 0) ? "NEXT RANK" : "TAKE PERK"); ((Graphic)_buyLabel).color = (((Selectable)_buy).interactable ? Palette.Gold : Palette.InkDim); bool flag3 = ModConfig.FreeRespec != null && ModConfig.FreeRespec.Value; ((Selectable)_refund).interactable = rank > 0 && (flag3 || current.RespecPoints > 0); _refundLabel.text = (flag3 ? "REFUND" : "REFUND · 1 RP"); } } internal static class PerkPanel { [CompilerGenerated] private static class <>O { public static Action <0>__Build; public static Action <1>__OnAllocationChanged; public static UnityAction <2>__Close; public static Action <3>__ShowTree; public static UnityAction <4>__DoPrestige; public static Action <5>__RefreshAll; } private static GameObject _root; private static RectTransform _rootRect; private static SkillRail _rail; private static TreeSubRail _subRail; private static PerkTreeView _treeView; private static PerkDetailPane _detail; private static Text _ledger; private static Text _treeTitle; private static Text _treeBlurb; private static Text _treeFormula; private static Text _empty; private static Button _prestige; private static Text _prestigeLabel; private static PerkTree _current; private static float _sizedForScale; private static Vector2 _sizedForScreen; private const float HeaderHeight = 70f; internal static bool IsOpen { get { if ((Object)(object)_root != (Object)null) { return _root.activeSelf; } return false; } } internal static void Init() { GUIManager.OnCustomGUIAvailable += Build; PerkEvents.AllocationChanged += OnAllocationChanged; Log.Debug("Perk panel subscribed to OnCustomGUIAvailable."); } internal static void Shutdown() { GUIManager.OnCustomGUIAvailable -= Build; PerkEvents.AllocationChanged -= OnAllocationChanged; Destroy(); } private static void Destroy() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _rootRect = null; _rail = null; _subRail = null; _treeView = null; _detail = null; _current = null; } internal static void Toggle() { if (IsOpen) { Close(); } else { Open(); } } internal static void Open() { if ((Object)(object)_root == (Object)null) { Build(); } if ((Object)(object)_root == (Object)null) { Log.Warn("Perk panel could not be built - custom GUI is not available yet."); return; } _root.SetActive(true); GUIManager.BlockInput(true); ApplyScale(); _rail.Build(); if (_current == null || !_rail.TrySelect(_current.Key)) { _current = null; _rail.SelectFirst(); } ((Behaviour)_empty).enabled = _rail.IsEmpty; RefreshAll(); } internal static void Close() { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } GUIManager.BlockInput(false); } private static void ApplyScale() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_rootRect == (Object)null)) { float num = Mathf.Clamp(ModConfig.UiScale.Value, 0.8f, 2.5f); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor((float)Screen.width, (float)Screen.height); ((Transform)_rootRect).localScale = new Vector3(num, num, 1f); _rootRect.sizeDelta = val / num; _sizedForScale = num; _sizedForScreen = val; } } private static void Build() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0093: 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_00b1: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Expected O, but got Unknown //IL_0289: 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_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_0494: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04c1: Unknown result type (might be due to invalid IL or missing references) //IL_04d0: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_050e: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_053b: Unknown result type (might be due to invalid IL or missing references) //IL_0554: Unknown result type (might be due to invalid IL or missing references) //IL_0559: Unknown result type (might be due to invalid IL or missing references) //IL_0576: Unknown result type (might be due to invalid IL or missing references) //IL_057c: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_0586: Unknown result type (might be due to invalid IL or missing references) //IL_058b: Unknown result type (might be due to invalid IL or missing references) //IL_05cb: Unknown result type (might be due to invalid IL or missing references) //IL_05d0: Unknown result type (might be due to invalid IL or missing references) //IL_05df: Unknown result type (might be due to invalid IL or missing references) //IL_05ee: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05b9: Unknown result type (might be due to invalid IL or missing references) //IL_05bf: Expected O, but got Unknown //IL_063d: Unknown result type (might be due to invalid IL or missing references) //IL_064d: Unknown result type (might be due to invalid IL or missing references) //IL_065c: Unknown result type (might be due to invalid IL or missing references) //IL_066b: Unknown result type (might be due to invalid IL or missing references) //IL_067a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)GUIManager.CustomGUIFront == (Object)null)) { Destroy(); Transform transform = GUIManager.CustomGUIFront.transform; _rootRect = UiFactory.Point("NorntasticPanel", transform, new Vector2(0.5f, 0.5f), new Vector2(1920f, 1080f)); _root = ((Component)_rootRect).gameObject; ((Graphic)UiFactory.Fill(_rootRect, Palette.Ground)).raycastTarget = true; RectTransform parent = UiFactory.Rect("header", (Transform)(object)_rootRect, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(16f, -70f), new Vector2(-16f, 0f)); UiFactory.Label("brand", (Transform)(object)parent, "NORNTASTIC SKILL GROWTH", 26, Palette.Ember, (TextAnchor)3, new Vector2(0f, 0f), new Vector2(0.38f, 1f), new Vector2(6f, 0f), Vector2.zero); _ledger = UiFactory.Label("ledger", (Transform)(object)parent, "", 15, Palette.Ink, (TextAnchor)5, new Vector2(0.38f, 0f), new Vector2(1f, 1f), Vector2.zero, new Vector2(-104f, 0f)); RectTransform val = UiFactory.Rect("close", (Transform)(object)parent, new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(-92f, 14f), new Vector2(-6f, -14f)); Button obj = UiFactory.Clickable(val, Palette.Panel3); UiFactory.Label("t", (Transform)(object)val, "CLOSE", 14, Palette.Ink2, (TextAnchor)4, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); ButtonClickedEvent onClick = obj.onClick; object obj2 = <>O.<2>__Close; if (obj2 == null) { UnityAction val2 = Close; <>O.<2>__Close = val2; obj2 = (object)val2; } ((UnityEvent)onClick).AddListener((UnityAction)obj2); _rail = new SkillRail((Transform)(object)UiFactory.Rect("railhost", (Transform)(object)_rootRect, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, -128f), new Vector2(0f, -70f))); _rail.TreeSelected += ShowTree; _subRail = new TreeSubRail((Transform)(object)UiFactory.Rect("subrailhost", (Transform)(object)_rootRect, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, -162f), new Vector2(0f, -128f))); _subRail.TreeSelected += ShowTree; RectTransform parent2 = UiFactory.Rect("body", (Transform)(object)_rootRect, Vector2.zero, Vector2.one, new Vector2(0f, 0f), new Vector2(0f, -162f)); _empty = UiFactory.Label("empty", (Transform)(object)parent2, "No skill has been levelled yet.\nSwing something, and its tree appears here.", 18, Palette.InkDim, (TextAnchor)4, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); ((Behaviour)_empty).enabled = false; RectTransform parent3 = UiFactory.Rect("stage", (Transform)(object)parent2, Vector2.zero, Vector2.one, new Vector2(14f, 12f), new Vector2(-394f, -12f)); RectTransform val3 = UiFactory.Rect("stagehead", (Transform)(object)parent3, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, -116f), new Vector2(0f, 0f)); UiFactory.Fill(val3, Palette.Panel); _treeTitle = UiFactory.Label("title", (Transform)(object)val3, "", 26, Palette.Ink, (TextAnchor)0, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(18f, -46f), new Vector2(-176f, -10f)); _treeBlurb = UiFactory.Label("blurb", (Transform)(object)val3, "", 14, Palette.Ink2, (TextAnchor)0, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(18f, -92f), new Vector2(-176f, -48f)); _treeFormula = UiFactory.Label("formula", (Transform)(object)val3, "", 12, Palette.InkDim, (TextAnchor)6, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(18f, 6f), new Vector2(-18f, 26f)); RectTransform val4 = UiFactory.Rect("prestige", (Transform)(object)val3, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-166f, -48f), new Vector2(-14f, -14f)); _prestige = UiFactory.Clickable(val4, Color32.op_Implicit(new Color32((byte)70, (byte)28, (byte)27, byte.MaxValue))); _prestigeLabel = UiFactory.Label("t", (Transform)(object)val4, "PRESTIGE", 13, Palette.Blood, (TextAnchor)4, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); ButtonClickedEvent onClick2 = _prestige.onClick; object obj3 = <>O.<4>__DoPrestige; if (obj3 == null) { UnityAction val5 = DoPrestige; <>O.<4>__DoPrestige = val5; obj3 = (object)val5; } ((UnityEvent)onClick2).AddListener((UnityAction)obj3); RectTransform parent4 = UiFactory.Rect("graph", (Transform)(object)parent3, Vector2.zero, Vector2.one, new Vector2(0f, 0f), new Vector2(0f, -120f)); _treeView = new PerkTreeView((Transform)(object)parent4); _treeView.NodeSelected += delegate(PerkNode node) { _detail.Show(node); }; UiFactory.Label("hint", (Transform)(object)parent4, "drag to pan · wheel to zoom · click a connector to travel · right-click a tab to pin it", 12, Palette.InkDim, (TextAnchor)6, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(22f, 18f), new Vector2(-22f, 38f)); _detail = new PerkDetailPane((Transform)(object)parent2); _detail.Changed += RefreshAll; ApplyScale(); _root.SetActive(false); Log.Debug("Perk panel built."); } } internal static void Tick() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (!IsOpen || (Object)(object)_rootRect == (Object)null) { return; } if (!Mathf.Approximately(_sizedForScale, ModConfig.UiScale.Value) || _sizedForScreen.x != (float)Screen.width || _sizedForScreen.y != (float)Screen.height) { ApplyScale(); } Vector2 val = Vector2.op_Implicit(Input.mousePosition); float axis = Input.GetAxis("Mouse ScrollWheel"); if (_rail != null && _rail.ContainsScreenPoint(val)) { if (!Mathf.Approximately(axis, 0f)) { _rail.Wheel(axis); } _treeView?.Tick(val, pointerOverViewport: false, 0f, _sizedForScale); } else { _treeView?.Tick(val, _treeView.ContainsScreenPoint(val), axis, _sizedForScale); } } private static void ShowTree(PerkTree tree) { _current = tree; _subRail?.Show(tree); _rail?.Refresh(); _treeView.Show(tree); _detail.Show(tree?.Node(_treeView.Selected)); RefreshAll(); } private static void DoPrestige() { if (_current == null) { return; } if (Prestige.TryPrestige(PerkState.Current, _current, out var message)) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)2, message, 0, (Sprite)null, false); } _treeView.Show(_current); } RefreshAll(); } private static void OnAllocationChanged() { if (IsOpen) { RefreshAll(); } } internal static void RefreshAll() { //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null) && _current != null) { PerkState current = PerkState.Current; int num = PointMath.Earned(current); int num2 = PointMath.Spent(current); int num3 = PointMath.SpentIn(current, _current); _ledger.text = $"{num} earned {num2} spent " + $"{num - num2} to spend anywhere " + $"{current.RespecPoints} RP" + ((num3 > 0) ? $" {num3} in {_current.Name}" : ""); _ledger.supportRichText = true; int prestige = current.GetPrestige(_current.Key); _treeTitle.text = ((prestige > 0) ? (_current.Name + " ✦" + prestige) : _current.Name); _treeBlurb.text = _current.Blurb; float num4 = PointMath.LevelFor(current, _current); if (_current.IsSector) { _treeFormula.text = $"average member level {num4:0} → {num} points " + $"({_current.Members.Count} members)"; } else if (_current.IsForeign) { bool flag = ForeignSkills.IsPresent(_current.Key); _treeFormula.text = (flag ? ($"from the {_current.ForeignSkill} mod · high-water {num4:0} " + $"/ interval {PerkDatabase.PointInterval}") : ("needs the " + _current.ForeignSkill + " mod, which is not installed")); } else if (_current.RidesAnotherSkill) { PerkTree perkTree = PerkDatabase.Tree(_current.RidesKey); _treeFormula.text = "follows " + ((perkTree != null) ? perkTree.Name : _current.RidesKey) + " " + $"at level {num4:0} · earns no points of its own"; } else { _treeFormula.text = $"high-water {num4:0} / interval {PerkDatabase.PointInterval}" + $" → {num} points"; } string reason; bool flag2 = Prestige.CanPrestige(current, _current, out reason); ((Selectable)_prestige).interactable = flag2; _prestigeLabel.text = ((_current.IsSector || _current.RidesAnotherSkill) ? "INHERITED" : $"PRESTIGE ✦{prestige}/{ModConfig.PrestigeCap.Value}"); ((Graphic)_prestigeLabel).color = (flag2 ? Palette.Gold : Palette.InkDim); _rail.Refresh(); _subRail?.Refresh(); _treeView.Refresh(); _detail.Refresh(); } } } internal static class PerkPanelInput { internal static ConfigEntry Hotkey; internal static void Bind(ConfigFile config) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) Hotkey = config.Bind("UI", "Hotkey", new KeyboardShortcut((KeyCode)112, Array.Empty()), "Opens the perk panel."); } internal static void Tick(Player __instance) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (Hotkey == null) { return; } if (PerkPanel.IsOpen && Input.GetKeyDown((KeyCode)27)) { PerkPanel.Close(); return; } PerkPanel.Tick(); if (Console.IsVisible() || TextInput.IsVisible()) { return; } Chat instance = Chat.instance; if (instance == null || !instance.HasFocus()) { KeyboardShortcut value = Hotkey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { PerkPanel.Toggle(); } } } } internal sealed class PerkTreeView { private sealed class NodeWidget { internal PerkNode Node; internal RectTransform Holder; internal Image Border; internal Image Fill; internal Text Rank; internal Text Label; internal Text Req; internal Button Button; } private readonly RectTransform _root; private readonly RectTransform _viewport; private readonly RectTransform _world; private readonly RectTransform _edges; private readonly RectTransform _nodes; private readonly CanvasGroup _worldGroup; private readonly Dictionary _widgets = new Dictionary(); private readonly Dictionary _focusByTree = new Dictionary(); private PerkTree _tree; private string _selected; private float _zoom = 1f; private Vector2 _pan; private Vector2 _panTarget; private bool _dragging; private bool _dragArmed; private Vector2 _dragOrigin; private Vector2 _panAtDragStart; private const float NodeSize = 54f; private const float LabelWidth = 168f; private const float SpreadX = 2600f; private const float SpreadY = 1700f; private const float MinZoom = 0.45f; private const float MaxZoom = 2.5f; private const float EdgeHitThickness = 26f; internal string Selected => _selected; internal event Action NodeSelected; internal PerkTreeView(Transform parent) { //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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) _root = UiFactory.Rect("tree", parent, Vector2.zero, Vector2.one, new Vector2(12f, 12f), new Vector2(-12f, -12f)); UiFactory.Fill(_root, Palette.Panel); _viewport = UiFactory.Rect("viewport", (Transform)(object)_root, Vector2.zero, Vector2.one, new Vector2(2f, 2f), new Vector2(-2f, -2f)); ((Component)_viewport).gameObject.AddComponent(); _world = UiFactory.Point("world", (Transform)(object)_viewport, new Vector2(0.5f, 0.5f), new Vector2(5200f, 3400f)); _worldGroup = ((Component)_world).gameObject.AddComponent(); _edges = UiFactory.Rect("edges", (Transform)(object)_world, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); _nodes = UiFactory.Rect("nodes", (Transform)(object)_world, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); } internal void Show(PerkTree tree) { _tree = tree; _zoom = Mathf.Clamp(ModConfig.TreeZoom.Value, 0.45f, 2.5f); Build(); string text = null; if (tree != null && _focusByTree.TryGetValue(tree.Key, out var value) && tree.Node(value) != null) { text = value; } text = text ?? DefaultFocus(tree); SetFocus(text, animate: false); } private static string DefaultFocus(PerkTree tree) { if (tree == null || tree.Nodes.Count == 0) { return null; } PerkState current = PerkState.Current; PerkNode perkNode = null; foreach (PerkNode node in tree.Nodes) { if (current.GetRank(node.Id) > 0 && (perkNode == null || node.Y > perkNode.Y)) { perkNode = node; } } return (perkNode ?? tree.Nodes[0]).Id; } private static Vector2 Place(PerkNode node) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) return new Vector2((node.X / 100f - 0.5f) * 2600f, (0.5f - node.Y / 100f) * 1700f); } private void Build() { UiFactory.Clear((Transform)(object)_edges); UiFactory.Clear((Transform)(object)_nodes); _widgets.Clear(); if (_tree == null) { return; } foreach (PerkNode node in _tree.Nodes) { _widgets[node.Id] = BuildNode(node); } Refresh(); } private NodeWidget BuildNode(PerkNode node) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_0116: 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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) RectTransform val = UiFactory.Point("node_" + node.Id, (Transform)(object)_nodes, new Vector2(0.5f, 0.5f), new Vector2(168f, 106f)); val.anchoredPosition = Place(node); RectTransform val2 = UiFactory.Point("gem", (Transform)(object)val, new Vector2(0.5f, 1f), new Vector2(54f, 54f)); val2.anchoredPosition = new Vector2(0f, -27f); Image border = UiFactory.Fill(val2, Palette.Line); Image fill = UiFactory.Fill(UiFactory.Rect("fill", (Transform)(object)val2, Vector2.zero, Vector2.one, new Vector2(2f, 2f), new Vector2(-2f, -2f)), Palette.Panel2); Button val3 = UiFactory.Clickable(val2, Palette.Line); PerkNode captured = node; ((UnityEvent)val3.onClick).AddListener((UnityAction)delegate { Select(captured); }); Text rank = UiFactory.Label("rank", (Transform)(object)val2, "", 15, Palette.InkDim, (TextAnchor)4, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); RectTransform val4 = UiFactory.Rect("plate", (Transform)(object)val, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(14f, 22f), new Vector2(-14f, 44f)); UiFactory.Fill(val4, Palette.Panel); Text val5 = UiFactory.Label("label", (Transform)(object)val4, node.Name, 15, Palette.InkDim, (TextAnchor)4, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); val5.horizontalOverflow = (HorizontalWrapMode)1; RectTransform val6 = UiFactory.Rect("reqplate", (Transform)(object)val, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(24f, 4f), new Vector2(-24f, 20f)); UiFactory.Fill(val6, Palette.Panel); Text val7 = UiFactory.Label("req", (Transform)(object)val6, "lv " + node.RequiresLevel, 12, Palette.InkDim, (TextAnchor)4, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); val7.horizontalOverflow = (HorizontalWrapMode)1; return new NodeWidget { Node = node, Holder = val, Border = border, Fill = fill, Rank = rank, Label = val5, Req = val7, Button = val3 }; } private void Select(PerkNode node) { SetFocus(node.Id, animate: true); this.NodeSelected?.Invoke(node); } internal void SetFocus(string nodeId, bool animate) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) _selected = nodeId; if (_tree != null && nodeId != null) { _focusByTree[_tree.Key] = nodeId; } PerkNode perkNode = _tree?.Node(nodeId); if (perkNode != null) { _panTarget = -Place(perkNode) * _zoom; if (!animate) { _pan = _panTarget; } } ApplyTransform(); Refresh(); } private void Travel(string fromId, string toId) { string text = ((_selected == toId) ? fromId : toId); PerkNode perkNode = _tree?.Node(text); if (perkNode != null) { SetFocus(text, animate: true); this.NodeSelected?.Invoke(perkNode); } } private void ApplyTransform() { //IL_0017: 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) ((Transform)_world).localScale = new Vector3(_zoom, _zoom, 1f); _world.anchoredPosition = _pan; } internal void Tick(Vector2 mouse, bool pointerOverViewport, float wheel, float uiScale) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) if (_tree == null) { return; } Vector2 val = _pan - _panTarget; if (((Vector2)(ref val)).sqrMagnitude > 0.5f && !_dragging) { float num = 1f - Mathf.Exp(-14f * Time.unscaledDeltaTime); _pan = Vector2.Lerp(_pan, _panTarget, num); ApplyTransform(); } if (!pointerOverViewport && !_dragging) { _dragArmed = false; return; } if (!Mathf.Approximately(wheel, 0f)) { float zoom = _zoom; _zoom = Mathf.Clamp(_zoom * (1f + wheel * 0.18f), 0.45f, 2.5f); if (!Mathf.Approximately(zoom, _zoom)) { float num2 = _zoom / zoom; _pan *= num2; _panTarget *= num2; ApplyTransform(); } } if (Input.GetMouseButtonDown(0)) { _dragArmed = true; _dragOrigin = mouse; _panAtDragStart = _pan; } if (_dragArmed && Input.GetMouseButton(0)) { Vector2 val2 = (mouse - _dragOrigin) / Mathf.Max(0.01f, uiScale); if (!_dragging && ((Vector2)(ref val2)).sqrMagnitude > 30f) { _dragging = true; _worldGroup.blocksRaycasts = false; } if (_dragging) { _pan = _panAtDragStart + val2; _panTarget = _pan; ApplyTransform(); } } if (Input.GetMouseButtonUp(0)) { _dragArmed = false; if (_dragging) { _dragging = false; _worldGroup.blocksRaycasts = true; } } } internal bool ContainsScreenPoint(Vector2 screen) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return UiFactory.ContainsScreenPoint(_viewport, screen); } internal void Refresh() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_0281: 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_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0296: 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_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Expected O, but got Unknown //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) if (_tree == null) { return; } PerkState current = PerkState.Current; foreach (NodeWidget value in _widgets.Values) { PerkNode node = value.Node; NodeVisualState nodeVisualState = Visual(current, node); ((Graphic)value.Border).color = Palette.NodeBorder(nodeVisualState); ((Graphic)value.Fill).color = Palette.NodeFill(nodeVisualState); ((Graphic)value.Label).color = Palette.NodeLabel(nodeVisualState); value.Rank.text = current.GetRank(node.Id) + "/" + node.MaxRank; ((Graphic)value.Rank).color = (Color)(nodeVisualState switch { NodeVisualState.Available => Palette.Frost, NodeVisualState.Locked => Palette.InkDim, _ => Color32.op_Implicit(new Color32((byte)21, (byte)11, (byte)5, byte.MaxValue)), }); if (!node.IsImplemented) { value.Req.text = "lv " + node.RequiresLevel + " · pending"; ((Graphic)value.Req).color = Palette.Blood; } else if (node.IsPartial) { value.Req.text = "lv " + node.RequiresLevel + " · partial"; ((Graphic)value.Req).color = Palette.Gold; } else { value.Req.text = "lv " + node.RequiresLevel; ((Graphic)value.Req).color = Palette.InkDim; } ((Transform)((Graphic)value.Border).rectTransform).localScale = (Vector3)((node.Id == _selected) ? new Vector3(1.18f, 1.18f, 1f) : Vector3.one); } UiFactory.Clear((Transform)(object)_edges); foreach (PerkNode node2 in _tree.Nodes) { foreach (string require in node2.Requires) { PerkNode perkNode = _tree.Node(require); if (perkNode != null) { int rank = current.GetRank(require); int rank2 = current.GetRank(node2.Id); Color colour = ((rank > 0 && rank2 > 0) ? Palette.Ember : ((rank > 0) ? Palette.Frost : Palette.Line)); Vector2 val = Place(perkNode); Vector2 to = Place(node2); string from = require; string to2 = node2.Id; ((UnityEvent)UiFactory.HitLine((Transform)(object)_edges, val, to, 26f).onClick).AddListener((UnityAction)delegate { Travel(from, to2); }); UiFactory.Connector((Transform)(object)_edges, val, to, (rank > 0 && rank2 > 0) ? 4f : 2.5f, colour); } } } } internal static NodeVisualState Visual(PerkState state, PerkNode node) { int rank = state.GetRank(node.Id); PerkTree perkTree = PerkDatabase.Tree(node.TreeKey); float num = ((perkTree != null) ? PointMath.LevelFor(state, perkTree) : 0f); if (rank > 0 && num < (float)node.RequiresLevel) { return NodeVisualState.Held; } if (rank >= node.MaxRank && rank > 0) { return NodeVisualState.Max; } if (rank > 0) { return NodeVisualState.Taken; } if (PointMath.CanBuy(state, node, out var _) != PointMath.Gate.Ok) { return NodeVisualState.Locked; } return NodeVisualState.Available; } } internal sealed class RightClick : MonoBehaviour, IPointerClickHandler, IEventSystemHandler { internal Action Clicked; public void OnPointerClick(PointerEventData eventData) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 if (eventData != null && (int)eventData.button == 1) { Clicked?.Invoke(); } } internal static RightClick On(GameObject host, Action action) { RightClick rightClick = host.AddComponent(); rightClick.Clicked = action; return rightClick; } } internal sealed class SkillRail { private sealed class Row { internal bool IsPinnedCopy; internal PerkTree Tree; internal RectTransform Root; internal Image Background; internal Image Accent; internal Text Name; internal Text Tally; } private readonly RectTransform _root; private readonly RectTransform _viewport; private readonly RectTransform _content; private readonly ScrollRect _scroll; private readonly List _rows = new List(); private string _selected; internal const float RailHeight = 58f; private const float TabPadding = 18f; private const float GroupGap = 26f; private const float FadeWidth = 54f; private const int NameSize = 17; internal bool IsEmpty => _rows.Count == 0; internal event Action TreeSelected; internal SkillRail(Transform parent) { //IL_0022: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) _root = UiFactory.Rect("rail", parent, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, -58f), new Vector2(0f, 0f)); UiFactory.Fill(_root, Palette.Panel); _viewport = UiFactory.Rect("viewport", (Transform)(object)_root, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); ((Component)_viewport).gameObject.AddComponent(); _content = UiFactory.Rect("content", (Transform)(object)_viewport, new Vector2(0f, 0f), new Vector2(0f, 1f), Vector2.zero, Vector2.zero); _content.pivot = new Vector2(0f, 0.5f); ((Graphic)UiFactory.Fill(_viewport, new Color(0f, 0f, 0f, 0f))).raycastTarget = true; _scroll = ((Component)_root).gameObject.AddComponent(); _scroll.content = _content; _scroll.viewport = _viewport; _scroll.horizontal = true; _scroll.vertical = false; _scroll.movementType = (MovementType)2; _scroll.scrollSensitivity = 42f; _scroll.inertia = true; _scroll.decelerationRate = ModConfig.RailGlide?.Value ?? 0.16f; UiFactory.EdgeFade(UiFactory.Rect("fade_l", (Transform)(object)_root, new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(54f, 0f)), Palette.Ground, opaqueAtLeft: true); UiFactory.EdgeFade(UiFactory.Rect("fade_r", (Transform)(object)_root, new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(-54f, 0f), new Vector2(0f, 0f)), Palette.Ground, opaqueAtLeft: false); } private static TreeKind GroupOf(PerkTree tree) { if (!tree.IsForeign) { return tree.Kind; } return TreeKind.Stub; } internal static bool Visible(PerkTree tree, PerkState state) { if (tree.IsForeign && !ForeignSkills.IsPresent(tree.Key)) { return false; } if (!ModConfig.HideUnlearnedSkills.Value) { return true; } if (tree.AlwaysShown) { return true; } foreach (PerkNode node in tree.Nodes) { if (state.GetRank(node.Id) > 0) { return true; } } if (tree.IsSector) { foreach (string member in tree.Members) { if (state.GetHighWater(member) > 0f) { return true; } } return false; } foreach (string item in tree.RevealWith) { if (state.GetHighWater(item) > 0f) { return true; } } if (tree.RidesAnotherSkill) { return state.GetHighWater(tree.RidesKey) > 0f; } return state.GetHighWater(tree.Key) > 0f; } internal void Build() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) UiFactory.Clear((Transform)(object)_content); _rows.Clear(); PerkState current = PerkState.Current; float x = 27f; x = Pinned(current, x); x = Group("SKILLS", TreeKind.Skill, current, x); x = Group("NEW", TreeKind.New, current, x); x = Group("SECTORS", TreeKind.Sector, current, x); x = Group("MODDED", TreeKind.Stub, current, x); _content.sizeDelta = new Vector2(x + 27f, 0f); Refresh(); } private float Pinned(PerkState state, float x) { List list = new List(); foreach (string item in Favourites.All) { if (PerkDatabase.Trees.TryGetValue(item, out var value) && Visible(value, state)) { list.Add(item); } } if (list.Count == 0) { return x; } x = Tag("PINNED", x); foreach (string item2 in list) { PerkTree tree = PerkDatabase.Trees[item2]; float num = TabWidth(tree); _rows.Add(BuildTab(tree, x, num, pinnedCopy: true)); x += num; } return x + 26f; } private float Tag(string title, float x) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00d2: Unknown result type (might be due to invalid IL or missing references) RectTransform parent = UiFactory.Rect("g_" + title, (Transform)(object)_content, new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(x, 6f), new Vector2(x + 16f, -6f)); Text obj = UiFactory.Label("t", (Transform)(object)parent, title, 10, Palette.InkDim, (TextAnchor)4, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, Vector2.zero); ((Graphic)obj).rectTransform.sizeDelta = new Vector2(44f, 16f); ((Graphic)obj).rectTransform.anchoredPosition = Vector2.zero; obj.horizontalOverflow = (HorizontalWrapMode)1; ((Transform)((Graphic)obj).rectTransform).localRotation = Quaternion.Euler(0f, 0f, 90f); return x + 16f + 10f; } private float Group(string title, TreeKind kind, PerkState state, float x) { List list = new List(); foreach (KeyValuePair tree2 in PerkDatabase.Trees) { if (GroupOf(tree2.Value) == kind && Visible(tree2.Value, state)) { list.Add(tree2.Key); } } if (list.Count == 0) { return x; } if (x > 54f) { x += 26f; } x = Tag(title, x); foreach (string item in list) { PerkTree tree = PerkDatabase.Trees[item]; float num = TabWidth(tree); _rows.Add(BuildTab(tree, x, num, pinnedCopy: false)); x += num; } return x; } private static float TabWidth(PerkTree tree) { return Mathf.Max(84f, (float)tree.Name.Length * 9.2f + 36f); } private Row BuildTab(PerkTree tree, float x, float width, bool pinnedCopy) { //IL_0039: 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_0053: 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_0089: 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_00b0: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) RectTransform rt = UiFactory.Rect((pinnedCopy ? "pin_" : "tab_") + tree.Key, (Transform)(object)_content, new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(x, 4f), new Vector2(x + width, -4f)); Button obj = UiFactory.Clickable(rt, new Color(0f, 0f, 0f, 0f)); PerkTree captured = tree; ((UnityEvent)obj.onClick).AddListener((UnityAction)delegate { Select(captured, rt); }); RightClick.On(((Component)rt).gameObject, delegate { Favourites.Toggle(captured.Key); Build(); TrySelect(_selected); }); Text val = UiFactory.Label("name", (Transform)(object)rt, tree.Name, 17, Palette.Ink2, (TextAnchor)4, Vector2.zero, Vector2.one, new Vector2(6f, 0f), new Vector2(-6f, 4f)); val.horizontalOverflow = (HorizontalWrapMode)1; Image accent = UiFactory.Fill(UiFactory.Rect("accent", (Transform)(object)rt, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(9f, 0f), new Vector2(-9f, 3f)), new Color(0f, 0f, 0f, 0f)); Text tally = UiFactory.Label("tally", (Transform)(object)rt, "", 11, Palette.Gold, (TextAnchor)2, new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 0f), new Vector2(-5f, -4f)); return new Row { Tree = tree, Root = rt, Background = ((Component)rt).GetComponent(), Accent = accent, Name = val, Tally = tally, IsPinnedCopy = pinnedCopy }; } private void Select(PerkTree tree, RectTransform clicked) { _selected = tree.Key; Refresh(); ScrollInto(clicked); this.TreeSelected?.Invoke(tree); } internal void SelectFirst() { if (_rows.Count > 0) { Select(_rows[0].Tree, _rows[0].Root); } } internal bool TrySelect(string key) { foreach (Row row in _rows) { if (!(row.Tree.Key != key)) { Select(row.Tree, row.Root); return true; } } return false; } private void ScrollInto(RectTransform tab) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)tab == (Object)null)) { float x = _content.sizeDelta.x; Rect rect = _viewport.rect; float width = ((Rect)(ref rect)).width; if (!(x <= width)) { _scroll.velocity = Vector2.zero; float x2 = tab.offsetMin.x; rect = tab.rect; float num = (x2 + ((Rect)(ref rect)).width * 0.5f - width * 0.5f) / (x - width); _scroll.horizontalNormalizedPosition = Mathf.Clamp01(num); } } } internal void Wheel(float delta) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) float x = _content.sizeDelta.x; Rect rect = _viewport.rect; float width = ((Rect)(ref rect)).width; if (!(x <= width)) { float num = ModConfig.RailScrollSpeed?.Value ?? 2600f; ScrollRect scroll = _scroll; scroll.velocity += new Vector2(delta * num, 0f); } } internal bool ContainsScreenPoint(Vector2 screen) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return UiFactory.ContainsScreenPoint(_root, screen); } internal void Refresh() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) PerkState current = PerkState.Current; foreach (Row row in _rows) { bool flag = row.Tree.Key == _selected; int num = PointMath.SpentIn(current, row.Tree); int prestige = current.GetPrestige(row.Tree.Key); ((Graphic)row.Background).color = (Color)(flag ? Palette.Panel2 : new Color(0f, 0f, 0f, 0f)); ((Graphic)row.Accent).color = (Color)(flag ? AccentFor(row.Tree.Kind) : new Color(0f, 0f, 0f, 0f)); string text = ((prestige > 0) ? (row.Tree.Name + " ✦" + prestige) : row.Tree.Name); row.Name.text = (row.IsPinnedCopy ? ("★ " + text) : text); ((Graphic)row.Name).color = (flag ? Palette.Ink : TintFor(row.Tree.Kind)); row.Tally.text = ((num > 0) ? num.ToString() : ""); } } private static Color AccentFor(TreeKind kind) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) return (Color)(kind switch { TreeKind.Sector => Palette.Frost, TreeKind.New => Palette.Blood, TreeKind.Style => Palette.Gold, TreeKind.Fork => Palette.Gold, TreeKind.Stub => Palette.InkDim, _ => Palette.Ember, }); } private static Color TintFor(TreeKind kind) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) switch (kind) { case TreeKind.Sector: return Palette.Frost; case TreeKind.New: return Palette.Gold; case TreeKind.Style: case TreeKind.Fork: return Palette.Ink2; case TreeKind.Stub: return Palette.InkDim; default: return Palette.Ink2; } } } internal static class TreeRelations { internal enum Relation { Self, Parent, Child, Overlap } internal struct Entry { internal PerkTree Tree; internal Relation Relation; } internal static List FamilyOf(PerkTree tree, Func visible) { List list = new List(); if (tree == null) { return list; } list.Add(new Entry { Tree = tree, Relation = Relation.Self }); if (tree.RidesAnotherSkill && !string.IsNullOrEmpty(tree.RidesKey) && PerkDatabase.Trees.TryGetValue(tree.RidesKey, out var value)) { Add(list, value, Relation.Parent, visible); } foreach (KeyValuePair tree2 in PerkDatabase.Trees) { PerkTree value2 = tree2.Value; if (value2.RidesAnotherSkill && !(value2.RidesKey != tree.Key)) { Add(list, value2, Relation.Child, visible); } } foreach (KeyValuePair tree3 in PerkDatabase.Trees) { PerkTree value3 = tree3.Value; if (value3.IsSector && value3.Members.Contains(tree.Key)) { Add(list, value3, Relation.Overlap, visible); } } if (tree.IsSector) { foreach (string member in tree.Members) { if (PerkDatabase.Trees.TryGetValue(member, out var value4)) { Add(list, value4, Relation.Overlap, visible); } } } return list; } internal static bool HasFamily(PerkTree tree, Func visible) { return FamilyOf(tree, visible).Count > 1; } private static void Add(List family, PerkTree tree, Relation relation, Func visible) { if (tree == null || (visible != null && !visible(tree))) { return; } foreach (Entry item in family) { if (item.Tree.Key == tree.Key) { return; } } family.Add(new Entry { Tree = tree, Relation = relation }); } } internal sealed class TreeSubRail { private sealed class Row { internal TreeRelations.Entry Entry; internal RectTransform Root; internal Image Background; internal Text Name; } internal const float SubRailHeight = 34f; private const float TabPadding = 14f; private const int NameSize = 14; private readonly RectTransform _root; private readonly RectTransform _content; private readonly List _rows = new List(); private string _selected; internal RectTransform Root => _root; internal event Action TreeSelected; internal TreeSubRail(Transform parent) { //IL_0022: 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_0064: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) _root = UiFactory.Rect("subrail", parent, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, -34f), new Vector2(0f, 0f)); UiFactory.Fill(_root, Palette.Ground); _content = UiFactory.Rect("content", (Transform)(object)_root, new Vector2(0f, 0f), new Vector2(0f, 1f), Vector2.zero, Vector2.zero); _content.pivot = new Vector2(0f, 0.5f); } internal void Show(PerkTree tree) { UiFactory.Clear((Transform)(object)_content); _rows.Clear(); _selected = tree?.Key; if (tree == null) { return; } PerkState state = PerkState.Current; List list = TreeRelations.FamilyOf(tree, (PerkTree t) => SkillRail.Visible(t, state)); float num = 14f; foreach (TreeRelations.Entry item in list) { float num2 = Mathf.Max(70f, (float)item.Tree.Name.Length * 7.6f + 28f); _rows.Add(BuildTab(item, num, num2)); num += num2 + 4f; } Refresh(); } private Row BuildTab(TreeRelations.Entry entry, float x, float width) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) RectTransform val = UiFactory.Rect("sub_" + entry.Tree.Key, (Transform)(object)_content, new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(x, 4f), new Vector2(x + width, -4f)); Button obj = UiFactory.Clickable(val, new Color(0f, 0f, 0f, 0f)); PerkTree captured = entry.Tree; ((UnityEvent)obj.onClick).AddListener((UnityAction)delegate { this.TreeSelected?.Invoke(captured); }); Text val2 = UiFactory.Label("name", (Transform)(object)val, Label(entry), 14, Palette.Ink2, (TextAnchor)4, Vector2.zero, Vector2.one, new Vector2(4f, 0f), new Vector2(-4f, 0f)); val2.horizontalOverflow = (HorizontalWrapMode)1; return new Row { Entry = entry, Root = val, Name = val2, Background = ((Component)val).GetComponent() }; } private static string Label(TreeRelations.Entry entry) { return entry.Relation switch { TreeRelations.Relation.Parent => "↰ " + entry.Tree.Name, TreeRelations.Relation.Child => "· " + entry.Tree.Name, TreeRelations.Relation.Overlap => "⇄ " + entry.Tree.Name, _ => entry.Tree.Name, }; } internal void Refresh() { //IL_0056: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) foreach (Row row in _rows) { bool flag = row.Entry.Tree.Key == _selected; ((Graphic)row.Background).color = (Color)(flag ? Palette.Panel2 : new Color(0f, 0f, 0f, 0f)); ((Graphic)row.Name).color = (flag ? Palette.Ink : TintFor(row.Entry.Relation)); } } private static Color TintFor(TreeRelations.Relation relation) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return (Color)(relation switch { TreeRelations.Relation.Overlap => Palette.Frost, TreeRelations.Relation.Parent => Palette.Gold, _ => Palette.InkDim, }); } } internal static class UiFactory { internal const int UiLayer = 5; private static Sprite _fadeLeft; private static Sprite _fadeRight; internal static Font Font { get { GUIManager instance = GUIManager.Instance; if (instance == null) { return null; } return instance.AveriaSerifBold; } } internal static RectTransform Rect(string name, Transform parent, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }) { layer = 5 }.GetComponent(); ((Transform)component).SetParent(parent, false); component.anchorMin = anchorMin; component.anchorMax = anchorMax; component.offsetMin = offsetMin; component.offsetMax = offsetMax; return component; } internal static RectTransform Point(string name, Transform parent, Vector2 anchor, Vector2 size) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }) { layer = 5 }.GetComponent(); ((Transform)component).SetParent(parent, false); component.anchorMin = anchor; component.anchorMax = anchor; component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = size; component.anchoredPosition = Vector2.zero; return component; } internal static Image Fill(RectTransform rt, Color colour) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) Image obj = ((Component)rt).gameObject.AddComponent(); ((Graphic)obj).color = colour; ((Graphic)obj).raycastTarget = false; return obj; } internal static Text Label(string name, Transform parent, string content, int size, Color colour, TextAnchor align, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) Text obj = ((Component)Rect(name, parent, anchorMin, anchorMax, offsetMin, offsetMax)).gameObject.AddComponent(); obj.font = Font; obj.fontSize = size; ((Graphic)obj).color = colour; obj.alignment = align; obj.text = content; ((Graphic)obj).raycastTarget = false; obj.horizontalOverflow = (HorizontalWrapMode)0; obj.verticalOverflow = (VerticalWrapMode)1; return obj; } internal static Button Clickable(RectTransform rt, Color idle) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) Image val = ((Component)rt).gameObject.GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)rt).gameObject.AddComponent(); } ((Graphic)val).color = idle; ((Graphic)val).raycastTarget = true; Button obj = ((Component)rt).gameObject.AddComponent