Decompiled source of HowToFishExtended v3.0.3
BepInEx/plugins/HTFExpanded.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using BepInEx; using FishNet; using FishNet.Connection; using FishNet.Managing.Server; using FishNet.Object; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HtfExpanded { public static class Ascension { private static int _level; public static int Level { get { return _level; } set { _level = Mathf.Max(0, value); } } public static int MaxLevel { get { Cfg.EnsureLoaded(); if (Cfg.AscensionMaxLevel > 0) { return Cfg.AscensionMaxLevel; } int i = 0; double num = Cfg.AscensionBaseCost; for (; i < 200; i++) { if (!(num * (double)Cfg.AscensionCostGrowth <= 2147483647.0)) { break; } num *= (double)Cfg.AscensionCostGrowth; } return i; } } public static bool AtMaxLevel => _level >= MaxLevel; public static bool Unlocked { get { try { if ((Object)(object)EndGameManager.Instance != (Object)null && EndGameManager.Instance.HasFinishedGame) { return true; } return SaveManager.CurServerSave?.HasFinishedGame ?? false; } catch { return false; } } } public static float HpMultiplier() { Cfg.EnsureLoaded(); if (_level <= 0) { return 1f; } double num = Math.Pow(Cfg.AscensionHpGrowth, _level); return (num > 1000000000.0) ? 1E+09f : ((float)num); } public static float ValueMultiplier() { Cfg.EnsureLoaded(); if (_level <= 0) { return 1f; } double num = Math.Pow(Cfg.AscensionValueGrowth, _level); return (num > 1000000000.0) ? 1E+09f : ((float)num); } public static int LuckBonus() { Cfg.EnsureLoaded(); return _level * Cfg.AscensionLuckBonus; } public static int ScaleHp(int baseHp) { try { if (_level <= 0 || baseHp <= 0) { return baseHp; } double num = (double)baseHp * (double)HpMultiplier(); if (num >= 2147483647.0) { return int.MaxValue; } return (int)num; } catch (Exception e) { Log.Ex("Ascension.ScaleHp", e); return baseHp; } } public static int CostForNextLevel() { Cfg.EnsureLoaded(); if (AtMaxLevel) { return -1; } double num = (double)Cfg.AscensionBaseCost * Math.Pow(Cfg.AscensionCostGrowth, _level); if (num >= 2147483647.0) { return -1; } return (int)num; } public static bool TryBuy(Player buyer) { try { Cfg.EnsureLoaded(); if (!Cfg.EnableAscension) { Log.Info("ascension purchase refused: disabled in the config"); return false; } if (!Unlocked) { Log.Info("ascension purchase refused: the game has not been finished on this save yet"); return false; } int num = CostForNextLevel(); if (num < 0) { Log.Info("ascension purchase refused: already at the top tier (" + MaxLevel + ")"); return false; } if (!MoneyManager.CanAfford(num)) { Log.Info("ascension purchase refused: cannot afford $" + num); return false; } MoneyManager.RemoveMoney(num, buyer); Level = _level + 1; Luck.SaveForCurrentSave(); Net.BroadcastState(); Log.Info("ascension purchased, now tier " + _level + " (creature health x" + HpMultiplier().ToString("0.#") + ", fish value x" + ValueMultiplier().ToString("0.#") + ", +" + LuckBonus() + " luck)"); return true; } catch (Exception e) { Log.Ex("Ascension.TryBuy", e); return false; } } } public static class Assets { private const string ResourcePrefix = "HtfExpanded.Assets."; private static string[] _searchDirs; private static string _lastSource = ""; public static string ModelDir => Cfg.Dir + "/HowToFishExpanded/models"; public static string[] SearchDirs { get { if (_searchDirs != null) { return _searchDirs; } List<string> list = new List<string>(); try { list.Add(ModelDir); } catch { } try { DirectoryInfo parent = Directory.GetParent(Application.dataPath); if (parent != null) { list.Add(parent.FullName + "/models"); } } catch { } try { string location = Assembly.GetExecutingAssembly().Location; if (!string.IsNullOrEmpty(location)) { string directoryName = Path.GetDirectoryName(location); if (!string.IsNullOrEmpty(directoryName)) { list.Add(directoryName + "/models"); } } } catch { } _searchDirs = list.ToArray(); return _searchDirs; } } public static string LastSource => _lastSource; public static void EnsureDir() { try { if (!Directory.Exists(ModelDir)) { Directory.CreateDirectory(ModelDir); } } catch (Exception e) { Log.Ex("Assets.EnsureDir", e); } } public static byte[] Read(string relative) { byte[] array = FromDisk(relative) ?? Inflate(FromDisk(relative + ".gz")); if (array != null) { return array; } byte[] array2 = FromResource(relative) ?? Inflate(FromResource(relative + ".gz")); if (array2 != null) { _lastSource = "the copy built into the mod"; } return array2; } public static string ReadText(string relative) { byte[] array = Read(relative); if (array == null) { return null; } try { return new UTF8Encoding(encoderShouldEmitUTF8Identifier: false).GetString(array); } catch (Exception e) { Log.Ex("Assets.ReadText(" + relative + ")", e); return null; } } public static bool Exists(string relative) { return Read(relative) != null; } public static bool IsEmbedded(string relative) { return FromResource(relative) != null || FromResource(relative + ".gz") != null; } private static byte[] FromDisk(string relative) { string[] searchDirs = SearchDirs; for (int i = 0; i < searchDirs.Length; i++) { try { string path = searchDirs[i] + "/" + relative; if (!File.Exists(path)) { continue; } _lastSource = searchDirs[i]; return File.ReadAllBytes(path); } catch (Exception e) { Log.Ex("Assets.FromDisk(" + relative + ")", e); } } return null; } private static byte[] FromResource(string relative) { try { string name = "HtfExpanded.Assets." + relative.Replace('/', '.'); using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } return array; } catch (Exception e) { Log.Ex("Assets.FromResource(" + relative + ")", e); return null; } } private static byte[] Inflate(byte[] compressed) { if (compressed == null) { return null; } try { using MemoryStream stream = new MemoryStream(compressed); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); byte[] array = new byte[16384]; int count; while ((count = gZipStream.Read(array, 0, array.Length)) > 0) { memoryStream.Write(array, 0, count); } return memoryStream.ToArray(); } catch (Exception ex) { Log.Warn("could not decompress an asset: " + ex.Message); return null; } } public static Texture2D LoadTexture(string relative) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown byte[] array = Read(relative); if (array == null) { return null; } try { Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true); if (!ImageConversion.LoadImage(val, array)) { Object.Destroy((Object)(object)val); Log.Warn("'" + relative + "' is not an image the game can read"); return null; } ((Object)val).name = relative; ((Texture)val).filterMode = (FilterMode)(!Cfg.ModelPointFilter); ((Texture)val).wrapMode = (TextureWrapMode)0; val.Apply(true, false); return val; } catch (Exception e) { Log.Ex("Assets.LoadTexture(" + relative + ")", e); return null; } } } public sealed class StoredItem { public byte ItemID; public float Weight = 1f; public float Cookness; public float BettingMultiplier; public float KillScoreMultiplier; public bool IsDripCreature; public byte SkinIndex; public byte Sharpness; public byte Sight; public byte BarrelAttachment; public byte AmmoType; public bool ExtendedMag; public bool LaserSight; public string Label = "?"; public int Worth; public int Tier { get { try { return Variants.TierForWeight(Weight); } catch { return 0; } } } } public static class Backpack { public static readonly List<StoredItem> Items = new List<StoredItem>(); private static string _saveName = ""; private static MethodInfo _toSavedItem; private static MethodInfo _getTotalSlots; private static FieldInfo _playerField; private static bool _reflectionWarned; public static readonly List<StoredItem> RemoteItems = new List<StoredItem>(); private const char EntrySep = '~'; private const char FieldSep = '|'; public static bool IsFull => Items.Count >= Capacity(); private static string ModFolder => Luck.ModFolder; public static int RemotePage { get; private set; } public static int RemoteCount { get; private set; } public static int RemoteCapacity { get; private set; } public static int Capacity() { Cfg.EnsureLoaded(); if (!Cfg.EnableBackpack) { return 0; } int num = Mathf.Max(0, Ascension.Level) * Mathf.Max(0, Cfg.BackpackSlotsPerAscension); return Mathf.Clamp(Cfg.BackpackSlots + num, 0, Cfg.BackpackMaxSlots); } public static int HotbarSlots(PlayerInventory inv) { try { if ((Object)(object)inv == (Object)null) { return 0; } if (_getTotalSlots == null) { _getTotalSlots = typeof(PlayerInventory).GetMethod("GetTotalSlots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (_getTotalSlots == null) { return 0; } return (int)_getTotalSlots.Invoke(inv, null); } catch (Exception e) { Log.Ex("Backpack.HotbarSlots", e); return 0; } } public static Player PlayerOf(PlayerInventory inv) { try { if ((Object)(object)inv == (Object)null) { return null; } if (_playerField == null) { _playerField = typeof(PlayerInventory).GetField("_player", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (_playerField != null) { object? value = _playerField.GetValue(inv); Player val = (Player)((value is Player) ? value : null); if ((Object)(object)val != (Object)null) { return val; } } return ((Component)inv).GetComponentInParent<Player>(); } catch (Exception e) { Log.Ex("Backpack.PlayerOf", e); return null; } } public static Item HotbarItem(PlayerInventory inv, int slot) { try { if ((Object)(object)inv == (Object)null || slot < 0 || slot > 255) { return null; } Item val = default(Item); return inv._items.TryGetValue((byte)slot, ref val) ? val : null; } catch { return null; } } public static int FirstFreeHotbarSlot(PlayerInventory inv) { int num = HotbarSlots(inv); for (int i = 0; i < num; i++) { if ((Object)(object)HotbarItem(inv, i) == (Object)null) { return i; } } return -1; } private static SavedItem Describe(Item item, byte slot) { try { if (_toSavedItem == null) { _toSavedItem = typeof(SaveManager).GetMethod("ItemToSavedItem", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(byte), typeof(Item) }, null); } if (_toSavedItem == null) { if (!_reflectionWarned) { _reflectionWarned = true; Log.Warn("storage is read-only on this build of the game: SaveManager.ItemToSavedItem is not there, so an item cannot be described without risking losing part of it. Taking things out still works."); } return null; } object? obj = _toSavedItem.Invoke(null, new object[2] { slot, item }); return (SavedItem)((obj is SavedItem) ? obj : null); } catch (Exception e) { Log.Ex("Backpack.Describe", e); return null; } } private static StoredItem FromSaved(SavedItem s, Item live) { StoredItem storedItem = new StoredItem(); storedItem.ItemID = s.ItemID; storedItem.Weight = s.Weight; storedItem.Cookness = s.Cookness; storedItem.BettingMultiplier = s.BettingMultiplier; storedItem.KillScoreMultiplier = s.KillScoreMultiplier; storedItem.IsDripCreature = s.IsDripCreature; storedItem.SkinIndex = s.SkinIndex; storedItem.Sharpness = s.Sharpness; storedItem.Sight = s.Sight; storedItem.BarrelAttachment = s.BarrelAttachment; storedItem.AmmoType = s.AmmoType; storedItem.ExtendedMag = s.ExtendedMag; storedItem.LaserSight = s.LaserSight; try { storedItem.Label = (((Object)(object)live != (Object)null) ? live.GetName() : "?"); } catch { storedItem.Label = "?"; } try { storedItem.Worth = (((Object)(object)live != (Object)null) ? live.TotalWorth : 0); } catch { storedItem.Worth = 0; } if (string.IsNullOrEmpty(storedItem.Label)) { storedItem.Label = "?"; } return storedItem; } private static SavedItem ToSaved(StoredItem r, byte slot) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown SavedItem val = new SavedItem(); val.Exists = true; val.InventorySlot = slot; val.ItemID = r.ItemID; val.Weight = r.Weight; val.Cookness = r.Cookness; val.BettingMultiplier = r.BettingMultiplier; val.KillScoreMultiplier = r.KillScoreMultiplier; val.IsDripCreature = r.IsDripCreature; val.SkinIndex = r.SkinIndex; val.Sharpness = r.Sharpness; val.Sight = r.Sight; val.BarrelAttachment = r.BarrelAttachment; val.AmmoType = r.AmmoType; val.ExtendedMag = r.ExtendedMag; val.LaserSight = r.LaserSight; return val; } public static bool Deposit(PlayerInventory inv, int slot, out string why) { why = ""; try { Cfg.EnsureLoaded(); if (!Cfg.EnableBackpack) { why = "Storage is switched off in the config."; return false; } if (!Net.IsServer) { why = "Only the host can move things in and out of storage."; return false; } if ((Object)(object)inv == (Object)null) { why = "No inventory."; return false; } if (IsFull) { why = "Storage is full (" + Items.Count + "/" + Capacity() + ")."; return false; } Item val = HotbarItem(inv, slot); if ((Object)(object)val == (Object)null) { why = "That slot is empty."; return false; } Item val2 = null; try { val2 = inv.SyncedCurItem; } catch { } if ((Object)(object)val2 != (Object)null && (Object)(object)val2 == (Object)(object)val) { why = "You are holding that - press its number again to put it away first."; return false; } SavedItem val3 = Describe(val, (byte)slot); if (val3 == null) { why = "This build of the game will not let the mod describe that item safely, so it was left alone."; return false; } StoredItem storedItem = FromSaved(val3, val); Items.Add(storedItem); SaveNow(); inv.RemoveItem(val); DespawnItem(val); Log.Info("stored " + storedItem.Label + " at " + storedItem.Weight.ToString("0.000") + "x (" + Items.Count + "/" + Capacity() + ")"); return true; } catch (Exception e) { Log.Ex("Backpack.Deposit", e); why = "Something went wrong storing that - see the log."; return false; } } public static int DepositAll(PlayerInventory inv, out string why) { why = ""; int num = 0; try { int num2 = HotbarSlots(inv); Item val = null; try { val = inv.SyncedCurItem; } catch { } for (int i = 0; i < num2; i++) { if (IsFull) { break; } Item val2 = HotbarItem(inv, i); if (!((Object)(object)val2 == (Object)null) && (!((Object)(object)val != (Object)null) || !((Object)(object)val2 == (Object)(object)val))) { if (!Deposit(inv, i, out var why2)) { why = why2; break; } num++; } } if (num == 0 && why.Length == 0) { why = "Nothing to stow."; } } catch (Exception e) { Log.Ex("Backpack.DepositAll", e); why = "Something went wrong - see the log."; } return num; } private static void DespawnItem(Item item) { try { if (!((Object)(object)item == (Object)null)) { GameObject gameObject = ((Component)item).gameObject; ServerManager serverManager = InstanceFinder.ServerManager; if ((Object)(object)serverManager != (Object)null) { serverManager.Despawn(gameObject, (DespawnType?)null); } else { Object.Destroy((Object)(object)gameObject); } } } catch (Exception e) { Log.Ex("Backpack.DespawnItem", e); } } public static bool Withdraw(PlayerInventory inv, int index, out string why) { //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) why = ""; try { Cfg.EnsureLoaded(); if (!Net.IsServer) { why = "Only the host can move things in and out of storage."; return false; } if ((Object)(object)inv == (Object)null) { why = "No inventory."; return false; } if (index < 0 || index >= Items.Count) { why = "Nothing there."; return false; } int num = FirstFreeHotbarSlot(inv); if (num < 0) { why = "No free inventory slot - drop or sell something first."; return false; } StoredItem storedItem = Items[index]; Item spawnable = GameInfo.GetSpawnable(storedItem.ItemID); if ((Object)(object)spawnable == (Object)null) { why = "The game does not have that item any more (id " + storedItem.ItemID + ")."; return false; } Player val = PlayerOf(inv); Vector3 val2 = (((Object)(object)val != (Object)null && (Object)(object)val.Transform != (Object)null) ? val.Transform.position : Vector3.zero); Item val3 = Object.Instantiate<Item>(spawnable, val2, Quaternion.identity); if ((Object)(object)val3 == (Object)null) { why = "Could not create that item."; return false; } if ((Object)(object)val != (Object)null) { val3.SetSyncedHolder(val, true); } val3.LoadFromSave(ToSaved(storedItem, (byte)num)); Creature val4 = null; try { val4 = val3.Creature; } catch { } if ((Object)(object)val4 != (Object)null) { Log.Info("withdraw " + storedItem.Label + ": stored " + storedItem.Weight.ToString("0.000") + "x, after LoadFromSave " + ((Item)val4).RandomizedWeight.ToString("0.000") + "x"); val4.ServerKillOnSpawn(); if (storedItem.IsDripCreature) { val4.SetDrip(); } } ServerManager serverManager = InstanceFinder.ServerManager; if ((Object)(object)serverManager == (Object)null) { Object.Destroy((Object)(object)((Component)val3).gameObject); why = "The server is not running."; return false; } serverManager.Spawn(((Component)val3).gameObject, (NetworkConnection)null, default(Scene)); if ((Object)(object)val4 != (Object)null) { Log.Info("withdraw " + storedItem.Label + ": after spawn " + ((Item)val4).RandomizedWeight.ToString("0.000") + "x"); } inv.AddItem((byte)num, val3); Items.RemoveAt(index); SaveNow(); Log.Info("took " + storedItem.Label + " out of storage into slot " + (num + 1) + " (" + Items.Count + "/" + Capacity() + ")"); return true; } catch (Exception e) { Log.Ex("Backpack.Withdraw", e); why = "Something went wrong taking that out - see the log."; return false; } } private static string PathFor(string saveName) { return ModFolder + "/" + saveName + ".backpack.dat"; } private static string CurrentSaveName() { try { ServerSaveObject curServerSave = SaveManager.CurServerSave; return (curServerSave != null && !string.IsNullOrEmpty(curServerSave.Name)) ? curServerSave.Name : ""; } catch { return ""; } } public static void LoadForCurrentSave() { try { Cfg.EnsureLoaded(); _saveName = CurrentSaveName(); Items.Clear(); if (!string.IsNullOrEmpty(_saveName)) { string path = PathFor(_saveName); if (File.Exists(path)) { ReadFile(path); } Log.Info("storage: " + Items.Count + " item(s) held for save '" + _saveName + "' (capacity " + Capacity() + ")"); } } catch (Exception e) { Log.Ex("Backpack.LoadForCurrentSave", e); } } public static void SaveNow() { try { string text = CurrentSaveName(); if (string.IsNullOrEmpty(text)) { text = _saveName; } if (!string.IsNullOrEmpty(text)) { Directory.CreateDirectory(ModFolder); WriteFile(PathFor(text)); } } catch (Exception e) { Log.Ex("Backpack.SaveNow", e); } } private static void WriteFile(string path) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# How To Fish - Extended storage. Safe to delete: you lose what is in it, nothing else."); stringBuilder.AppendLine("v=1"); foreach (StoredItem item in Items) { stringBuilder.Append(item.ItemID).Append('|').Append(item.Weight.ToString("0.#####", CultureInfo.InvariantCulture)) .Append('|') .Append(item.Cookness.ToString("0.#####", CultureInfo.InvariantCulture)) .Append('|') .Append(item.BettingMultiplier.ToString("0.#####", CultureInfo.InvariantCulture)) .Append('|') .Append(item.KillScoreMultiplier.ToString("0.#####", CultureInfo.InvariantCulture)) .Append('|') .Append(item.IsDripCreature ? 1 : 0) .Append('|') .Append(item.SkinIndex) .Append('|') .Append(item.Sharpness) .Append('|') .Append(item.Sight) .Append('|') .Append(item.BarrelAttachment) .Append('|') .Append(item.AmmoType) .Append('|') .Append(item.ExtendedMag ? 1 : 0) .Append('|') .Append(item.LaserSight ? 1 : 0) .Append('|') .Append(item.Worth.ToString(CultureInfo.InvariantCulture)) .Append('|') .Append(Sanitise(item.Label)) .AppendLine(); } File.WriteAllText(path, stringBuilder.ToString()); } private static string Sanitise(string s) { if (string.IsNullOrEmpty(s)) { return "?"; } return s.Replace('|', '/').Replace('\r', ' ').Replace('\n', ' ') .Trim(); } private static void ReadFile(string path) { string[] array = File.ReadAllLines(path); foreach (string text in array) { string text2 = text.Trim(); if (text2.Length == 0 || text2[0] == '#' || text2.StartsWith("v=", StringComparison.Ordinal)) { continue; } string[] array2 = text2.Split(new char[1] { '|' }, 15); if (array2.Length >= 14) { try { StoredItem storedItem = new StoredItem(); storedItem.ItemID = (byte)Mathf.Clamp(ParseInt(array2[0]), 0, 255); storedItem.Weight = ParseFloat(array2[1], 1f); storedItem.Cookness = ParseFloat(array2[2], 0f); storedItem.BettingMultiplier = ParseFloat(array2[3], 0f); storedItem.KillScoreMultiplier = ParseFloat(array2[4], 0f); storedItem.IsDripCreature = ParseInt(array2[5]) != 0; storedItem.SkinIndex = (byte)Mathf.Clamp(ParseInt(array2[6]), 0, 255); storedItem.Sharpness = (byte)Mathf.Clamp(ParseInt(array2[7]), 0, 255); storedItem.Sight = (byte)Mathf.Clamp(ParseInt(array2[8]), 0, 255); storedItem.BarrelAttachment = (byte)Mathf.Clamp(ParseInt(array2[9]), 0, 255); storedItem.AmmoType = (byte)Mathf.Clamp(ParseInt(array2[10]), 0, 255); storedItem.ExtendedMag = ParseInt(array2[11]) != 0; storedItem.LaserSight = ParseInt(array2[12]) != 0; storedItem.Worth = ParseInt(array2[13]); storedItem.Label = ((array2.Length > 14 && array2[14].Trim().Length > 0) ? array2[14].Trim() : "?"); Items.Add(storedItem); } catch (Exception e) { Log.Ex("Backpack.ReadFile line", e); } } } } private static int ParseInt(string s) { int result; return int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out result) ? result : 0; } private static float ParseFloat(string s, float d) { float result; return float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out result) ? result : d; } private static string Wire(string s) { if (string.IsNullOrEmpty(s)) { return "?"; } return s.Replace('~', '-').Replace('|', '/').Replace(';', ',') .Replace('=', '-') .Trim(); } public static string EncodePage(int page, int perPage) { StringBuilder stringBuilder = new StringBuilder(); int value = Capacity(); stringBuilder.Append(page).Append('~').Append(Items.Count) .Append('~') .Append(value); int num = Mathf.Max(0, page * perPage); for (int i = num; i < Items.Count && i < num + perPage; i++) { StoredItem storedItem = Items[i]; stringBuilder.Append('~').Append(i).Append('|') .Append(storedItem.Weight.ToString("0.###", CultureInfo.InvariantCulture)) .Append('|') .Append(storedItem.Worth.ToString(CultureInfo.InvariantCulture)) .Append('|') .Append(Wire(storedItem.Label)); } return stringBuilder.ToString(); } public static void ApplyRemotePage(string payload) { try { if (string.IsNullOrEmpty(payload)) { return; } string[] array = payload.Split('~'); if (array.Length < 3) { return; } int num = ParseInt(array[0]); int num2 = ParseInt(array[1]); int num3 = ParseInt(array[2]); List<StoredItem> list = new List<StoredItem>(); for (int i = 3; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { '|' }, 4); if (array2.Length >= 4) { StoredItem storedItem = new StoredItem(); storedItem.Weight = ParseFloat(array2[1], 1f); storedItem.Worth = ParseInt(array2[2]); storedItem.Label = ((array2[3].Trim().Length > 0) ? array2[3].Trim() : "?"); list.Add(storedItem); } } RemotePage = Mathf.Max(0, num); RemoteCount = Mathf.Max(0, num2); RemoteCapacity = Mathf.Max(0, num3); RemoteItems.Clear(); RemoteItems.AddRange(list); } catch (Exception e) { Log.Ex("Backpack.ApplyRemotePage", e); } } public static string Summary() { try { Cfg.EnsureLoaded(); long num = 0L; foreach (StoredItem item in Items) { num += item.Worth; } return "storage: " + Items.Count + "/" + Capacity() + " item(s), worth about $" + num.ToString("N0") + " when stored"; } catch (Exception ex) { return "storage unavailable: " + ex.Message; } } } public class BackpackPanel : MonoBehaviour { private enum Tab { Storage, Trophies, Credits } private static BackpackPanel _instance; private static readonly Color Shade = UiKit.Shade; private static readonly Color PanelBg = UiKit.PanelBg; private static readonly Color HeaderBg = UiKit.HeaderBg; private static readonly Color CellBg = UiKit.CellBg; private static readonly Color CellEmpty = UiKit.CellEmpty; private static readonly Color TabOn = UiKit.TabOn; private static readonly Color TabOff = UiKit.TabOff; private static readonly Color Gold = UiKit.Gold; private static readonly Color TextLight = UiKit.TextLight; private static readonly Color TextDim = UiKit.TextDim; private static readonly Color Warn = UiKit.Warn; private const float PanelW = 1160f; private const float PanelH = 700f; private const float HeaderH = 58f; private const float FooterH = 44f; private const int StorageCols = 6; private const int StorageRows = 5; private const int TrophyRows = 11; private const int CreditCols = 3; private const int CreditRows = 8; private Canvas _canvas; private RectTransform _root; private RectTransform _body; private TextMeshProUGUI _titleText; private TextMeshProUGUI _footerText; private TextMeshProUGUI _countText; private Image _tabStorageBg; private Image _tabTrophiesBg; private Image _tabCreditsBg; private Tab _tab = Tab.Storage; private int _page; private float _messageUntil; private Key _toggleKey = (Key)36; private bool _built; private readonly UiKit.Hotspots _hotspots = new UiKit.Hotspots(); private int _lastRemoteStamp = -1; public static bool IsOpen { get; private set; } public static void Bootstrap() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown try { Cfg.EnsureLoaded(); if (Cfg.EnableBackpack && !((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("HTFX_BackpackPanel"); Object.DontDestroyOnLoad((Object)(object)val); _instance = val.AddComponent<BackpackPanel>(); Log.Info("storage panel ready - press " + Cfg.BackpackKey + " to open"); WarnIfKeyTaken(); } } catch (Exception e) { Log.Ex("BackpackPanel.Bootstrap", e); } } private unsafe static void WarnIfKeyTaken() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) try { if (!Enum.TryParse<Key>(Cfg.BackpackKey, ignoreCase: true, out Key result)) { return; } PlayerInput input = GameInfo.Input; if ((Object)(object)input == (Object)null) { return; } InputActionAsset actions = input.actions; if ((Object)(object)actions == (Object)null) { return; } string value = "/" + ((object)(*(Key*)(&result))/*cast due to .constrained prefix*/).ToString().ToLowerInvariant(); List<string> list = new List<string>(); Enumerator<InputActionMap> enumerator = actions.actionMaps.GetEnumerator(); try { while (enumerator.MoveNext()) { InputActionMap current = enumerator.Current; if (current == null) { continue; } Enumerator<InputAction> enumerator2 = current.actions.GetEnumerator(); try { while (enumerator2.MoveNext()) { InputAction current2 = enumerator2.Current; if (current2 == null) { continue; } try { Enumerator<InputBinding> enumerator3 = current2.bindings.GetEnumerator(); try { while (enumerator3.MoveNext()) { InputBinding current3 = enumerator3.Current; string text = (string.IsNullOrEmpty(((InputBinding)(ref current3)).overridePath) ? ((InputBinding)(ref current3)).path : ((InputBinding)(ref current3)).overridePath); if (!string.IsNullOrEmpty(text) && text.IndexOf("Keyboard", StringComparison.OrdinalIgnoreCase) >= 0 && text.ToLowerInvariant().EndsWith(value, StringComparison.Ordinal)) { string name = current2.name; if (!string.IsNullOrEmpty(name) && !list.Contains(name)) { list.Add(name); } } } } finally { ((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose(); } } catch { } } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } if (list.Count == 0) { Log.Info("the storage key (" + ((object)(*(Key*)(&result))/*cast due to .constrained prefix*/).ToString() + ") is not bound to anything in the game."); return; } Log.Warn("the storage key (" + ((object)(*(Key*)(&result))/*cast due to .constrained prefix*/).ToString() + ") is also the game's key for: " + string.Join(", ", list.ToArray()) + ". Opening storage will do both. Change BackpackKey in " + Cfg.Path + " to a free key."); } catch (Exception e) { Log.Ex("BackpackPanel.WarnIfKeyTaken", e); } } private void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (!Enum.TryParse<Key>(Cfg.BackpackKey, ignoreCase: true, out _toggleKey)) { _toggleKey = (Key)36; } } private void Update() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) try { Keyboard current = Keyboard.current; if (current != null && ((ButtonControl)current[_toggleKey]).wasPressedThisFrame) { Toggle(); } if (!IsOpen) { return; } if (Paused()) { Close(); return; } PollRemote(); HandleHover(); if (Mouse.current != null && Mouse.current.leftButton.wasPressedThisFrame) { HandleClick(); } } catch (Exception e) { Log.Ex("BackpackPanel.Update", e); } } private static bool Paused() { try { if (PauseManager.IsPaused) { return true; } } catch { } try { if (MainMenuManager.IsInMenu) { return true; } } catch { } return false; } public void Toggle() { if (IsOpen) { Close(); } else { Open(); } } private void Open() { try { Cfg.EnsureLoaded(); if (Cfg.EnableBackpack && !Paused()) { if (!_built) { Build(); _built = true; } if (!((Object)(object)_canvas == (Object)null)) { IsOpen = true; ((Component)_canvas).gameObject.SetActive(true); _page = 0; _messageUntil = 0f; SetCursor(show: true); RequestPageIfClient(); Refresh(); } } } catch (Exception e) { Log.Ex("BackpackPanel.Open", e); } } private void Close() { try { IsOpen = false; if ((Object)(object)_canvas != (Object)null) { ((Component)_canvas).gameObject.SetActive(false); } SetCursor(show: false); Backpack.SaveNow(); } catch (Exception e) { Log.Ex("BackpackPanel.Close", e); } } private static void SetCursor(bool show) { try { PlayerCamera.ToggleMouse(show); } catch (Exception e) { Log.Ex("BackpackPanel.SetCursor", e); } } private void HandleHover() { _hotspots.Hover(); } private void HandleClick() { _hotspots.Click(); } private void Say(string text, bool warn) { //IL_0040: 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) _messageUntil = Time.unscaledTime + 4f; if ((Object)(object)_footerText != (Object)null) { ((TMP_Text)_footerText).text = text; ((Graphic)_footerText).color = (warn ? Warn : TextDim); } } private static TMP_FontAsset Font() { return UiKit.Font(); } private static RectTransform NewRect(string name, Transform parent) { return UiKit.NewRect(name, parent); } private static Image NewImage(string name, Transform parent, Color color) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) return UiKit.NewImage(name, parent, color); } private static TextMeshProUGUI NewText(string name, Transform parent, string text, int size, Color color, TextAlignmentOptions align) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return UiKit.NewText(name, parent, text, size, color, align); } private static void Place(RectTransform rt, float x, float y, float w, float h) { UiKit.Place(rt, x, y, w, h); } private static void Stretch(RectTransform rt) { UiKit.Stretch(rt); } private void Build() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0097: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_024d: 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_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("HTFX_BackpackCanvas", new Type[3] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler) }); Object.DontDestroyOnLoad((Object)(object)val); val.transform.SetParent(((Component)this).transform, false); _canvas = val.GetComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 5000; CanvasScaler component = val.GetComponent<CanvasScaler>(); component.uiScaleMode = (ScaleMode)1; component.referenceResolution = new Vector2(1920f, 1080f); component.screenMatchMode = (ScreenMatchMode)0; component.matchWidthOrHeight = 0.5f; Image val2 = NewImage("Shade", val.transform, Shade); Stretch(((Graphic)val2).rectTransform); Image val3 = NewImage("Panel", val.transform, PanelBg); _root = ((Graphic)val3).rectTransform; RectTransform root = _root; RectTransform root2 = _root; Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(0.5f, 0.5f); root2.anchorMax = val4; root.anchorMin = val4; _root.pivot = new Vector2(0.5f, 0.5f); _root.anchoredPosition = Vector2.zero; _root.sizeDelta = new Vector2(1160f, 700f); Image val5 = NewImage("Header", (Transform)(object)_root, HeaderBg); Place(((Graphic)val5).rectTransform, 0f, 0f, 1160f, 58f); _titleText = NewText("Title", (Transform)(object)((Graphic)val5).rectTransform, "Storage", 24, Gold, (TextAlignmentOptions)513); Place(((TMP_Text)_titleText).rectTransform, 20f, 12f, 300f, 34f); _countText = NewText("Count", (Transform)(object)((Graphic)val5).rectTransform, "", 16, TextDim, (TextAlignmentOptions)516); Place(((TMP_Text)_countText).rectTransform, 900f, 18f, 240f, 26f); _tabStorageBg = NewImage("TabStorage", (Transform)(object)((Graphic)val5).rectTransform, TabOn); Place(((Graphic)_tabStorageBg).rectTransform, 300f, 12f, 150f, 34f); TextMeshProUGUI val6 = NewText("TabStorageText", (Transform)(object)((Graphic)_tabStorageBg).rectTransform, "Storage", 16, TextLight, (TextAlignmentOptions)514); Stretch(((TMP_Text)val6).rectTransform); _tabTrophiesBg = NewImage("TabTrophies", (Transform)(object)((Graphic)val5).rectTransform, TabOff); Place(((Graphic)_tabTrophiesBg).rectTransform, 458f, 12f, 150f, 34f); TextMeshProUGUI val7 = NewText("TabTrophiesText", (Transform)(object)((Graphic)_tabTrophiesBg).rectTransform, "Trophies", 16, TextLight, (TextAlignmentOptions)514); Stretch(((TMP_Text)val7).rectTransform); _tabCreditsBg = NewImage("TabCredits", (Transform)(object)((Graphic)val5).rectTransform, TabOff); Place(((Graphic)_tabCreditsBg).rectTransform, 616f, 12f, 150f, 34f); TextMeshProUGUI val8 = NewText("TabCreditsText", (Transform)(object)((Graphic)_tabCreditsBg).rectTransform, "Credits", 16, TextLight, (TextAlignmentOptions)514); Stretch(((TMP_Text)val8).rectTransform); _body = NewRect("Body", (Transform)(object)_root); Place(_body, 0f, 58f, 1160f, 598f); _footerText = NewText("Footer", (Transform)(object)_root, "", 14, TextDim, (TextAlignmentOptions)513); Place(((TMP_Text)_footerText).rectTransform, 20f, 666f, 1120f, 26f); val.SetActive(false); } private void ClearBody() { _hotspots.Clear(); if (!((Object)(object)_body == (Object)null)) { for (int num = ((Transform)_body).childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)((Transform)_body).GetChild(num)).gameObject); } } } private UiKit.Hotspot Clickable(Image bg, Action onClick) { return _hotspots.Add(bg, onClick); } private void Refresh() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0080: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) try { if (_built && !((Object)(object)_canvas == (Object)null)) { ClearBody(); ((Graphic)_tabStorageBg).color = ((_tab == Tab.Storage) ? TabOn : TabOff); ((Graphic)_tabTrophiesBg).color = ((_tab == Tab.Trophies) ? TabOn : TabOff); ((Graphic)_tabCreditsBg).color = ((_tab == Tab.Credits) ? TabOn : TabOff); Clickable(_tabStorageBg, delegate { _tab = Tab.Storage; _page = 0; Refresh(); }).Base = ((Graphic)_tabStorageBg).color; Clickable(_tabTrophiesBg, delegate { _tab = Tab.Trophies; _page = 0; Refresh(); }).Base = ((Graphic)_tabTrophiesBg).color; Clickable(_tabCreditsBg, delegate { _tab = Tab.Credits; _page = 0; Refresh(); }).Base = ((Graphic)_tabCreditsBg).color; if (_tab == Tab.Storage) { DrawStorage(); } else if (_tab == Tab.Trophies) { DrawTrophies(); } else { DrawCredits(); } if ((Object)(object)_footerText != (Object)null && Time.unscaledTime >= _messageUntil) { ((Graphic)_footerText).color = TextDim; ((TMP_Text)_footerText).text = ((_tab != Tab.Storage) ? ((_tab == Tab.Trophies) ? ("Records for this save. Press " + ((object)Unsafe.As<Key, Key>(ref _toggleKey)/*cast due to .constrained prefix*/).ToString() + " to close.") : ("Thanks for playing. Press " + ((object)Unsafe.As<Key, Key>(ref _toggleKey)/*cast due to .constrained prefix*/).ToString() + " to close.")) : (Net.IsServer ? ("Click a pocket to store it. Click a stored item to take it back. Mouse only - press " + ((object)Unsafe.As<Key, Key>(ref _toggleKey)/*cast due to .constrained prefix*/).ToString() + " to close.") : ("Shared with the host. Click to ask - the host's game does the moving. Press " + ((object)Unsafe.As<Key, Key>(ref _toggleKey)/*cast due to .constrained prefix*/).ToString() + " to close."))); } } } catch (Exception e) { Log.Ex("BackpackPanel.Refresh", e); } } private void RequestPageIfClient() { try { if (!Net.IsServer) { Player localPlayer = Player.LocalPlayer; if (!((Object)(object)localPlayer == (Object)null)) { Net.SendStorageSync(localPlayer, _page); } } } catch (Exception e) { Log.Ex("BackpackPanel.RequestPageIfClient", e); } } private void PollRemote() { if (!Net.IsServer) { int num = Backpack.RemoteCount * 1000 + Backpack.RemoteItems.Count * 7 + Backpack.RemotePage; if (num != _lastRemoteStamp) { _lastRemoteStamp = num; Refresh(); } } } private PlayerInventory Inventory() { try { Player localPlayer = Player.LocalPlayer; return ((Object)(object)localPlayer != (Object)null) ? localPlayer.Inventory : null; } catch { return null; } } private void DrawStorage() { //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_0525: Unknown result type (might be due to invalid IL or missing references) //IL_054b: Unknown result type (might be due to invalid IL or missing references) //IL_0530: 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_062c: Unknown result type (might be due to invalid IL or missing references) PlayerInventory inv = Inventory(); bool isServer = Net.IsServer; List<StoredItem> list = (isServer ? Backpack.Items : Backpack.RemoteItems); int num = (isServer ? Backpack.Capacity() : Backpack.RemoteCapacity); int num2 = (isServer ? Backpack.Items.Count : Backpack.RemoteCount); int num3 = ((!isServer) ? (Backpack.RemotePage * 6 * 5) : 0); ((TMP_Text)_titleText).text = "Storage"; ((TMP_Text)_countText).text = num2 + " / " + num; Place(((TMP_Text)NewText("PocketsLabel", (Transform)(object)_body, "Pockets", 17, Gold, (TextAlignmentOptions)513)).rectTransform, 24f, 14f, 240f, 24f); int num4 = Backpack.HotbarSlots(inv); for (int i = 0; i < 9; i++) { int num5 = i % 3; int num6 = i / 3; float x = 24f + (float)num5 * 100f; float y = 48f + (float)num6 * 92f; bool flag = i < num4; Item val = (flag ? Backpack.HotbarItem(inv, i) : null); Image val2 = NewImage("Pocket" + i, (Transform)(object)_body, (Color)((!flag) ? new Color(0.07f, 0.08f, 0.1f, 1f) : (((Object)(object)val != (Object)null) ? CellBg : CellEmpty))); Place(((Graphic)val2).rectTransform, x, y, 92f, 84f); if (!flag) { TextMeshProUGUI val3 = NewText("PocketLocked" + i, (Transform)(object)((Graphic)val2).rectTransform, "locked", 11, new Color(0.35f, 0.38f, 0.43f, 1f), (TextAlignmentOptions)514); Stretch(((TMP_Text)val3).rectTransform); continue; } TextMeshProUGUI val4 = NewText("PocketNum" + i, (Transform)(object)((Graphic)val2).rectTransform, (i + 1).ToString(), 11, TextDim, (TextAlignmentOptions)257); Place(((TMP_Text)val4).rectTransform, 6f, 4f, 20f, 16f); if ((Object)(object)val == (Object)null) { TextMeshProUGUI val5 = NewText("PocketEmpty" + i, (Transform)(object)((Graphic)val2).rectTransform, "-", 14, new Color(0.3f, 0.34f, 0.39f, 1f), (TextAlignmentOptions)514); Stretch(((TMP_Text)val5).rectTransform); continue; } int tier = 0; try { tier = Variants.TierOf(val); } catch { } string text = "?"; try { text = val.GetName(); } catch { } TextMeshProUGUI val6 = NewText("PocketName" + i, (Transform)(object)((Graphic)val2).rectTransform, text, 12, TierColor(tier), (TextAlignmentOptions)514); Place(((TMP_Text)val6).rectTransform, 4f, 20f, 84f, 44f); int index = i; Clickable(val2, delegate { DoDeposit(index); }); } Image val7 = NewImage("StowAll", (Transform)(object)_body, new Color(0.16f, 0.22f, 0.18f, 1f)); Place(((Graphic)val7).rectTransform, 24f, 330f, 292f, 34f); TextMeshProUGUI val8 = NewText("StowAllText", (Transform)(object)((Graphic)val7).rectTransform, "Stow everything", 14, TextLight, (TextAlignmentOptions)514); Stretch(((TMP_Text)val8).rectTransform); Clickable(val7, DoDepositAll); float num7 = 344f; Place(((TMP_Text)NewText("StorageLabel", (Transform)(object)_body, "In storage", 17, Gold, (TextAlignmentOptions)513)).rectTransform, num7, 14f, 300f, 24f); int num8 = Mathf.Max(num, num2); int num9 = 30; int num10 = Mathf.Max(1, Mathf.CeilToInt((float)num8 / (float)num9)); _page = Mathf.Clamp(_page, 0, num10 - 1); for (int num11 = 0; num11 < num9; num11++) { int num12 = _page * num9 + num11; if (num12 >= num8) { break; } int num13 = num11 % 6; int num14 = num11 / 6; float x2 = num7 + (float)num13 * 126f; float y2 = 48f + (float)num14 * 96f; int num15 = num12 - num3; bool flag2 = num15 >= 0 && num15 < list.Count; bool flag3 = num12 >= num; Image val9 = NewImage("Slot" + num12, (Transform)(object)_body, (Color)((!flag2) ? CellEmpty : (flag3 ? new Color(0.22f, 0.14f, 0.12f, 1f) : CellBg))); Place(((Graphic)val9).rectTransform, x2, y2, 118f, 88f); if (flag2) { StoredItem storedItem = list[num15]; TextMeshProUGUI val10 = NewText("SlotName" + num12, (Transform)(object)((Graphic)val9).rectTransform, storedItem.Label, 12, TierColor(storedItem.Tier), (TextAlignmentOptions)258); Place(((TMP_Text)val10).rectTransform, 5f, 6f, 108f, 40f); TextMeshProUGUI val11 = NewText("SlotSub" + num12, (Transform)(object)((Graphic)val9).rectTransform, storedItem.Weight.ToString("0.00") + "x $" + storedItem.Worth.ToString("N0"), 11, TextDim, (TextAlignmentOptions)1026); Place(((TMP_Text)val11).rectTransform, 5f, 62f, 108f, 20f); int index2 = num12; Clickable(val9, delegate { DoWithdraw(index2); }); } } if (num10 > 1) { DrawPager(num7, 534f, 748f, num10); } } private void DrawPager(float x, float y, float w, int pages) { //IL_0035: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) Image val = NewImage("PagePrev", (Transform)(object)_body, new Color(0.14f, 0.17f, 0.22f, 1f)); Place(((Graphic)val).rectTransform, x, y, 90f, 30f); TextMeshProUGUI val2 = NewText("PagePrevText", (Transform)(object)((Graphic)val).rectTransform, "< Prev", 13, TextLight, (TextAlignmentOptions)514); Stretch(((TMP_Text)val2).rectTransform); Clickable(val, delegate { _page = Mathf.Max(0, _page - 1); RequestPageIfClient(); Refresh(); }); TextMeshProUGUI val3 = NewText("PageLabel", (Transform)(object)_body, "Page " + (_page + 1) + " of " + pages, 13, TextDim, (TextAlignmentOptions)514); Place(((TMP_Text)val3).rectTransform, x + 96f, y + 6f, w - 192f, 20f); Image val4 = NewImage("PageNext", (Transform)(object)_body, new Color(0.14f, 0.17f, 0.22f, 1f)); Place(((Graphic)val4).rectTransform, x + w - 90f, y, 90f, 30f); TextMeshProUGUI val5 = NewText("PageNextText", (Transform)(object)((Graphic)val4).rectTransform, "Next >", 13, TextLight, (TextAlignmentOptions)514); Stretch(((TMP_Text)val5).rectTransform); Clickable(val4, delegate { _page = Mathf.Min(pages - 1, _page + 1); RequestPageIfClient(); Refresh(); }); } private void DrawTrophies() { //IL_0115: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_026e: 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_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)_titleText).text = "Trophies"; ((TMP_Text)_countText).text = CatchStats.TotalCaught(CatchStats.PerSave).ToString("N0") + " this save"; List<string> list = new List<string>(CatchStats.PerSave.Keys); list.Sort(StringComparer.OrdinalIgnoreCase); if (list.Count == 0) { TextMeshProUGUI val = NewText("TrophyEmpty", (Transform)(object)_body, "Nothing caught yet - go fishing.", 16, TextDim, (TextAlignmentOptions)514); Place(((TMP_Text)val).rectTransform, 0f, 120f, 1160f, 30f); return; } int num = Mathf.Max(1, Mathf.CeilToInt((float)list.Count / 11f)); _page = Mathf.Clamp(_page, 0, num - 1); TextMeshProUGUI val2 = NewText("TrophyHead", (Transform)(object)_body, "Lifetime: " + CatchStats.TotalCaught(CatchStats.Lifetime).ToString("N0") + " caught", 14, TextDim, (TextAlignmentOptions)513); Place(((TMP_Text)val2).rectTransform, 24f, 12f, 600f, 22f); for (int i = 0; i < 11; i++) { int num2 = _page * 11 + i; if (num2 >= list.Count) { break; } SpeciesRecord speciesRecord = CatchStats.PerSave[list[num2]]; Image val3 = NewImage("TrophyRow" + i, (Transform)(object)_body, (i % 2 == 0) ? CellBg : CellEmpty); Place(((Graphic)val3).rectTransform, 24f, 42f + (float)i * 48f, 1112f, 44f); TextMeshProUGUI val4 = NewText("TrophyName" + i, (Transform)(object)((Graphic)val3).rectTransform, speciesRecord.Species, 15, TextLight, (TextAlignmentOptions)513); Place(((TMP_Text)val4).rectTransform, 12f, 4f, 260f, 36f); TextMeshProUGUI val5 = NewText("TrophyCount" + i, (Transform)(object)((Graphic)val3).rectTransform, speciesRecord.TotalCaught.ToString("N0") + " caught", 13, TextDim, (TextAlignmentOptions)513); Place(((TMP_Text)val5).rectTransform, 280f, 4f, 130f, 36f); string text = "ordinary only"; Color color = TextDim; for (int num3 = Variants.Tiers.Length; num3 >= 1; num3--) { if (speciesRecord.TierCounts.Length > num3 && speciesRecord.TierCounts[num3] > 0) { text = Variants.Tiers[num3 - 1].Name + " x" + speciesRecord.TierCounts[num3] + " best " + speciesRecord.TierBestWeight[num3].ToString("0.000") + "x"; color = TierColor(num3); break; } } TextMeshProUGUI val6 = NewText("TrophyBest" + i, (Transform)(object)((Graphic)val3).rectTransform, text, 13, color, (TextAlignmentOptions)513); Place(((TMP_Text)val6).rectTransform, 420f, 4f, 420f, 36f); float num4 = ((speciesRecord.TierBestWeight.Length != 0) ? speciesRecord.TierBestWeight[0] : 0f); TextMeshProUGUI val7 = NewText("TrophyOrd" + i, (Transform)(object)((Graphic)val3).rectTransform, (num4 > 0f) ? ("best ordinary " + num4.ToString("0.000") + "x") : "", 12, TextDim, (TextAlignmentOptions)516); Place(((TMP_Text)val7).rectTransform, 852f, 4f, 248f, 36f); } if (num > 1) { DrawPager(24f, 574f, 1112f, num); } } private void DrawCredits() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)_titleText).text = "Credits"; ((TMP_Text)_countText).text = "v" + ModInfo.Display; TextMeshProUGUI val = NewText("CreditTitle", (Transform)(object)_body, "How To Fish - Extended", 26, Gold, (TextAlignmentOptions)514); Place(((TMP_Text)val).rectTransform, 0f, 18f, 1160f, 34f); float y = 66f; y = Section("Made by", y); for (int i = 0; i < Credits.Authors.Length; i++) { CreditEntry creditEntry = Credits.Authors[i]; TextMeshProUGUI val2 = NewText("Author" + i, (Transform)(object)_body, creditEntry.Name + ((creditEntry.Note != null) ? (" - " + creditEntry.Note) : ""), 17, TextLight, (TextAlignmentOptions)514); Place(((TMP_Text)val2).rectTransform, 0f, y, 1160f, 24f); y += 26f; } y += 14f; y = Section("Contributors", y); if (!Credits.HasTesters) { TextMeshProUGUI val3 = NewText("NoTesters", (Transform)(object)_body, "The people who broke this before you had to.", 14, TextDim, (TextAlignmentOptions)514); Place(((TMP_Text)val3).rectTransform, 0f, y, 1160f, 22f); y += 30f; } else { int num = 24; int num2 = Mathf.Max(1, Mathf.CeilToInt((float)Credits.Testers.Length / (float)num)); _page = Mathf.Clamp(_page, 0, num2 - 1); float num3 = 354.66666f; float num4 = y; for (int j = 0; j < num; j++) { int num5 = _page * num + j; if (num5 >= Credits.Testers.Length) { break; } CreditEntry creditEntry2 = Credits.Testers[num5]; int num6 = j % 3; int num7 = j / 3; float x = 48f + (float)num6 * num3; float num8 = num4 + (float)num7 * 34f; TextMeshProUGUI val4 = NewText("Tester" + num5, (Transform)(object)_body, creditEntry2.Name, 16, TextLight, (TextAlignmentOptions)258); Place(((TMP_Text)val4).rectTransform, x, num8, num3 - 12f, 20f); if (creditEntry2.Note != null) { TextMeshProUGUI val5 = NewText("TesterNote" + num5, (Transform)(object)_body, creditEntry2.Note, 12, TextDim, (TextAlignmentOptions)258); Place(((TMP_Text)val5).rectTransform, x, num8 + 17f, num3 - 12f, 16f); } } int num9 = Mathf.CeilToInt((float)Mathf.Min(num, Credits.Testers.Length - _page * num) / 3f); y = num4 + (float)num9 * 34f + 8f; if (num2 > 1) { DrawPager(48f, y, 1064f, num2); y += 38f; } } y += 10f; y = Section("Thanks", y); for (int k = 0; k < Credits.Thanks.Length; k++) { TextMeshProUGUI val6 = NewText("Thanks" + k, (Transform)(object)_body, Credits.Thanks[k], 14, TextDim, (TextAlignmentOptions)514); Place(((TMP_Text)val6).rectTransform, 0f, y, 1160f, 20f); y += 22f; } } private float Section(string label, float y) { //IL_0015: 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) TextMeshProUGUI val = NewText("Head_" + label, (Transform)(object)_body, label, 15, Gold, (TextAlignmentOptions)514); Place(((TMP_Text)val).rectTransform, 0f, y, 1160f, 22f); Image val2 = NewImage("Rule_" + label, (Transform)(object)_body, new Color(0.22f, 0.26f, 0.32f, 1f)); Place(((Graphic)val2).rectTransform, 440f, y + 24f, 280f, 1f); return y + 34f; } private static Color TierColor(int tier) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) try { if (tier <= 0 || tier > Variants.Tiers.Length) { return TextLight; } string color = Variants.Tiers[tier - 1].Color; if (string.IsNullOrEmpty(color) || color.Length < 7 || color[0] != '#') { return TextLight; } int num = Convert.ToInt32(color.Substring(1, 2), 16); int num2 = Convert.ToInt32(color.Substring(3, 2), 16); int num3 = Convert.ToInt32(color.Substring(5, 2), 16); return new Color((float)num / 255f, (float)num2 / 255f, (float)num3 / 255f, 1f); } catch { return TextLight; } } private void DoDeposit(int slot) { if (!Net.IsServer) { Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null) { Say("No player.", warn: true); return; } Net.SendStorageDeposit(localPlayer, slot); Say("Asking the host...", warn: false); } else { if (Backpack.Deposit(Inventory(), slot, out var why)) { Say("Stored.", warn: false); } else { Say(why, warn: true); } Refresh(); } } private void DoDepositAll() { if (!Net.IsServer) { PlayerInventory val = Inventory(); Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null) { Say("No player.", warn: true); return; } int num = 0; int num2 = Backpack.HotbarSlots(val); Item val2 = null; try { val2 = (((Object)(object)val != (Object)null) ? val.SyncedCurItem : null); } catch { } for (int i = 0; i < num2; i++) { Item val3 = Backpack.HotbarItem(val, i); if (!((Object)(object)val3 == (Object)null) && (!((Object)(object)val2 != (Object)null) || !((Object)(object)val3 == (Object)(object)val2))) { Net.SendStorageDeposit(localPlayer, i); num++; } } Say((num > 0) ? ("Asking the host to stow " + num + "...") : "Nothing to stow.", num == 0); } else { string why; int num3 = Backpack.DepositAll(Inventory(), out why); if (num3 > 0) { Say("Stored " + num3 + " item" + ((num3 == 1) ? "" : "s") + ((why.Length > 0) ? (" - then stopped: " + why) : "."), why.Length > 0); } else { Say(why, warn: true); } Refresh(); } } private void DoWithdraw(int index) { if (!Net.IsServer) { Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null) { Say("No player.", warn: true); return; } Net.SendStorageWithdraw(localPlayer, index); Say("Asking the host...", warn: false); } else { if (Backpack.Withdraw(Inventory(), index, out var why)) { Say("Taken out.", warn: false); } else { Say(why, warn: true); } Refresh(); } } } public sealed class SpeciesRecord { public string Species; public int[] TierCounts; public float[] TierBestWeight; public long TotalWorth; public int TotalCaught { get { int num = 0; for (int i = 0; i < TierCounts.Length; i++) { num += TierCounts[i]; } return num; } } public SpeciesRecord(string species, int tiers) { Species = species; TierCounts = new int[tiers + 1]; TierBestWeight = new float[tiers + 1]; } } public static class CatchStats { public static Dictionary<string, SpeciesRecord> PerSave = new Dictionary<string, SpeciesRecord>(StringComparer.OrdinalIgnoreCase); public static Dictionary<string, SpeciesRecord> Lifetime = new Dictionary<string, SpeciesRecord>(StringComparer.OrdinalIgnoreCase); private static string _saveName = ""; private static string _toastText; private static float _toastUntil; private static GUIStyle _toastStyle; private static string ModFolder => Luck.ModFolder; private static int TierCount() { Cfg.EnsureLoaded(); return Variants.Tiers.Length; } private static SpeciesRecord GetOrCreate(Dictionary<string, SpeciesRecord> dict, string species) { if (!dict.TryGetValue(species, out var value)) { value = (dict[species] = new SpeciesRecord(species, TierCount())); } else if (value.TierCounts.Length != TierCount() + 1) { SpeciesRecord speciesRecord2 = new SpeciesRecord(species, TierCount()); for (int i = 0; i < value.TierCounts.Length && i < speciesRecord2.TierCounts.Length; i++) { speciesRecord2.TierCounts[i] = value.TierCounts[i]; speciesRecord2.TierBestWeight[i] = value.TierBestWeight[i]; } speciesRecord2.TotalWorth = value.TotalWorth; value = (dict[species] = speciesRecord2); } return value; } public static string SpeciesOf(Item item) { if ((Object)(object)item == (Object)null) { return "?"; } string text = ((Object)item).name; int num = text.IndexOf("(Clone)"); if (num > 0) { text = text.Substring(0, num).Trim(); } return string.IsNullOrEmpty(text) ? ((object)item).GetType().Name : text; } public static void RecordCatch(Item item) { try { Cfg.EnsureLoaded(); if (Cfg.EnableCatchStats && !((Object)(object)item == (Object)null) && item is Creature) { string text = SpeciesOf(item); int num = Mathf.Clamp(Variants.TierOf(item), 0, TierCount()); float num2; try { num2 = item._syncedRandomWeight.Value; } catch { num2 = 0f; } int b; try { b = item.TotalWorth; } catch { b = 0; } bool flag = false; SpeciesRecord orCreate = GetOrCreate(PerSave, text); orCreate.TierCounts[num]++; if (num2 > orCreate.TierBestWeight[num]) { orCreate.TierBestWeight[num] = num2; flag = true; } SpeciesRecord orCreate2 = GetOrCreate(Lifetime, text); orCreate2.TierCounts[num]++; if (num2 > orCreate2.TierBestWeight[num]) { orCreate2.TierBestWeight[num] = num2; } orCreate2.TotalWorth = SaturateAdd(orCreate2.TotalWorth, b); Log.Info("caught " + text + ((num > 0) ? (" (" + Variants.Tiers[num - 1].Name + ")") : " (ordinary)") + " weight " + num2.ToString("0.000") + "x worth $" + b.ToString("N0") + (flag ? " [new best]" : "")); if (flag) { string text2 = ((num > 0) ? (Variants.Tiers[num - 1].Name + " " + text) : text); Toast("New best: " + text2 + " " + num2.ToString("0.000") + "x"); } SaveForCurrentSave(); SaveLifetime(); } } catch (Exception e) { Log.Ex("CatchStats.RecordCatch", e); } } private static long SaturateAdd(long a, int b) { if (b <= 0) { return a; } if (a > long.MaxValue - b) { return long.MaxValue; } return a + b; } public static void Toast(string text) { _toastText = text; _toastUntil = Time.unscaledTime + Cfg.CatchToastDuration; } public static void DrawToast() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(_toastText) && !(Time.unscaledTime >= _toastUntil)) { if (_toastStyle == null) { _toastStyle = new GUIStyle(GUI.skin.label); _toastStyle.fontSize = 20; _toastStyle.normal.textColor = new Color(1f, 0.85f, 0.2f, 1f); } GUIContent val = new GUIContent(_toastText); float num = 640f; float num2 = 44f; float num3 = ((float)Screen.width - num) / 2f; GUI.Box(new Rect(num3, 76f, num, num2), GUIContent.none); Vector2 val2 = _toastStyle.CalcSize(val); GUI.Label(new Rect(num3 + Mathf.Max(0f, (num - val2.x) / 2f), 80f, num, num2 - 8f), val, _toastStyle); } } private static string PerSavePath(string saveName) { return ModFolder + "/" + saveName + ".catches.dat"; } private static string LifetimePath() { return ModFolder + "/lifetime.catches.dat"; } private static string CurrentSaveName() { try { ServerSaveObject curServerSave = SaveManager.CurServerSave; return (curServerSave != null && !string.IsNullOrEmpty(curServerSave.Name)) ? curServerSave.Name : ""; } catch { return ""; } } public static void LoadForCurrentSave() { try { _saveName = CurrentSaveName(); PerSave = new Dictionary<string, SpeciesRecord>(StringComparer.OrdinalIgnoreCase); if (!string.IsNullOrEmpty(_saveName)) { string path = PerSavePath(_saveName); if (File.Exists(path)) { PerSave = LoadFile(path); } } Log.Info("catch stats: " + TotalCaught(PerSave) + " caught this save ('" + _saveName + "')"); } catch (Exception e) { Log.Ex("CatchStats.LoadForCurrentSave", e); } } public static void SaveForCurrentSave() { try { string text = CurrentSaveName(); if (string.IsNullOrEmpty(text)) { text = _saveName; } if (!string.IsNullOrEmpty(text)) { Directory.CreateDirectory(ModFolder); WriteFile(PerSavePath(text), PerSave); } } catch (Exception e) { Log.Ex("CatchStats.SaveForCurrentSave", e); } } public static void LoadLifetime() { try { Lifetime = new Dictionary<string, SpeciesRecord>(StringComparer.OrdinalIgnoreCase); string path = LifetimePath(); if (File.Exists(path)) { Lifetime = LoadFile(path); } } catch (Exception e) { Log.Ex("CatchStats.LoadLifetime", e); } } public static void SaveLifetime() { try { Directory.CreateDirectory(ModFolder); WriteFile(LifetimePath(), Lifetime); } catch (Exception e) { Log.Ex("CatchStats.SaveLifetime", e); } } public static void ResetForCurrentSave() { PerSave = new Dictionary<string, SpeciesRecord>(StringComparer.OrdinalIgnoreCase); SaveForCurrentSave(); } public static int TotalCaught(Dictionary<string, SpeciesRecord> dict) { int num = 0; foreach (SpeciesRecord value in dict.Values) { num += value.TotalCaught; } return num; } private static void WriteFile(string path, Dictionary<string, SpeciesRecord> dict) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# How To Fish - Extended catch stats. Safe to delete."); stringBuilder.AppendLine("v=1"); foreach (KeyValuePair<string, SpeciesRecord> item in dict) { SpeciesRecord value = item.Value; stringBuilder.Append(item.Key).Append('=').Append(value.TotalWorth.ToString(CultureInfo.InvariantCulture)); for (int i = 0; i < value.TierCounts.Length; i++) { stringBuilder.Append('|').Append(value.TierCounts[i]); } for (int j = 0; j < value.TierBestWeight.Length; j++) { stringBuilder.Append('|').Append(value.TierBestWeight[j].ToString("0.####", CultureInfo.InvariantCulture)); } stringBuilder.AppendLine(); } File.WriteAllText(path, stringBuilder.ToString()); } private static Dictionary<string, SpeciesRecord> LoadFile(string path) { Dictionary<string, SpeciesRecord> dictionary = new Dictionary<string, SpeciesRecord>(StringComparer.OrdinalIgnoreCase); string[] array = File.ReadAllLines(path); foreach (string text in array) { string text2 = text.Trim(); if (text2.Length == 0 || text2[0] == '#') { continue; } int num = text2.IndexOf('='); if (num <= 0) { continue; } string text3 = text2.Substring(0, num).Trim(); if (text3 == "v") { continue; } string[] array2 = text2.Substring(num + 1).Split('|'); if (array2.Length < 1) { continue; } if (!long.TryParse(array2[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { result = 0L; } int num2 = TierCount() + 1; SpeciesRecord speciesRecord = new SpeciesRecord(text3, TierCount()); speciesRecord.TotalWorth = result; for (int j = 0; j < num2 && j + 1 < array2.Length; j++) { if (int.TryParse(array2[j + 1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2)) { speciesRecord.TierCounts[j] = Math.Max(0, result2); } } for (int k = 0; k < num2 && k + 1 + num2 < array2.Length; k++) { if (float.TryParse(array2[k + 1 + num2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3)) { speciesRecord.TierBestWeight[k] = Math.Max(0f, result3); } } dictionary[text3] = speciesRecord; } return dictionary; } public static string Summary() { try { Cfg.EnsureLoaded(); int value = TotalCaught(PerSave); int value2 = TotalCaught(Lifetime); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("catch stats: ").Append(value).Append(" this save, ") .Append(value2) .Append(" lifetime"); if (PerSave.Count > 0) { stringBuilder.Append(" | species:"); foreach (SpeciesRecord value3 in PerSave.Values) { stringBuilder.Append(' ').Append(value3.Species).Append(" x") .Append(value3.TotalCaught); } } return stringBuilder.ToString(); } catch (Exception ex) { return "catch stats unavailable: " + ex.Message; } } } public sealed class CatchToast : MonoBehaviour { private static CatchToast _instance; public static void Bootstrap() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown try { Cfg.EnsureLoaded(); if (Cfg.EnableCatchStats && !((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("HTFX_CatchToast"); Object.DontDestroyOnLoad((Object)(object)val); _instance = val.AddComponent<CatchToast>(); } } catch (Exception e) { Log.Ex("CatchToast.Bootstrap", e); } } private void OnGUI() { try { CatchStats.DrawToast(); } catch (Exception e) { Log.Ex("CatchToast.OnGUI", e); } } } public class ConfigPanel : MonoBehaviour { private sealed class Row { public string Name; public string Label; public string Help; public float Min; public float Max; public float Step; public FieldInfo Field; public Row(string name, string label, string help, float min = 0f, float max = 0f, float step = 1f) { Name = name; Label = label; Help = help; Min = min; Max = max; Step = step; } } private sealed class Group { public string Title; public Row[] Rows; public Group(string title, Row[] rows) { Title = title; Rows = rows; } } private static ConfigPanel _instance; private const float PanelW = 1180f; private const float PanelH = 720f; private const float HeaderH = 58f; private const float FooterH = 56f; private const float RowH = 46f; private const int RowsPerPage = 11; private static readonly Group[] Groups = new Group[6] { new Group("Features", new Row[11] { new Row("EnableVariants", "Fish size variants", "Plump through Mythic. Off returns every catch to its vanilla name and value."), new Row("EnableLuckShop", "Lucky Charm stands", "The luck stands on each island, and the luck system behind them."), new Row("EnableAscension", "Ascension (New Game+)", "Unlocks after the game is finished. Off hides the stand entirely."), new Row("EnableBackpack", "Storage panel", "The mod's own inventory window, opened in game with the storage key."), new Row("EnableCatchStats", "Catch trophies", "Records every fish you land and pops a toast on a new record."), new Row("EnableFishScaling", "Fish drawn to size", "Draws a fish at a size matching its weight, instead of one size for all."), new Row("EnableExtraHooks", "Extra hooks", "More than one fish on the line at a time. Still being tuned."), new Row("PreventMoneyOverflow", "Money overflow guard", "Stops a very large catch wrapping the game's 32-bit money counter."), new Row("EnableCustomStandModels", "Custom stand models", "The mod's own kiosk model. Off falls back to a plain marker."), new Row("HighlightModStands", "Outline mod stands", "Keeps the mod's stands permanently outlined so they can be found."), new Row("EnableDebugMenu", "Debug menu", "Developer overlay. Off unless you have been asked to turn it on.") }), new Group("Fish size", new Row[9] { new Row("FishScaleExponent", "Size exponent", "size = weight ^ this. 0.33 is physically honest; higher exaggerates it.", 0f, 1f, 0.01f), new Row("FishScaleMin", "Smallest draw size", "A runt never draws smaller than this.", 0.05f, 1f, 0.05f), new Row("FishScaleMax", "Largest draw size", "A safety rail. Nothing in the variant table reaches it.", 1f, 10f, 0.25f), new Row("ScaleBossFish", "Scale bosses too", "Only does anything with 'Variants from bosses' on as well."), new Row("VariantChanceMulti", "Variant chance", "Multiplies the odds of rolling any variant at all.", 0.1f, 10f, 0.1f), new Row("VariantsFromBirds", "Variants from birds", "Whether a fish taken from a bird can be a variant."), new Row("VariantsFromDynamite", "Variants from dynamite", "Off by default: a blast catches many fish at once."), new Row("VariantsFromBosses", "Variants from bosses", "Rolls a weight for bosses, which the game otherwise pins to 1.0."), new Row("UseColors", "Colour variant names", "Tints the variant prefix in the catch readout.") }), new Group("Health bars", new Row[6] { new Row("EnableFishHealthBars", "Show health bars", "Draws a bar above each fish that drains as it is fought."), new Row("FishHealthBarWidth", "Bar width", "How wide the bar is, in world units.", 0.5f, 4f, 0.1f), new Row("FishHealthBarThickness", "Bar thickness", "How tall the bar is, in world units.", 0.05f, 0.6f, 0.01f), new Row("FishHealthBarLift", "Height above fish", "The gap between the top of a fish and the bar.", 0f, 1.5f, 0.05f), new Row("FishHealthBarOpacity", "Opacity", "Overall transparency, 0.2 to 1.", 0.2f, 1f, 0.05f), new Row("FishHealthBarOnlyWhenDamaged", "Only when damaged", "Hide the bar until the fish takes damage.") }), new Group("Luck", new Row[5] { new Row("LuckBaseCost", "First luck level cost", "What level 1 costs. Every level after grows from this.", 10f, 100000f, 25f), new Row("LuckCostGrowth", "Luck cost growth", "Per-level multiplier on the price.", 1.01f, 2f, 0.01f), new Row("LuckMaxLevel", "Luck level cap", "How far the luck ladder goes.", 5f, 250f, 5f), new Row("OrdinaryChanceAtMaxLuck", "Ordinary at max luck", "Share of catches still plain once luck is maxed.", 0.01f, 1f, 0.01f), new Row("LuckBaseWeightBonus", "Luck weight bonus", "How much luck pushes the weight roll upward.", 0f, 0.2f, 0.01f) }), new Group("Ascension", new Row[7] { new Row("AscensionBaseCost", "First ascension cost", "Price of tier 1.", 100f, 100000000f, 5000f), new Row("AscensionCostGrowth", "Ascension cost growth", "Per-tier multiplier on the price.", 1.05f, 5f, 0.05f), new Row("AscensionHpGrowth", "Creature health growth", "Per-tier multiplier on how hard things hit back.", 1f, 5f, 0.05f), new Row("AscensionValueGrowth", "Fish value growth", "Per-tier multiplier on what a catch is worth.", 1f, 5f, 0.05f), new Row("AscensionMaxLevel", "Ascension tier cap", "How many tiers the loop runs for.", 1f, 100f), new Row("AscensionLuckBonus", "Free luck per tier", "Luck levels granted on each ascension.", 0f, 50f), new Row("EnableAscensionSlots", "Pockets per tier", "Whether ascension grows your hotbar. It stops at nine either way.") }), new Group("Storage and upgrades", new Row[9] { new Row("BackpackSlots", "Storage slots", "How much the storage panel holds before ascension.", 5f, 300f, 5f), new Row("BackpackSlotsPerAscension", "Slots per tier", "Extra storage each ascension tier adds.", 0f, 50f), new Row("ExtraGunTiers", "Extra gun tiers", "-1 means as many as the game can address.", -1f, 250f), new Row("ExtraMeleeTiers", "Extra melee tiers", "-1 means as many as the game can address.", -1f, 250f), new Row("GunDamageGrowth", "Gun damage growth", "Upper bound on the per-tier damage rate.", 1f, 3f, 0.01f), new Row("GunCostGrowth", "Gun cost growth", "Upper bound on the per-tier price rate.", 1.01f, 3f, 0.01f), new Row("UnlockShopCap", "Unlock the shop cap", "Lets the shop sell past its original top tier."), new Row("HookCount", "Hooks on the line", "How many fish can be on the line at once.", 1f, 5f), new Row("HookSpread", "Hook spacing", "How far apart extra fish sit. 0 stacks them.", 0f, 2f, 0.02f) }) }; private Canvas _canvas; private RectTransform _root; private RectTransform _body; private TextMeshProUGUI _titleText; private TextMeshProUGUI _footerText; private readonly List<Image> _tabBgs = new List<Image>(); private readonly UiKit.Hotspots _hotspots = new UiKit.Hotspots(); private int _tab; private int _page; private bool _built; private bool _dirty; private float _messageUntil; private readonly Dictionary<string, object> _opening = new Dictionary<string, object>(); private static bool _resolved; public static bool IsOpen { get; private set; } public static void Bootstrap() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown try { if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("HTFX_ConfigPanel"); Object.DontDestroyOnLoad((Object)(object)val); _instance = val.AddComponent<ConfigPanel>(); Log.Info("config panel ready; the button is on the main menu"); } } catch (Exception e) { Log.Ex("ConfigPanel.Bootstrap", e); } } public static void OpenPanel() { try { Bootstrap(); if ((Object)(object)_instance != (Object)null) { _instance.Open(); } } catch (Exception e) { Log.Ex("ConfigPanel.OpenPanel", e); } } private void Awake() { try { ResolveFields(); } catch (Exception e) { Log.Ex("ConfigPanel.Awake", e); } } private static void ResolveFields() { if (_resolved) { return; } _resolved = true; int num = 0; Group[] groups = Groups; foreach (Group obj in groups) { Row[] rows = obj.Rows; foreach (Row row in rows) { row.Field = typeof(Cfg).GetField(row.Name, BindingFlags.Static | BindingFlags.Public); if (row.Field == null) { num++; Log.Warn("config panel: setting '" + row.Name + "' is listed in the panel but no longer exists, so its row is hidden"); } } } if (num == 0) { Log.Info("config panel: all " + CountRows() + " settings resolved"); } } private static int CountRows() { int num = 0; Group[] groups = Groups; foreach (Group obj in groups) { num += obj.Rows.Length; } return num; } private void Update() { try { if (IsOpen) { _hotspots.Hover(); if (UiKit.MouseClicked()) { _hotspots.Click(); } if (_messageUntil > 0f && Time.unscaledTime > _messageUntil) { _messageUntil = 0f; Footer(); } } } catch (Exception e) { Log.Ex("ConfigPanel.Update", e); } } private void Open() { try { Cfg.EnsureLoaded(); if (!_built) { Build(); _built = true; } if ((Object)(object)_canvas == (Object)null) { return; } _opening.Clear(); Group[] groups = Groups; foreach (Group obj in groups) { Row[] rows = obj.Rows; foreach (Row row in rows) { if (row.Field != null) { _opening[row.Name] = row.Field.GetValue(null); } } } IsOpen = true; _dirty = false; _tab = 0; _page = 0; _messageUntil = 0f; ((Component)_canvas).gameObject.SetActive(true); Refresh(); } catch (Exception e) { Log.Ex("ConfigPanel.Open", e); } } private void Close() { try { IsOpen = false; if ((Object)(object)_canvas != (Object)null) { ((Component)_canvas).gameObject.SetActive(false); } } catch (Exception e) { Log.Ex("ConfigPanel.Close", e); } } private void Revert() { Group[] groups = Groups; foreach (Group obj in groups) { Row[] rows = obj.Rows; foreach (Row row in rows) { if (row.Field != null && _opening.TryGetValue(row.Name, out var value)) { row.Field.SetValue(null, value); } } } _dirty = false; } private void Save() { try { Cfg.Write(); _opening.Clear(); Group[] groups = Groups; foreach (Group obj in groups) { Row[] rows = obj.Rows; foreach (Row row in rows) { if (row.Field != null) { _opening[row.Name] = row.Field.GetValue(null); } } } _dirty = false; Say("Saved. These apply to the next game you load.", warn: false); Log.Info("config panel: settings saved to " + Cfg.Path); } catch (Exception e) { Log.Ex("ConfigPanel.Save", e); Say("Could not write the config file - see the log.", warn: true); } } private void Say(string text, bool warn) { //IL_0040: 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) _messageUntil = Time.unscaledTime + 5f; if ((Object)(object)_footerText != (Object)null) { ((TMP_Text)_footerText).text = text; ((Graphic)_footerText).color = (warn ? UiKit.Warn : UiKit.Good); } } private void Footer() { //IL_0048: 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) if (!((Object)(object)_footerText == (Object)null)) { ((TMP_Text)_footerText).text = (_dirty ? "Unsaved changes. Save writes them to the config file; they take effect in the next game you load." : "Changes apply to the next game you load. The config file is in AppData if you would rather edit it there."); ((Graphic)_footerText).color = (_dirty ? UiKit.Gold : UiKit.TextDim); } } private void Build() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0097: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: 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) GameObject val = new GameObject("HTFX_ConfigCanvas", new Type[3] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler) }); Object.DontDestroyOnLoad((Object)(object)val); val.transform.SetParent(((Component)this).transform, false); _canvas = val.GetComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 5200; CanvasScaler component = val.GetComponent<CanvasScaler>(); component.uiScaleMode = (ScaleMode)1; component.referenceResolution = new Vector2(1920f, 1080f); component.screenMatchMode = (ScreenMatchMode)0; component.matchWidthOrHeight = 0.5f; Image val2 = UiKit.NewImage("Shade", val.transform, UiKit.Shade); UiKit.Stretch(((Graphic)val2).rectTransform); Image val3 = UiKit.NewImage("Panel", val.transform, UiKit.PanelBg); _root = ((Graphic)val3).rectTransform; RectTransform root = _root; RectTransform root2 = _root; Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(0.5f, 0.5f); root2.anchorMax = val4; root.anchorMin = val4; _root.pivot = new Vector2(0.5f, 0.5f); _root.anchoredPosition = Vector2.zero; _root.sizeDelta = new Vector2(1180f, 720f); Image val5 = UiKit.NewImage("Header", (Transform)(object)_root, UiKit.HeaderBg); UiKit.Place(((Graphic)val5).rectTransform, 0f, 0f, 1180f, 58f); _titleText = UiKit.NewText("Title", (Transform)(object)((Graphic)val5).rectTransform, "How To Fish - Extended", 22, UiKit.Gold, (TextAlignmentOptions)513); UiKit.Place(((TMP_Text)_titleText).rectTransform, 20f, 14f, 420f, 32f); _body = UiKit.NewRect("Body", (Transform)(object)_root); UiKit.Place(_body, 0f, 58f, 1180f, 606f); _footerText = UiKit.NewText("Footer", (Transform)(object)_root, "", 14, UiKit.TextDim, (TextAlignmentOptions)513); UiKit.Place(((TMP_Text)_footerText).rectTransform, 20f, 672f, 860f, 40f); val.SetActive(false); } private void ClearBody() { _hotspots.Clear(); _tabBgs.Clear(); if (!((Object)(object)_body == (Object)null)) { for (int num = ((Transform)_body).childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)((Transform)_body).GetChild(num)).gameObject); } } } private void Refresh() { try { if (_built && !((Object)(object)_canvas == (Object)null)) { ClearBody(); ((TMP_Text)_titleText).text = "How To Fish - Extended " + ModInfo.Display + " - Settings"; DrawTabs(); DrawRows(); if (Groups[_tab].Title == "Health bars") { DrawHealthBarPreview(); } DrawButtons(); Footer(); } } catch (Exception e) { Log.Ex("ConfigPanel.Refresh", e); } } private void DrawTabs() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) float num = 20f; for (int i = 0; i < Groups.Length; i++) { int index = i; Image val = UiKit.NewImage("Tab" + i, (Transform)(object)_body, (i == _tab) ? UiKit.TabOn : UiKit.TabOff); float num2 = Mathf.Min(190f, 1140f / (float)Groups.Length - 8f); UiKit.Place(((Graphic)val).rectTransform, num, 10f, num2, 36f); TextMeshProUGUI val2 = UiKit.NewText("TabText" + i, (Transform)(object)((Graphic)val).rectTransform, Groups[i].Title, 15, (i == _tab) ? UiKit.Gold : UiKit.TextLight, (TextAlignmentOptions)514); UiKit.Stretch(((TMP_Text)val2).rectTransform); _hotspots.Add(val, delegate { _tab = index; _page = 0; Refresh(); }); _tabBgs.Add(val); num += num2 + 8f; } } private void DrawRows() { Row[] rows = Groups[_tab].Rows; int num = Mathf.Max(1, Mathf.CeilToInt((float)rows.Length / 11f)); _page = Mathf.Clamp(_page, 0, num - 1); float num2 = 62f; for (int i = _page * 11; i < rows.Length && i < (_page + 1) * 11; i++) { DrawRow(rows[i], num2); num2 += 46f; } if (num > 1) { DrawPager(num2 + 6f, num); } } private void DrawHealthBarPreview() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) float y = 62f + (float)Groups[_tab].Rows.Length * 46f + 8f; Image val = UiKit.NewImage("HpPreview", (Transform)(object)_body, UiKit.CellEmpty); UiKit.Place(((Graphic)val).rectTransform, 20f, y, 1140f, 200f); TextMeshProUGUI val2 = UiKit.NewText("HpPreviewTitle", (Transform)(object)((Graphic)val).rectTransform, "Preview - the bar floats above the fish", 13, UiKit.TextDim, (TextAlignmentOptions)513); UiKit.Place(((TMP_Text)val2).rectTransform, 14f, 8f, 1112f, 20f); float num = 220f; float h = 62f; float num2 = 570f - num / 2f; float num3 = 100f; Image val3 = UiKit.NewImage("HpFish", (Transform)(object)((Graphic)val).rectTransform, new Color(0.24f, 0.31f, 0.4f, 1f)); UiKit.Place(((Graphic)val3).rectTransform, num2, num3, num, h); float num4 = Mathf.Clamp(Cfg.FishHealthBarWidth * 100f, 12f, 1100f); float num5 = Mathf.Clamp(Cfg.FishHealthBarThickness * 100f, 3f, 48f); float num6 = Mathf.Clamp(Cfg.FishHealthBarLift * 100f, 0f, 60f); float fishHealthBarOpacity = Cfg.FishHealthBarOpacity; float x = num2 + (num - num4) / 2f; float y2 = Mathf.Max(34f, num3 - num6 - num5); Image val4 = UiKit.NewImage("HpTrack", (Transform)(object)((Graphic)val).rectTransform, new Color(0.03f, 0.05f, 0.06f, 0.85f * fishHealthBarOpacity)); UiKit.Place(((Graphic)val4).rectTransform, x, y2, num4, num5); Image val5 = UiKit.NewImage("HpFill", (Transform)(object)((Graphic)val).rectTransform, new Color(0.22f, 0.86f, 0.42f, 0.95f * fishHealthBarOpacity)); UiKit.Place(((Graphic)val5).rectTransform, x, y2, num4 * 0.62f, num5); TextMeshProUGUI val6 = UiKit.NewText("HpDims", (Transform)(object)((Graphic)val).rectTransform, "width " + Cfg.FishHealthBarWidth.ToString("0.00") + " x thickness " + Cfg.FishHealthBarThickness.ToString("0.00") + " | " + Mathf.RoundToInt(fishHealthBarOpacity * 100f) + "% opacity" + (Cfg.FishHealthBarOnlyWhenDamaged ? " | hidden until damaged" : ""), 13, UiKit.TextDim, (TextAlignmentOptions)514); UiKit.Place(((TMP_Text)val6).rectTransform, 14f, 176f, 1112f, 20f); } private void DrawRow(Row r, float y) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if (!(r.Field == null)) { Image val = UiKit.NewImage("Row_" + r.Name, (Transform)(object)_body, UiKit.CellEmpty); UiKit.Place(((Graphic)val).rectTransform, 20f, y, 1140f, 40f); TextMeshProUGUI val2 = UiKit.NewText("Label", (Transform)(object)((Graphic)val).rectTransform, r.Label, 16, UiKit.TextLight, (TextAlignmentOptions)513); UiKit.Place(((TMP_Text)val2).rectTransform, 14f, 3f, 280f, 20f); TextMeshProUGUI val3 = UiKit.NewText("Help", (Transform)(object)((Graphic)val).rectTransform, r.Help, 12, UiKit.TextDim, (TextAlignmentOptions)513); UiKit.Place(((TMP_Text)val3).rectTransform, 14f, 21f, 700f, 18f); if (r.Field.FieldType == typeof(bool)) { DrawToggle(r, val); } else { DrawStepper(r, val); } } } private void DrawToggle(Row r, Image rowBg) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) bool flag = (bool)r.Field.GetValue(null); Image val = UiKit.NewImage("Toggle", (Transform)(object)((Graphic)rowBg).rectTransform, flag ? UiKit.TabOn : UiKit.TabOff); UiKit.Place(((Graphic)val).rectTransform, 1010f, 5f, 110f, 30f); TextMeshProUGUI val2 = UiKit.NewText("ToggleText", (Transform)(object)((Graphic)val).rectTransform, flag ? "On" : "Off", 15, flag ? UiKit.Good : UiKit.TextDim, (TextAlignmentOptions)514); UiKit.Stretch(((TMP_Text)val2).rectTransform); _hotspots.Add(val, delegate { r.Field.SetValue(null, !(bool)r.Field.GetValue(null)); _dirty = true; Refresh(); }); } private void DrawStepper(Row r, Image rowBg) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references)