Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of NorntasticSkillGrowth v0.14.2
plugins\Norntastic.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.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 <text> 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<ItemData> 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<string, object> Obj(object o) { return o as Dictionary<string, object>; } internal static List<object> Arr(object o) { return o as List<object>; } internal static object Get(object o, string key) { if (!(o is Dictionary<string, object> 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<string> StrList(object o, string key) { List<string> list = new List<string>(); if (!(Get(o, key) is List<object> 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<string, object> ParseObject(string s, ref int i) { Dictionary<string, object> dictionary = new Dictionary<string, object>(); 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<object> ParseArray(string s, ref int i) { List<object> list = new List<object>(); 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<string> Owners = new List<string>(); internal int Prefixes; internal int Postfixes; internal int Transpilers; internal int Finalizers; internal readonly List<string> Detail = new List<string>(); 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<Entry> Collect() { List<Entry> list = new List<Entry>(); IEnumerable<MethodBase> 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<T>(ICollection<T> 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<Patch> 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<string> Report(string ourId, string filter) { List<string> list = new List<string>(); List<Entry> 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<Entry> list3 = new List<Entry>(); 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<SkillType, string> ToKey; private static readonly Dictionary<string, SkillType> FromKey; private static readonly Dictionary<SkillType, string> Custom; static SkillKeys() { //IL_0176: Unknown result type (might be due to invalid IL or missing references) ToKey = new Dictionary<SkillType, string> { { (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<string, SkillType>(StringComparer.OrdinalIgnoreCase); Custom = new Dictionary<SkillType, string>(); foreach (KeyValuePair<SkillType, string> 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<string> Pinned = new List<string>(); private static bool _loaded; internal static IReadOnlyList<string> 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<string> list = new List<string>(); 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 ? "<color=#DE7430>" : "<color=#75858F>").Append(i).Append("</color> ") .Append(flag2 ? "<color=#D8E0E8>" : "<color=#75858F>") .Append(_node.RankText(i)) .Append("</color>\n\n"); } _ranks.supportRichText = true; _ranks.text = stringBuilder2.ToString(); List<string> list2 = new List<string>(); if (nodeVisualState == NodeVisualState.Held) { list2.Add("<color=#E9B45F>Held. Bought above this level and still applying — gates are checked at purchase only.</color>"); } if (_node.IsExclusive) { PerkNode perkNode2 = PointMath.ExclusiveBlocker(current, perkTree, _node); list2.Add((perkNode2 == null) ? "<color=#6FA9C4>An exclusive fork. Taking it locks the others until refunded.</color>" : ("<color=#A8413F>Locked: you committed to " + perkNode2.Name + ".</color>")); } if (!_node.IsImplemented) { list2.Add("<color=#A8413F>Not yet implemented: " + _node.PendingNote + "</color>"); } else if (_node.IsPartial) { list2.Add("<color=#E9B45F>Partly implemented. What is missing: " + _node.PendingNote + "</color>"); } else if (!string.IsNullOrEmpty(_node.ImplementedNote)) { list2.Add("<color=#8FA8B8>" + _node.ImplementedNote + "</color>"); } string reason; PointMath.Gate gate = PointMath.CanBuy(current, _node, out reason); if (gate != PointMath.Gate.Ok && nodeVisualState != NodeVisualState.Held) { list2.Add("<color=#E2A3A1>" + reason + "</color>"); } _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<PerkTree> <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 " + $"<color=#E9B45F>{num - num2} to spend anywhere</color> " + $"<color=#6FA9C4>{current.RespecPoints} RP</color>" + ((num3 > 0) ? $" <color=#75858F>{num3} in {_current.Name}</color>" : ""); _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<KeyboardShortcut> Hotkey; internal static void Bind(ConfigFile config) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) Hotkey = config.Bind<KeyboardShortcut>("UI", "Hotkey", new KeyboardShortcut((KeyCode)112, Array.Empty<KeyCode>()), "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<string, NodeWidget> _widgets = new Dictionary<string, NodeWidget>(); private readonly Dictionary<string, string> _focusByTree = new Dictionary<string, string>(); 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<PerkNode> 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<RectMask2D>(); _world = UiFactory.Point("world", (Transform)(object)_viewport, new Vector2(0.5f, 0.5f), new Vector2(5200f, 3400f)); _worldGroup = ((Component)_world).gameObject.AddComponent<CanvasGroup>(); _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>(); 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<Row> _rows = new List<Row>(); 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<PerkTree> 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<RectMask2D>(); _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<ScrollRect>(); _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<string> list = new List<string>(); 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<string> list = new List<string>(); foreach (KeyValuePair<string, PerkTree> 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<Image>(), Accent = a