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 Noctyra ItemUpgrader v0.2.0
BepInEx/plugins/NoctyraItemUpgrader/ItemUpgrader.dll
Decompiled 4 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Newtonsoft.Json; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Noctyra Item Upgrader")] [assembly: AssemblyDescription("Local item exchange roulette for Valheim")] [assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyVersion("0.2.0.0")] namespace Noctyra.ItemUpgrader; public static class GridWindow { public static int PoolSize(double viewport, double rowStride, int columns) { return ((int)Math.Ceiling(viewport / rowStride) + 2) * columns; } public static int FirstIndex(double offset, double rowStride, int columns, int count) { int val = Math.Max(0, (int)Math.Floor(Math.Max(0.0, offset - 8.0) / rowStride) - 1); int val2 = Math.Max(0, (count + columns - 1) / columns - 1); return Math.Min(val, val2) * columns; } public static double ContentHeight(int count, int columns, double cellHeight, double gap) { if (count != 0) { return 16.0 + Math.Ceiling((double)count / (double)columns) * (cellHeight + gap) - gap; } return 16.0; } } public sealed class RewardReceipt { public string Prefab; public int Amount = 1; public int Quality = 1; public string Transaction; } [BepInPlugin("noctyra.valheim.itemupgrader", "Noctyra Item Upgrader", "0.2.0")] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "noctyra.valheim.itemupgrader"; public const string Version = "0.2.0"; private const string ReceiptKey = "noctyra.valheim.itemupgrader.pendingReward.v1"; public static Plugin Instance; private static int closedFrame = -1; private ConfigEntry<KeyboardShortcut> hotkey; private ConfigEntry<bool> modEnabled; private ConfigEntry<double> returnRate; private ConfigEntry<double> maxChance; private ConfigEntry<double> craftingMarkup; private ConfigEntry<float> spinSeconds; private ConfigEntry<int> maximumRewardAmount; private Harmony harmony; private UpgraderUI ui; private Player player; private float refreshTime; private bool initialized; private bool invalidReceipt; private string catalogError; private RewardReceipt pending; private float spinStart; private float spinDuration; private double spinAngle; private double spinEndAngle; private double spinChance; private bool spinWin; private string spinTarget; public static bool IsOpen { get { if ((Object)(object)Instance != (Object)null && Instance.ui != null) { return Instance.ui.Visible; } return false; } } public static bool BlocksInput { get { if (!IsOpen) { return Time.frameCount == closedFrame; } return true; } } public ValueCatalog Catalog { get; private set; } public ItemData Source { get; private set; } public CatalogItem Target { get; private set; } public int Quantity { get; private set; } public int TargetQuantity { get; private set; } public int RewardRemaining { get { if (pending != null) { return pending.Amount; } return 0; } } public int MaximumRewardAmount => maximumRewardAmount.Value; public bool Spinning { get; private set; } public string Status { get; private set; } public bool HasReward => pending != null; public CatalogItem RewardItem { get { if (pending != null && Catalog != null) { return Catalog.Find(pending.Prefab); } return null; } } public Player LocalPlayer => player; public string HotkeyLabel => ((object)hotkey.Value/*cast due to .constrained prefix*/).ToString(); public double Stake { get { if (Catalog != null) { return Catalog.StakeValue(Source, Quantity); } return 0.0; } } public double TargetTotal { get { if (Target != null) { return RollMath.TargetValue(Target.Value, TargetQuantity); } return 0.0; } } public double Chance => RollMath.Chance(Stake, TargetTotal, returnRate.Value, maxChance.Value); public double DisplayChance { get { if (!Spinning && (Source != null || !(spinAngle > 0.0))) { return Chance; } return spinChance; } } public bool CanChangeSelection { get { if (!Spinning && !HasReward) { return !invalidReceipt; } return false; } } public static void JustClosed() { closedFrame = Time.frameCount; } private void Awake() { //IL_0042: 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_009b: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Expected O, but got Unknown //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Expected O, but got Unknown //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) Instance = this; modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable the local upgrader UI."); hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "OpenKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Key for opening and closing the upgrader."); returnRate = ((BaseUnityPlugin)this).Config.Bind<double>("Balance", "ReturnRate", 0.9, new ConfigDescription("Chance = stake value / target value * ReturnRate. No artificial minimum chance.", (AcceptableValueBase)(object)new AcceptableValueRange<double>(0.01, 1.0), Array.Empty<object>())); maxChance = ((BaseUnityPlugin)this).Config.Bind<double>("Balance", "MaximumChance", 0.95, new ConfigDescription("Maximum probability: 0.95 means 95%.", (AcceptableValueBase)(object)new AcceptableValueRange<double>(0.01, 1.0), Array.Empty<object>())); craftingMarkup = ((BaseUnityPlugin)this).Config.Bind<double>("Balance", "CraftingMarkup", 1.15, new ConfigDescription("Labor multiplier for automatically valued recipes. Existing ItemValues.json entries take precedence.", (AcceptableValueBase)(object)new AcceptableValueRange<double>(1.0, 3.0), Array.Empty<object>())); spinSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "SpinSeconds", 5f, new ConfigDescription("Wheel animation duration in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>())); maximumRewardAmount = ((BaseUnityPlugin)this).Config.Bind<int>("Balance", "MaximumRewardAmount", 1000, new ConfigDescription("Maximum selected reward quantity. Larger rewards can be claimed in several batches.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10000), Array.Empty<object>())); ConfigEntry<string> val = ((BaseUnityPlugin)this).Config.Bind<string>("Internal", "AnimationVersion", "", "Tracks the one-time migration to the five-second animation."); if (val.Value != "0.2.0") { spinSeconds.Value = 5f; val.Value = "0.2.0"; } harmony = new Harmony("noctyra.valheim.itemupgrader"); harmony.PatchAll(typeof(Plugin).Assembly); Status = "Выбери ставку и желаемый предмет."; Quantity = 1; TargetQuantity = 1; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Noctyra Item Upgrader 0.2.0 loaded. Local only. Open with " + ((object)hotkey.Value/*cast due to .constrained prefix*/).ToString() + ".")); } private void Update() { //IL_01ba: 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) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)(object)player) { if (ui != null) { ui.Destroy(); } ui = null; player = localPlayer; Source = null; Target = null; Quantity = 1; TargetQuantity = 1; Spinning = false; pending = null; invalidReceipt = false; spinAngle = 0.0; initialized = false; Catalog = null; catalogError = null; } if ((Object)(object)player == (Object)null) { return; } if (!modEnabled.Value) { if (ui != null && ui.Visible) { ui.Hide(); } return; } if (!initialized && (Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items.Count > 0 && ObjectDB.instance.m_recipes.Count > 0 && !((Character)player).InCutscene()) { Initialize(); } if (!initialized) { return; } if (Spinning) { float num = Mathf.Clamp01((Time.unscaledTime - spinStart) / spinDuration); if (ui != null) { ui.SetAngle((float)(spinAngle * RollMath.SmoothSpin(num))); } if (num >= 1f) { if (ui != null) { ui.SetAngle((float)spinEndAngle); } CompleteSpin(); } } if (ui != null && ui.Visible && ((Character)player).IsDead()) { ui.Hide(); } KeyboardShortcut value = hotkey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { if (ui != null && ui.Visible) { ui.Hide(); } else if (!((Character)player).IsDead() && !((Character)player).InCutscene() && !InventoryGui.IsVisible() && !Menu.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus())) { Open(); } } if (ui == null || !ui.Visible) { return; } if (Input.GetKeyDown((KeyCode)27)) { ui.Hide(); return; } Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; if (Time.unscaledTime > refreshTime) { refreshTime = Time.unscaledTime + 0.35f; ValidateSource(); ui.Refresh(force: false); } } private void Initialize() { try { Catalog = new ValueCatalog(Path.Combine(Paths.ConfigPath, "ItemUpgrader"), craftingMarkup.Value, ((BaseUnityPlugin)this).Logger); Catalog.Build(); LoadReceipt(); initialized = true; Status = (invalidReceipt ? "Ошибка сохранённой награды. Пришли LogOutput.log для исправления." : ((pending == null) ? "Выбери ставку и желаемый предмет." : "Есть сохранённый выигрыш. Нажми «Забрать».")); ((MonoBehaviour)this).StartCoroutine(PrewarmUi(player)); } catch (Exception ex) { initialized = true; Catalog = null; catalogError = "Ошибка таблицы ценностей. Проверь ItemValues.json и LogOutput.log."; ((BaseUnityPlugin)this).Logger.LogError((object)("ItemUpgrader initialization failed: " + ex)); } } private IEnumerator PrewarmUi(Player owner) { yield return null; if ((Object)(object)player != (Object)(object)owner || Catalog == null) { yield break; } try { if (ui == null) { ui = new UpgraderUI(this); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("UI prewarm failed: " + ex)); yield break; } UpgraderUI prepared = ui; IEnumerator steps = prepared.Prewarm(); while ((Object)(object)player == (Object)(object)owner && ui == prepared && steps.MoveNext()) { yield return steps.Current; } } private void Open() { if (Catalog == null) { ((Character)player).Message((MessageType)2, catalogError ?? "Каталог ещё не готов.", 0, (Sprite)null, false); return; } try { if (ui == null) { ui = new UpgraderUI(this); } ValidateSource(); ui.Show(); } catch (Exception ex) { if (ui != null) { ui.Destroy(); } ui = null; ((BaseUnityPlugin)this).Logger.LogError((object)("Could not create upgrader UI: " + ex)); ((Character)player).Message((MessageType)2, "Не удалось открыть меню. Пришли LogOutput.log.", 0, (Sprite)null, false); } } public void SelectSource(ItemData item) { if (CanChangeSelection && item != null && ((Humanoid)player).GetInventory().ContainsItem(item)) { if (item.m_equipped) { SetStatus("Сначала сними этот предмет с персонажа."); return; } if (Catalog.Find(item) == null) { SetStatus("Для этого предмета обмен отключён."); return; } Source = item; Quantity = 1; spinAngle = 0.0; ui.ResetWheel(); Status = "Ставка выбрана. Выбери желаемый предмет справа."; ui.Refresh(force: true); } } public void SelectTarget(CatalogItem target) { if (CanChangeSelection && target != null) { Target = target; TargetQuantity = 1; spinAngle = 0.0; Status = "При проигрыше выбранное количество ставки исчезнет."; ui.ResetWheel(); ui.Refresh(force: true); } } public void SetQuantity(int quantity) { if (CanChangeSelection && Source != null) { Quantity = Math.Max(1, Math.Min(Source.m_stack, quantity)); ui.Refresh(force: false); } } public void SetTargetQuantity(int quantity) { if (CanChangeSelection && Target != null) { TargetQuantity = Math.Max(1, Math.Min(MaximumRewardAmount, quantity)); spinAngle = 0.0; if (ui != null) { ui.ResetWheel(); ui.Refresh(force: false); } } } public void ClearSource() { if (CanChangeSelection) { Source = null; Quantity = 1; spinAngle = 0.0; ui.ResetWheel(); ui.Refresh(force: true); } } private void ValidateSource() { if (Source != null) { if ((Object)(object)player == (Object)null || !((Humanoid)player).GetInventory().ContainsItem(Source) || Source.m_equipped || Source.m_stack < 1) { Source = null; Quantity = 1; } else { Quantity = Math.Min(Quantity, Source.m_stack); } } } public bool CanRoll() { ValidateSource(); if (modEnabled.Value && (Object)(object)player != (Object)null && !((Character)player).IsDead() && CanChangeSelection && Source != null && Target != null && Quantity >= 1) { return Chance > 0.0; } return false; } public void Roll() { if (!CanRoll()) { return; } Inventory inventory = ((Humanoid)player).GetInventory(); if (!inventory.ContainsItem(Source) || Source.m_stack < Quantity || Source.m_equipped) { SetStatus("Ставка изменилась. Выбери предмет заново."); return; } if ((Object)(object)ObjectDB.instance.GetItemPrefab(Target.Id) == (Object)null) { SetStatus("Желаемый предмет недоступен."); return; } double sample = UniformSample(); double chance = Chance; bool flag = RollMath.Wins(sample, chance); string text = System.Guid.NewGuid().ToString("N"); RewardReceipt rewardReceipt = (flag ? new RewardReceipt { Prefab = Target.Id, Amount = TargetQuantity, Quality = 1, Transaction = text } : null); string value = (flag ? JsonConvert.SerializeObject((object)rewardReceipt) : null); string name = ((Object)Source.m_dropPrefab).name; int quantity = Quantity; double stake = Stake; if (!inventory.RemoveItem(Source, quantity)) { SetStatus("Не удалось списать ставку. Попытка отменена."); return; } pending = rewardReceipt; if (flag) { player.m_customData["noctyra.valheim.itemupgrader.pendingReward.v1"] = value; } else { player.m_customData.Remove("noctyra.valheim.itemupgrader.pendingReward.v1"); } spinChance = chance; spinWin = flag; spinTarget = Target.Name + " × " + TargetQuantity; spinEndAngle = RollMath.EndAngle(sample); spinAngle = 2160.0 + spinEndAngle; spinStart = Time.unscaledTime; spinDuration = spinSeconds.Value; Spinning = true; Source = null; Quantity = 1; Status = "Колесо вращается…"; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Upgrade " + text + ": " + name + " x" + quantity + " (" + stake.ToString("0.####", CultureInfo.InvariantCulture) + ") -> " + Target.Id + " x" + TargetQuantity + "; chance=" + RollMath.Percent(chance) + "; success=" + flag)); if (ui != null) { ui.SetAngle(0f); ui.Refresh(force: true); } } private void CompleteSpin() { Spinning = false; Status = (spinWin ? ("УСПЕХ! «" + spinTarget + "» ждёт в ячейке результата.") : "Не повезло. Ставка сгорела. Можно попробовать снова."); if (ui != null) { ui.ShowResult(spinWin); ui.Refresh(force: true); } } public void Claim() { if (Spinning || pending == null || (Object)(object)player == (Object)null || ((Character)player).IsDead()) { return; } if (pending.Amount < 1 || pending.Amount > 100000 || pending.Quality != 1) { SetStatus("Некорректная сохранённая награда. Пришли лог."); return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(pending.Prefab); ItemDrop val = (((Object)(object)itemPrefab == (Object)null) ? null : itemPrefab.GetComponent<ItemDrop>()); if ((Object)(object)val == (Object)null) { SetStatus("Предмет награды отсутствует. Награда сохранена до его возвращения."); return; } Inventory inventory = ((Humanoid)player).GetInventory(); int num = 0; while (pending.Amount > 0) { ItemData val2 = val.m_itemData.Clone(); val2.m_dropPrefab = itemPrefab; val2.m_quality = 1; val2.m_equipped = false; val2.m_durability = val2.GetMaxDurability(); int num2 = Math.Max(1, val2.m_shared.m_maxStackSize); long num3 = (long)Math.Max(0, inventory.GetWidth() * inventory.GetHeight() - inventory.GetAllItems().Count) * (long)num2; foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem.m_shared.m_name == val2.m_shared.m_name && allItem.m_quality == 1 && allItem.m_worldLevel == val2.m_worldLevel) { num3 += Math.Max(0, num2 - allItem.m_stack); } } int num4 = (int)Math.Min(pending.Amount, Math.Min(num2, num3)); if (num4 < 1 || !inventory.CanAddItem(val2, num4)) { break; } val2.m_stack = num4; bool num5 = inventory.AddItem(val2); int num6 = (num5 ? num4 : Math.Max(0, num4 - val2.m_stack)); pending.Amount -= num6; num += num6; if (!num5) { break; } } if (pending.Amount == 0) { player.m_customData.Remove("noctyra.valheim.itemupgrader.pendingReward.v1"); pending = null; } else { player.m_customData["noctyra.valheim.itemupgrader.pendingReward.v1"] = JsonConvert.SerializeObject((object)pending); } Status = ((num == 0) ? "Нет места. Освободи ячейки и нажми «Забрать»." : ((pending == null) ? ("Получено: " + num + " шт. Выбирай следующую ставку.") : ("Получено: " + num + " шт. Осталось забрать: " + pending.Amount + "."))); if (ui != null) { ui.Refresh(force: true); } } public void ReloadValues() { if (Spinning) { return; } try { string id = ((Target == null) ? null : Target.Id); ValueCatalog valueCatalog = new ValueCatalog(Path.Combine(Paths.ConfigPath, "ItemUpgrader"), craftingMarkup.Value, ((BaseUnityPlugin)this).Logger); valueCatalog.Build(); Catalog = valueCatalog; Target = Catalog.Find(id); if (ui != null) { ui.RefreshCatalog(); } SetStatus("Ценности перечитаны из ItemValues.json."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Price reload failed: " + ex)); SetStatus("Ошибка JSON. Предыдущие цены сохранены."); } } private void LoadReceipt() { if (!player.m_customData.TryGetValue("noctyra.valheim.itemupgrader.pendingReward.v1", out var value)) { return; } try { RewardReceipt rewardReceipt = JsonConvert.DeserializeObject<RewardReceipt>(value); if (rewardReceipt == null || string.IsNullOrEmpty(rewardReceipt.Prefab) || rewardReceipt.Amount < 1 || rewardReceipt.Amount > 100000 || rewardReceipt.Quality != 1) { throw new InvalidDataException("Invalid reward receipt"); } pending = rewardReceipt; } catch (Exception ex) { invalidReceipt = true; ((BaseUnityPlugin)this).Logger.LogError((object)("Pending reward data is invalid; further rolls blocked: " + ex)); } } private static double UniformSample() { byte[] array = new byte[8]; using (RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create()) { randomNumberGenerator.GetBytes(array); } return (double)(BitConverter.ToUInt64(array, 0) >> 11) * 1.1102230246251565E-16; } public void SetStatus(string text) { Status = text; if (ui != null) { ui.Refresh(force: false); } } private void OnDestroy() { if (ui != null) { ui.Destroy(); } if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } [HarmonyPatch(typeof(Player), "TakeInput")] internal static class PlayerInputPatch { private static bool Prefix(ref bool __result) { if (!Plugin.BlocksInput) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(InventoryGui), "IsVisible")] internal static class InventoryVisiblePatch { private static void Postfix(ref bool __result) { if (Plugin.BlocksInput) { __result = true; } } } [HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")] internal static class CursorPatch { private static void Postfix() { if (Plugin.IsOpen) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } } [HarmonyPatch(typeof(Menu), "Update")] internal static class MenuPatch { private static bool Prefix() { return !Plugin.BlocksInput; } } public static class RollMath { public static double Chance(double stake, double target, double returnRate, double maximum) { if (!FinitePositive(stake) || !FinitePositive(target)) { return 0.0; } if (!FinitePositive(returnRate) || !FinitePositive(maximum)) { return 0.0; } return Math.Min(Math.Min(maximum, 1.0), stake / target * Math.Min(returnRate, 1.0)); } public static bool FinitePositive(double value) { if (value > 0.0 && !double.IsInfinity(value)) { return !double.IsNaN(value); } return false; } public static bool Wins(double sample, double chance) { if (sample >= 0.0 && sample < 1.0) { return sample < chance; } return false; } public static double EndAngle(double sample) { return sample * 360.0; } public static double TargetValue(double unitValue, int amount) { if (amount <= 0 || !FinitePositive(unitValue)) { return 0.0; } return unitValue * (double)amount; } public static double SmoothSpin(double t) { t = Math.Max(0.0, Math.Min(1.0, t)); if (t < 0.12) { return 0.5 * (t - 3.0 / (25.0 * Math.PI) * Math.Sin(Math.PI * t / 0.12)) / 0.62; } double num = 0.06; if (t < 0.36) { return (num + t - 0.12) / 0.62; } double num2 = t - 0.36; double num3 = 0.64; return (num + 0.36 - 0.12 + 0.5 * (num2 + num3 / Math.PI * Math.Sin(Math.PI * num2 / num3))) / 0.62; } public static string Percent(double chance) { double num = chance * 100.0; if (num >= 0.01) { return num.ToString("0.00", CultureInfo.InvariantCulture) + "%"; } if (num > 0.0) { return num.ToString("0.########", CultureInfo.InvariantCulture) + "%"; } return "0%"; } } public sealed class UpgraderUI { private sealed class CardView { public RectTransform Root; public Image Icon; public Image Background; public FrameGraphic Frame; public Button Button; public Text First; public Text Second; public CatalogItem Entry; public ItemData Item; public string Tooltip; public int Index = -1; public void SetSelected(bool selected) { //IL_0024: 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_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) ((Graphic)Background).color = (Color)(selected ? new Color(0.3f, 0.22f, 0.11f, 1f) : Card); ((Graphic)Frame).color = (selected ? Gold : Border); } } private readonly Plugin plugin; private GameObject root; private RectTransform panel; private RectTransform needle; private Font font; private WheelGraphic wheel; private Text sourceName; private Text sourceValue; private Text sourceQty; private Text targetName; private Text targetValue; private Text targetQuality; private Text percent; private Text status; private Text footer; private Text catalogCount; private Image sourceIcon; private Image targetIcon; private Button roll; private Button claim; private Button minus; private Button plus; private Button all; private Button clear; private Button reload; private Button category; private Button targetMinus; private Button targetPlus; private Text rollLabel; private Text claimLabel; private Text categoryLabel; private InputField search; private InputField targetQuantity; private RectTransform targetQuantityGroup; private ScrollRect inventoryScroll; private ScrollRect catalogScroll; private RectTransform inventoryContent; private RectTransform catalogContent; private readonly List<CardView> inventoryCards = new List<CardView>(); private readonly List<CardView> targetCards = new List<CardView>(); private readonly List<CatalogItem> matches = new List<CatalogItem>(); private List<ItemData> inventoryItems = new List<ItemData>(); private int inventoryStamp = int.MinValue; private bool catalogBound; private int filter; private bool lastVisible; private bool previousCursorVisible; private CursorLockMode previousCursorLock; private string footerDefault; private static readonly Color Background = new Color(0.055f, 0.068f, 0.083f, 0.985f); private static readonly Color Card = new Color(0.085f, 0.1f, 0.12f, 1f); private static readonly Color Border = new Color(0.29f, 0.26f, 0.19f, 1f); private static readonly Color Gold = new Color(0.96f, 0.68f, 0.24f, 1f); private static readonly Color TextColor = new Color(0.91f, 0.91f, 0.87f, 1f); private static readonly Color Muted = new Color(0.56f, 0.59f, 0.61f, 1f); private static readonly Color Green = new Color(0.4f, 0.85f, 0.56f, 1f); public bool Visible { get { if ((Object)(object)root != (Object)null) { return root.activeSelf; } return false; } } public UpgraderUI(Plugin plugin) { this.plugin = plugin; try { font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"); } catch { } if ((Object)(object)font == (Object)null) { try { font = Resources.GetBuiltinResource<Font>("Arial.ttf"); } catch { } } if ((Object)(object)font == (Object)null) { font = ((IEnumerable<Font>)Resources.FindObjectsOfTypeAll<Font>()).FirstOrDefault((Func<Font, bool>)((Font f) => (Object)(object)f != (Object)null && f.HasCharacter('Я'))); } if ((Object)(object)font == (Object)null) { throw new InvalidOperationException("No UI font available"); } Build(); root.SetActive(false); } private void Build() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_0218: 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_02d2: 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) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Unknown result type (might be due to invalid IL or missing references) root = new GameObject("Noctyra_ItemUpgrader", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); Object.DontDestroyOnLoad((Object)(object)root); Canvas component = root.GetComponent<Canvas>(); component.renderMode = (RenderMode)0; component.sortingOrder = 30000; CanvasScaler component2 = root.GetComponent<CanvasScaler>(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1600f, 900f); component2.matchWidthOrHeight = 0.5f; RectTransform obj = Rect(root.transform, "Shade", 0f, 0f, 1600f, 900f); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.sizeDelta = Vector2.zero; Paint(obj, new Color(0f, 0f, 0f, 0.67f), raycast: true); panel = Rect(root.transform, "Panel", 0f, 0f, 1080f, 820f); Paint(panel, Background, raycast: true); Outline(panel, Border, 2f); Label((Transform)(object)panel, "Title", "УЛУЧШЕНИЕ ПРЕДМЕТОВ", 0f, 374f, 850f, 44f, 27, Gold, (TextAnchor)4); Label((Transform)(object)panel, "Subtitle", "ПОСТАВЬ ПРЕДМЕТ · ВЫБЕРИ ЦЕЛЬ · ИСПЫТАЙ УДАЧУ", 0f, 342f, 850f, 25f, 12, Muted, (TextAnchor)4); Action((Transform)(object)panel, "Close", "×", 505f, 375f, 38f, 38f, delegate { Hide(); }, 24); Line((Transform)(object)panel, 0f, 325f, 1016f, Border); BuildSource(); BuildTarget(); BuildWheel(); roll = Action((Transform)(object)panel, "Upgrade", "УЛУЧШИТЬ", 0f, 29f, 350f, 48f, delegate { plugin.Roll(); }, 20, accent: true); rollLabel = ((Component)roll).GetComponentInChildren<Text>(); status = Label((Transform)(object)panel, "Status", "", 0f, -20f, 1000f, 42f, 14, Muted, (TextAnchor)4); Line((Transform)(object)panel, 0f, -48f, 1016f, Border); Label((Transform)(object)panel, "InventoryTitle", "ТВОЙ ИНВЕНТАРЬ", -265f, -72f, 488f, 30f, 15, Gold, (TextAnchor)3); Label((Transform)(object)panel, "CatalogTitle", "ВЫБЕРИ ЖЕЛАЕМЫЙ ПРЕДМЕТ", 265f, -72f, 488f, 30f, 15, Gold, (TextAnchor)3); inventoryScroll = Scroll((Transform)(object)panel, "Inventory", -265f, -226f, 500f, 272f, out inventoryContent, new Vector2(57f, 66f), 8); search = Search((Transform)(object)panel, 195f, -113f, 356f, 32f); ((UnityEvent<string>)(object)search.onValueChanged).AddListener((UnityAction<string>)delegate { RebuildTargets(); }); category = Action((Transform)(object)panel, "Category", "Все", 450f, -113f, 135f, 32f, CycleCategory, 12); categoryLabel = ((Component)category).GetComponentInChildren<Text>(); catalogScroll = Scroll((Transform)(object)panel, "Catalog", 265f, -253f, 500f, 218f, out catalogContent, new Vector2(116f, 92f), 4); ((UnityEvent<Vector2>)(object)catalogScroll.onValueChanged).AddListener((UnityAction<Vector2>)delegate { UpdateVisibleTargets(); }); catalogCount = Label((Transform)(object)panel, "Count", "", 255f, -383f, 180f, 22f, 11, Muted, (TextAnchor)5); reload = Action((Transform)(object)panel, "ReloadPrices", "ОБНОВИТЬ ЦЕНЫ", 447f, -383f, 142f, 27f, delegate { plugin.ReloadValues(); }, 10); footerDefault = plugin.HotkeyLabel + " / Esc — закрыть · Выбери ставку слева, затем цель справа"; footer = Label((Transform)(object)panel, "Footer", footerDefault, -168f, -383f, 660f, 27f, 11, Muted, (TextAnchor)3); } private void BuildSource() { //IL_0026: 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_0064: 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_00d1: 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_0171: Unknown result type (might be due to invalid IL or missing references) RectTransform val = Rect((Transform)(object)panel, "SourceSlot", -350f, 199f, 264f, 246f); Paint(val, Card); Outline(val, Border, 1f); Label((Transform)(object)val, "Caption", "ТВОЯ СТАВКА", 0f, 98f, 240f, 25f, 13, Muted, (TextAnchor)4); RectTransform rect = Rect((Transform)(object)val, "ItemIcon", 0f, 34f, 68f, 68f); sourceIcon = Paint(rect, Color.white); sourceIcon.preserveAspect = true; sourceName = Label((Transform)(object)val, "Name", "Выбери предмет снизу", 0f, -17f, 242f, 42f, 15, TextColor, (TextAnchor)4); sourceValue = Label((Transform)(object)val, "Value", "Ценность: —", 0f, -51f, 240f, 26f, 14, Gold, (TextAnchor)4); minus = Action((Transform)(object)val, "Minus", "−", -92f, -91f, 31f, 31f, delegate { plugin.SetQuantity(plugin.Quantity - 1); }, 18); sourceQty = Label((Transform)(object)val, "Quantity", "× 1", -25f, -91f, 80f, 31f, 15, TextColor, (TextAnchor)4); plus = Action((Transform)(object)val, "Plus", "+", 43f, -91f, 31f, 31f, delegate { plugin.SetQuantity(plugin.Quantity + 1); }, 18); all = Action((Transform)(object)val, "All", "ВСЁ", 92f, -91f, 51f, 31f, delegate { if (plugin.Source != null) { plugin.SetQuantity(plugin.Source.m_stack); } }, 10); clear = Action((Transform)(object)val, "Clear", "×", 108f, 97f, 23f, 23f, delegate { plugin.ClearSource(); }, 14); } private void BuildTarget() { //IL_0026: 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_0064: 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_00d1: 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_0137: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) RectTransform val = Rect((Transform)(object)panel, "TargetSlot", 350f, 199f, 264f, 246f); Paint(val, Card); Outline(val, Border, 1f); Label((Transform)(object)val, "Caption", "ЖЕЛАЕМЫЙ ПРЕДМЕТ", 0f, 98f, 240f, 25f, 13, Muted, (TextAnchor)4); RectTransform rect = Rect((Transform)(object)val, "ItemIcon", 0f, 43f, 64f, 64f); targetIcon = Paint(rect, Color.white); targetIcon.preserveAspect = true; targetName = Label((Transform)(object)val, "Name", "Выбери цель в каталоге", 0f, -7f, 242f, 34f, 15, TextColor, (TextAnchor)4); targetValue = Label((Transform)(object)val, "Value", "Ценность: —", 0f, -39f, 240f, 24f, 14, Gold, (TextAnchor)4); targetQuality = Label((Transform)(object)val, "Quality", "Качество 1", 0f, -63f, 236f, 18f, 10, Muted, (TextAnchor)4); claim = Action((Transform)(object)val, "Claim", "ЗАБРАТЬ", 0f, -91f, 218f, 31f, delegate { plugin.Claim(); }, 13, accent: true); claimLabel = ((Component)claim).GetComponentInChildren<Text>(); ((Component)claim).gameObject.SetActive(false); targetQuantityGroup = Rect((Transform)(object)val, "QuantityControls", 0f, -91f, 218f, 31f); targetMinus = Action((Transform)(object)targetQuantityGroup, "Minus", "−", -85f, 0f, 31f, 31f, delegate { plugin.SetTargetQuantity(plugin.TargetQuantity - 1); }, 18); targetPlus = Action((Transform)(object)targetQuantityGroup, "Plus", "+", 85f, 0f, 31f, 31f, delegate { plugin.SetTargetQuantity(plugin.TargetQuantity + 1); }, 18); targetQuantity = Search((Transform)(object)targetQuantityGroup, 0f, 0f, 108f, 31f); targetQuantity.contentType = (ContentType)2; targetQuantity.characterLimit = 5; targetQuantity.textComponent.alignment = (TextAnchor)4; ((Text)targetQuantity.placeholder).text = "Количество"; ((UnityEvent<string>)(object)targetQuantity.onValueChanged).AddListener((UnityAction<string>)delegate(string value) { if (int.TryParse(value, out var result) && result > 0) { plugin.SetTargetQuantity(result); if (result > plugin.MaximumRewardAmount) { targetQuantity.SetTextWithoutNotify(plugin.MaximumRewardAmount.ToString()); } } }); ((UnityEvent<string>)(object)targetQuantity.onEndEdit).AddListener((UnityAction<string>)delegate(string value) { plugin.SetTargetQuantity((!int.TryParse(value, out var result)) ? 1 : result); targetQuantity.SetTextWithoutNotify(plugin.TargetQuantity.ToString()); }); } private void BuildWheel() { //IL_0096: 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_00ee: 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_014e: 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) RectTransform val = Rect((Transform)(object)panel, "Wheel", 0f, 185f, 260f, 260f); wheel = ((Component)val).gameObject.AddComponent<WheelGraphic>(); ((Graphic)wheel).raycastTarget = false; needle = Rect((Transform)(object)val, "Needle", 0f, 0f, 260f, 260f); RectTransform obj = Rect((Transform)(object)needle, "Shaft", 0f, 0f, 2f, 119f); obj.pivot = new Vector2(0.5f, 0f); Paint(obj, new Color(0.96f, 0.91f, 0.73f, 1f)); ((Graphic)((Component)Rect((Transform)(object)needle, "ArrowTip", 0f, 116f, 16f, 18f)).gameObject.AddComponent<ArrowGraphic>()).color = Gold; ((Graphic)((Component)Rect((Transform)(object)val, "Center", 0f, 0f, 156f, 156f)).gameObject.AddComponent<DiskGraphic>()).color = Background; percent = Label((Transform)(object)val, "Percent", "—", 0f, 8f, 154f, 46f, 29, Gold, (TextAnchor)4); Label((Transform)(object)val, "ChanceLabel", "ШАНС УСПЕХА", 0f, -27f, 150f, 25f, 11, Muted, (TextAnchor)4); } public void Show() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (!Visible) { previousCursorVisible = Cursor.visible; previousCursorLock = Cursor.lockState; lastVisible = true; } root.SetActive(true); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; Refresh(force: true); } public void Hide() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (Visible) { Plugin.JustClosed(); } if ((Object)(object)root != (Object)null) { root.SetActive(false); } if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } if (lastVisible) { Cursor.lockState = previousCursorLock; Cursor.visible = previousCursorVisible; lastVisible = false; } } public void Destroy() { Hide(); if ((Object)(object)root != (Object)null) { Object.Destroy((Object)(object)root); } root = null; } public void SetAngle(float degrees) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)needle != (Object)null) { ((Transform)needle).localRotation = Quaternion.Euler(0f, 0f, 0f - degrees); } } public void ResetWheel() { SetAngle(0f); wheel.ClearResult(); } public void ShowResult(bool won) { wheel.SetResult(won); } public void Refresh(bool force) { //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)root == (Object)null)) { ItemData source = plugin.Source; CatalogItem catalogItem = ((plugin.HasReward && !plugin.Spinning) ? plugin.RewardItem : plugin.Target); sourceName.text = ((source == null) ? "Выбери предмет снизу" : (Name(source) + ((source.m_quality > 1) ? (" ★" + source.m_quality) : ""))); sourceValue.text = ((source == null) ? "Ценность: —" : ("Ценность ставки: " + Number(plugin.Stake))); sourceQty.text = "× " + plugin.Quantity; SetIcon(sourceIcon, (source == null) ? null : source.GetIcon()); targetName.text = ((catalogItem != null) ? catalogItem.Name : (plugin.HasReward ? "Сохранённая награда" : "Выбери цель в каталоге")); int amount = ((plugin.HasReward && !plugin.Spinning) ? plugin.RewardRemaining : plugin.TargetQuantity); targetValue.text = ((catalogItem == null) ? "Ценность: —" : ("Ценность цели: " + Number(RollMath.TargetValue(catalogItem.Value, amount)))); targetQuality.text = ((catalogItem == null) ? "Качество 1" : ("Качество 1 · за 1 шт.: " + Number(catalogItem.Value))); SetIcon(targetIcon, (catalogItem == null) ? null : catalogItem.Template.GetIcon()); ((Component)claim).gameObject.SetActive(plugin.HasReward && !plugin.Spinning); ((Selectable)claim).interactable = plugin.HasReward && !plugin.Spinning; claimLabel.text = "ЗАБРАТЬ × " + plugin.RewardRemaining; ((Component)targetQuantityGroup).gameObject.SetActive(!((Component)claim).gameObject.activeSelf); bool canChangeSelection = plugin.CanChangeSelection; ((Selectable)targetMinus).interactable = canChangeSelection && plugin.Target != null && plugin.TargetQuantity > 1; ((Selectable)targetPlus).interactable = canChangeSelection && plugin.Target != null && plugin.TargetQuantity < plugin.MaximumRewardAmount; ((Selectable)targetQuantity).interactable = canChangeSelection && plugin.Target != null; if (!targetQuantity.isFocused) { targetQuantity.SetTextWithoutNotify(plugin.TargetQuantity.ToString()); } ((Selectable)minus).interactable = canChangeSelection && source != null && plugin.Quantity > 1; ((Selectable)plus).interactable = canChangeSelection && source != null && plugin.Quantity < source.m_stack; ((Selectable)all).interactable = canChangeSelection && source != null && plugin.Quantity < source.m_stack; ((Selectable)clear).interactable = canChangeSelection && source != null; ((Selectable)roll).interactable = plugin.CanRoll(); rollLabel.text = (plugin.Spinning ? "ВРАЩАЕТСЯ…" : (plugin.HasReward ? "ЗАБЕРИ ВЫИГРЫШ" : "УЛУЧШИТЬ")); ((Selectable)reload).interactable = !plugin.Spinning; status.text = plugin.Status; ((Graphic)status).color = ((plugin.HasReward && !plugin.Spinning) ? Green : Muted); double displayChance = plugin.DisplayChance; percent.text = ((displayChance <= 0.0) ? "—" : RollMath.Percent(displayChance)); if (percent.text.Length > 8) { percent.fontSize = 17; } else { percent.fontSize = 29; } wheel.SetChance((float)displayChance); if (!plugin.Spinning && source != null) { wheel.ClearResult(); } RebuildInventory(); if (!catalogBound) { RebuildTargets(); } else { UpdateVisibleTargets(); } } } public void RefreshCatalog() { inventoryStamp = int.MinValue; RebuildTargets(); Refresh(force: false); } public IEnumerator Prewarm() { int targetCount = GridWindow.PoolSize(214.0, 96.0, 4); int inventoryCount = ((Humanoid)plugin.LocalPlayer).GetInventory().GetAllItems().Count; while (targetCards.Count < targetCount) { for (int i = 0; i < 4; i++) { if (targetCards.Count >= targetCount) { break; } targetCards.Add(CreateCard(target: true)); } yield return null; } while (inventoryCards.Count < inventoryCount) { for (int j = 0; j < 4; j++) { if (inventoryCards.Count >= inventoryCount) { break; } inventoryCards.Add(CreateCard(target: false)); } yield return null; } Refresh(force: false); int[] array = new int[4] { 10, 11, 15, 29 }; foreach (int num in array) { font.RequestCharactersInTexture("АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя0123456789×%—.,:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", num); yield return null; } } private void RebuildInventory() { //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)plugin.LocalPlayer == (Object)null) { return; } List<ItemData> allItems = ((Humanoid)plugin.LocalPlayer).GetInventory().GetAllItems(); int num = 17; foreach (ItemData item in allItems) { num = num * 31 + ((object)item).GetHashCode(); num = num * 31 + item.m_stack; num = num * 31 + item.m_quality; num = num * 31 + item.m_durability.GetHashCode(); num = num * 31 + ((object)Unsafe.As<Vector2i, Vector2i>(ref item.m_gridPos)/*cast due to .constrained prefix*/).GetHashCode(); num = num * 31 + (item.m_equipped ? 1 : 0); } if (num != inventoryStamp) { inventoryStamp = num; inventoryItems = (from i in allItems orderby i.m_gridPos.y, i.m_gridPos.x select i).ToList(); inventoryContent.sizeDelta = new Vector2(0f, (float)GridWindow.ContentHeight(inventoryItems.Count, 8, 66.0, 4.0)); } while (inventoryCards.Count < inventoryItems.Count) { inventoryCards.Add(CreateCard(target: false)); } for (int num2 = 0; num2 < inventoryCards.Count; num2++) { CardView cardView = inventoryCards[num2]; if (num2 >= inventoryItems.Count) { ((Component)cardView.Root).gameObject.SetActive(false); continue; } ItemData val = inventoryItems[num2]; ((Component)cardView.Root).gameObject.SetActive(true); cardView.Item = val; Position(cardView.Root, num2, 8, 57, 66); cardView.Icon.sprite = val.GetIcon(); ((Graphic)cardView.Icon).color = (Color)(val.m_equipped ? new Color(0.7f, 0.7f, 0.7f, 1f) : Color.white); cardView.First.text = "×" + val.m_stack; cardView.Second.text = (val.m_equipped ? "●" : ""); cardView.Tooltip = Name(val) + " · ценность 1 шт.: " + Number(plugin.Catalog.StakeValue(val, 1)) + (val.m_equipped ? " · сначала сними" : ""); ((Selectable)cardView.Button).interactable = plugin.CanChangeSelection && !val.m_equipped && plugin.Catalog.Find(val) != null; cardView.SetSelected(plugin.Source == val); } } private void CycleCategory() { filter = (filter + 1) % 4; categoryLabel.text = (new string[4] { "Все", "Снаряжение", "Ресурсы", "Еда / зелья" })[filter]; catalogScroll.verticalNormalizedPosition = 1f; RebuildTargets(); } private bool MatchesFilter(CatalogItem entry) { string text = ((object)Unsafe.As<ItemType, ItemType>(ref entry.Template.m_shared.m_itemType)/*cast due to .constrained prefix*/).ToString(); if (filter == 1) { if (!text.Contains("Weapon")) { switch (text) { default: return text == "Trinket"; case "Bow": case "Shield": case "Helmet": case "Chest": case "Legs": case "Shoulder": case "Utility": case "Tool": break; } } return true; } if (filter == 2) { if (!(text == "Material") && !(text == "Trophy")) { return text == "Misc"; } return true; } if (filter == 3) { if (!(text == "Consumable")) { return text == "Fish"; } return true; } return true; } private void RebuildTargets() { //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) if (plugin.Catalog == null || (Object)(object)catalogContent == (Object)null) { return; } string text = (((Object)(object)search == (Object)null) ? "" : search.text.Trim()); matches.Clear(); foreach (CatalogItem item in plugin.Catalog.Items) { if (MatchesFilter(item) && (text.Length == 0 || item.Name.IndexOf(text, StringComparison.CurrentCultureIgnoreCase) >= 0 || item.Id.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0)) { matches.Add(item); } } catalogBound = true; catalogContent.sizeDelta = new Vector2(0f, (float)GridWindow.ContentHeight(matches.Count, 4, 92.0, 4.0)); catalogContent.anchoredPosition = Vector2.zero; catalogScroll.StopMovement(); int num = GridWindow.PoolSize(214.0, 96.0, 4); while (targetCards.Count < num) { targetCards.Add(CreateCard(target: true)); } catalogCount.text = matches.Count + " / " + plugin.Catalog.Items.Count + " предметов"; UpdateVisibleTargets(); } private void UpdateVisibleTargets() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) int num = GridWindow.FirstIndex(catalogContent.anchoredPosition.y, 96.0, 4, matches.Count); for (int i = 0; i < targetCards.Count; i++) { CardView cardView = targetCards[i]; int num2 = num + i; if (num2 >= matches.Count) { ((Component)cardView.Root).gameObject.SetActive(false); cardView.Entry = null; continue; } CatalogItem catalogItem = matches[num2]; ((Component)cardView.Root).gameObject.SetActive(true); if (cardView.Index != num2) { Position(cardView.Root, num2, 4, 116, 92); cardView.Index = num2; } if (cardView.Entry != catalogItem) { cardView.Entry = catalogItem; cardView.Icon.sprite = catalogItem.Template.GetIcon(); cardView.First.text = catalogItem.Name; cardView.Second.text = Number(catalogItem.Value); cardView.Tooltip = catalogItem.Name + " · " + catalogItem.Id + " · ценность: " + Number(catalogItem.Value); } ((Selectable)cardView.Button).interactable = plugin.CanChangeSelection; cardView.SetSelected(plugin.Target == catalogItem); } } private CardView CreateCard(bool target) { //IL_00a8: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: 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_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Expected O, but got Unknown //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: 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) CardView card = new CardView(); card.Root = Rect((Transform)(object)(target ? catalogContent : inventoryContent), target ? "TargetCell" : "InventoryCell", 0f, 0f, target ? 116 : 57, target ? 92 : 66); RectTransform obj = card.Root; RectTransform obj2 = card.Root; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); obj2.anchorMax = val; obj.anchorMin = val; card.Root.pivot = new Vector2(0f, 1f); card.Background = Paint(card.Root, Card, raycast: true); Outline(card.Root, Border, 1f); card.Frame = ((Component)((Transform)card.Root).Find("Frame")).GetComponent<FrameGraphic>(); card.Button = ((Component)card.Root).gameObject.AddComponent<Button>(); ((Selectable)card.Button).targetGraphic = (Graphic)(object)card.Background; Navigation navigation = ((Selectable)card.Button).navigation; ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)card.Button).navigation = navigation; ((UnityEvent)card.Button.onClick).AddListener((UnityAction)delegate { if (target) { if (card.Entry != null) { plugin.SelectTarget(card.Entry); } } else if (card.Item != null) { plugin.SelectSource(card.Item); } }); card.Icon = Paint(Rect((Transform)(object)card.Root, "Icon", 0f, target ? 22 : 8, target ? 30 : 36, target ? 30 : 36), Color.white); card.Icon.preserveAspect = true; card.First = Label((Transform)(object)card.Root, "First", "", 0f, target ? (-10) : (-21), target ? 108 : 54, target ? 32 : 18, 10, TextColor, (TextAnchor)4); card.Second = (target ? Label((Transform)(object)card.Root, "Second", "", 0f, -34f, 108f, 20f, 11, Gold, (TextAnchor)4) : Label((Transform)(object)card.Root, "Equipped", "", 18f, 21f, 16f, 16f, 10, Gold, (TextAnchor)4)); ItemTip itemTip = ((Component)card.Root).gameObject.AddComponent<ItemTip>(); itemTip.Enter = delegate { //IL_0026: Unknown result type (might be due to invalid IL or missing references) footer.text = card.Tooltip; ((Graphic)footer).color = TextColor; }; itemTip.Exit = delegate { //IL_0026: Unknown result type (might be due to invalid IL or missing references) footer.text = footerDefault; ((Graphic)footer).color = Muted; }; ((Component)card.Root).gameObject.SetActive(false); return card; } private static void Position(RectTransform rect, int index, int columns, int width, int height) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) rect.anchoredPosition = new Vector2((float)(8 + index % columns * (width + 3)), (float)(-8 - index / columns * (height + 4))); } private static string Name(ItemData item) { if (Localization.instance != null) { return Localization.instance.Localize(item.m_shared.m_name); } return item.m_shared.m_name; } private static string Number(double value) { if (!(value >= 10000.0)) { return value.ToString("0.##", CultureInfo.InvariantCulture); } return value.ToString("N0", CultureInfo.InvariantCulture); } private static void SetIcon(Image image, Sprite sprite) { image.sprite = sprite; ((Behaviour)image).enabled = (Object)(object)sprite != (Object)null; } private static RectTransform Rect(Transform parent, string name, float x, float y, float width, float height) { //IL_0014: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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) RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 0.5f); component.anchorMax = val; component.anchorMin = val; component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(x, y); component.sizeDelta = new Vector2(width, height); return component; } private static Image Paint(RectTransform rect, Color color, bool raycast = false) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) Image obj = ((Component)rect).gameObject.AddComponent<Image>(); ((Graphic)obj).color = color; ((Graphic)obj).raycastTarget = raycast; return obj; } private static void Outline(RectTransform rect, Color color, float thickness) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) FrameGraphic frameGraphic = ((Component)Rect((Transform)(object)rect, "Frame", 0f, 0f, rect.sizeDelta.x, rect.sizeDelta.y)).gameObject.AddComponent<FrameGraphic>(); ((Graphic)frameGraphic).color = color; frameGraphic.Thickness = thickness; ((Graphic)frameGraphic).raycastTarget = false; } private void Line(Transform parent, float x, float y, float width, Color color) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) Paint(Rect(parent, "Divider", x, y, width, 1f), color); } private Text Label(Transform parent, string name, string text, float x, float y, float w, float h, int size, Color color, TextAnchor align) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) Text obj = ((Component)Rect(parent, name, x, y, w, h)).gameObject.AddComponent<Text>(); obj.font = font; obj.text = text; obj.fontSize = size; ((Graphic)obj).color = color; obj.alignment = align; ((Graphic)obj).raycastTarget = false; obj.supportRichText = false; obj.horizontalOverflow = (HorizontalWrapMode)0; obj.verticalOverflow = (VerticalWrapMode)0; return obj; } private Button Action(Transform parent, string name, string text, float x, float y, float w, float h, Action callback, int size, bool accent = false) { //IL_0052: 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_006a: 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_008c: 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_00a8: 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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_016b: 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) RectTransform val = Rect(parent, name, x, y, w, h); Image targetGraphic = Paint(val, accent ? new Color(0.81f, 0.51f, 0.14f, 1f) : new Color(0.13f, 0.15f, 0.17f, 1f), raycast: true); Outline(val, accent ? Gold : Border, 1f); Button obj = ((Component)val).gameObject.AddComponent<Button>(); ((Selectable)obj).targetGraphic = (Graphic)(object)targetGraphic; ColorBlock colors = ((Selectable)obj).colors; ((ColorBlock)(ref colors)).highlightedColor = new Color(1.17f, 1.17f, 1.17f, 1f); ((ColorBlock)(ref colors)).pressedColor = new Color(0.72f, 0.72f, 0.72f, 1f); ((ColorBlock)(ref colors)).disabledColor = new Color(0.6f, 0.6f, 0.6f, 0.65f); ((Selectable)obj).colors = colors; Navigation navigation = ((Selectable)obj).navigation; ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)obj).navigation = navigation; ((UnityEvent)obj.onClick).AddListener((UnityAction)delegate { callback(); }); Label((Transform)(object)val, "Label", text, 0f, 0f, w - 8f, h - 4f, size, (Color)(accent ? new Color(0.14f, 0.09f, 0.03f, 1f) : TextColor), (TextAnchor)4); return obj; } private InputField Search(Transform parent, float x, float y, float w, float h) { //IL_0013: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) RectTransform val = Rect(parent, "Search", x, y, w, h); Image targetGraphic = Paint(val, Card, raycast: true); Outline(val, Border, 1f); InputField obj = ((Component)val).gameObject.AddComponent<InputField>(); ((Selectable)obj).targetGraphic = (Graphic)(object)targetGraphic; obj.characterLimit = 64; Text val2 = Label((Transform)(object)val, "Text", "", 0f, 0f, w - 18f, h - 4f, 13, TextColor, (TextAnchor)3); val2.horizontalOverflow = (HorizontalWrapMode)1; obj.textComponent = val2; Text placeholder = Label((Transform)(object)val, "Placeholder", "Поиск по названию или ID…", 0f, 0f, w - 18f, h - 4f, 12, Muted, (TextAnchor)3); obj.placeholder = (Graphic)(object)placeholder; obj.lineType = (LineType)0; return obj; } private static ScrollRect Scroll(Transform parent, string name, float x, float y, float width, float height, out RectTransform content, Vector2 cell, int columns) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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) RectTransform obj = Rect(parent, name, x, y, width, height); Paint(obj, new Color(0.035f, 0.044f, 0.054f, 1f), raycast: true); Outline(obj, Border, 1f); ScrollRect val = ((Component)obj).gameObject.AddComponent<ScrollRect>(); val.horizontal = false; val.vertical = true; val.movementType = (MovementType)2; val.scrollSensitivity = 30f; RectTransform val2 = Rect((Transform)(object)obj, "Viewport", 0f, 0f, width - 4f, height - 4f); Paint(val2, Color.white, raycast: true); ((Component)val2).gameObject.AddComponent<Mask>().showMaskGraphic = false; content = Rect((Transform)(object)val2, "Content", 0f, 0f, width - 4f, height); content.anchorMin = new Vector2(0f, 1f); content.anchorMax = new Vector2(1f, 1f); content.pivot = new Vector2(0.5f, 1f); content.anchoredPosition = Vector2.zero; content.sizeDelta = new Vector2(0f, height); val.viewport = val2; val.content = content; val.verticalNormalizedPosition = 1f; return val; } } public sealed class FrameGraphic : MaskableGraphic { public float Thickness = 1f; protected override void OnPopulateMesh(VertexHelper vh) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) vh.Clear(); Rect rect = ((Graphic)this).rectTransform.rect; float thickness = Thickness; Add(vh, ((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMax - thickness, ((Rect)(ref rect)).xMax, ((Rect)(ref rect)).yMax); Add(vh, ((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMin, ((Rect)(ref rect)).xMax, ((Rect)(ref rect)).yMin + thickness); Add(vh, ((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMin + thickness, ((Rect)(ref rect)).xMin + thickness, ((Rect)(ref rect)).yMax - thickness); Add(vh, ((Rect)(ref rect)).xMax - thickness, ((Rect)(ref rect)).yMin + thickness, ((Rect)(ref rect)).xMax, ((Rect)(ref rect)).yMax - thickness); } private void Add(VertexHelper vh, float x0, float y0, float x1, float y1) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) int currentVertCount = vh.currentVertCount; vh.AddVert(Vector2.op_Implicit(new Vector2(x0, y0)), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero)); vh.AddVert(Vector2.op_Implicit(new Vector2(x0, y1)), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero)); vh.AddVert(Vector2.op_Implicit(new Vector2(x1, y1)), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero)); vh.AddVert(Vector2.op_Implicit(new Vector2(x1, y0)), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero)); vh.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2); vh.AddTriangle(currentVertCount, currentVertCount + 2, currentVertCount + 3); } } public sealed class ItemTip : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { public Action Enter; public Action Exit; public void OnPointerEnter(PointerEventData e) { if (Enter != null) { Enter(); } } public void OnPointerExit(PointerEventData e) { if (Exit != null) { Exit(); } } } public sealed class WheelGraphic : MaskableGraphic { private float chance; private Color ticks = new Color(0.36f, 0.39f, 0.44f, 1f); public void SetChance(float value) { if (Math.Abs(chance - value) > 1E-08f) { chance = Mathf.Clamp01(value); ((Graphic)this).SetVerticesDirty(); } } public void SetResult(bool won) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) ticks = (won ? new Color(0.4f, 0.85f, 0.56f, 1f) : new Color(0.78f, 0.3f, 0.22f, 1f)); ((Graphic)this).SetVerticesDirty(); } public void ClearResult() { //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) ticks = new Color(0.36f, 0.39f, 0.44f, 1f); ((Graphic)this).SetVerticesDirty(); } protected override void OnPopulateMesh(VertexHelper vh) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) vh.Clear(); Rect rect = ((Graphic)this).rectTransform.rect; float width = ((Rect)(ref rect)).width; rect = ((Graphic)this).rectTransform.rect; float num = Mathf.Min(width, ((Rect)(ref rect)).height) / 2f; Arc(vh, num * 0.62f, num * 0.82f, 360f, new Color(0.17f, 0.2f, 0.25f, 1f)); if (chance > 0f) { Arc(vh, num * 0.62f, num * 0.82f, chance * 360f, new Color(1f, 0.61f, 0.17f, 1f)); } Vector2 val = default(Vector2); for (int i = 0; i < 60; i++) { float num2 = (float)i * (float)Math.PI * 2f / 60f; ((Vector2)(ref val))..ctor(Mathf.Sin(num2), Mathf.Cos(num2)); Vector2 val2 = new Vector2(val.y, 0f - val.x) * ((i % 5 == 0) ? 1.5f : 1f); Vector2 val3 = val * num * ((i % 5 == 0) ? 0.86f : 0.89f); Vector2 val4 = val * num * 0.95f; Quad(vh, val3 - val2, val3 + val2, val4 + val2, val4 - val2, ticks); } } private static void Arc(VertexHelper vh, float inner, float outer, float degrees, Color tint) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) int num = Math.Max(1, (int)Math.Ceiling(degrees / 2f)); Vector2 val = default(Vector2); Vector2 val2 = default(Vector2); for (int i = 0; i < num; i++) { float num2 = degrees * (float)i / (float)num * ((float)Math.PI / 180f); float num3 = degrees * (float)(i + 1) / (float)num * ((float)Math.PI / 180f); ((Vector2)(ref val))..ctor(Mathf.Sin(num2), Mathf.Cos(num2)); ((Vector2)(ref val2))..ctor(Mathf.Sin(num3), Mathf.Cos(num3)); Quad(vh, val * inner, val * outer, val2 * outer, val2 * inner, tint); } } private static void Quad(VertexHelper vh, Vector2 a, Vector2 b, Vector2 c, Vector2 d, Color tint) { //IL_0008: 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_000e: 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_0025: 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_002b: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) int currentVertCount = vh.currentVertCount; vh.AddVert(Vector2.op_Implicit(a), Color32.op_Implicit(tint), Vector4.op_Implicit(Vector2.zero)); vh.AddVert(Vector2.op_Implicit(b), Color32.op_Implicit(tint), Vector4.op_Implicit(Vector2.zero)); vh.AddVert(Vector2.op_Implicit(c), Color32.op_Implicit(tint), Vector4.op_Implicit(Vector2.zero)); vh.AddVert(Vector2.op_Implicit(d), Color32.op_Implicit(tint), Vector4.op_Implicit(Vector2.zero)); vh.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2); vh.AddTriangle(currentVertCount, currentVertCount + 2, currentVertCount + 3); } } public sealed class ArrowGraphic : MaskableGraphic { protected override void OnPopulateMesh(VertexHelper vh) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) vh.Clear(); Rect rect = ((Graphic)this).rectTransform.rect; float num = ((Rect)(ref rect)).width / 2f; rect = ((Graphic)this).rectTransform.rect; float num2 = ((Rect)(ref rect)).height / 2f; vh.AddVert(Vector2.op_Implicit(new Vector2(0f, num2)), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero)); vh.AddVert(Vector2.op_Implicit(new Vector2(num, 0f - num2)), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero)); vh.AddVert(Vector2.op_Implicit(new Vector2(0f - num, 0f - num2)), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero)); vh.AddTriangle(0, 1, 2); } } public sealed class DiskGraphic : MaskableGraphic { protected override void OnPopulateMesh(VertexHelper vh) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) vh.Clear(); Rect rect = ((Graphic)this).rectTransform.rect; float width = ((Rect)(ref rect)).width; rect = ((Graphic)this).rectTransform.rect; float num = Mathf.Min(width, ((Rect)(ref rect)).height) / 2f; vh.AddVert(Vector2.op_Implicit(Vector2.zero), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero)); for (int i = 0; i <= 64; i++) { float num2 = (float)i * (float)Math.PI * 2f / 64f; vh.AddVert(Vector2.op_Implicit(new Vector2(Mathf.Cos(num2), Mathf.Sin(num2)) * num), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero)); } for (int j = 1; j <= 64; j++) { vh.AddTriangle(0, j, j + 1); } } } public sealed class CatalogItem { public string Id; public GameObject Prefab; public ItemData Template; public double Value; public string Reason; private string localizedName; public string Name => localizedName ?? (localizedName = ((Localization.instance == null) ? Id : Localization.instance.Localize(Template.m_shared.m_name))); } public sealed class ValueCatalog { public readonly List<CatalogItem> Items = new List<CatalogItem>(); private readonly Dictionary<string, CatalogItem> byId = new Dictionary<string, CatalogItem>(StringComparer.Ordinal); private Dictionary<string, double> prices; private readonly Dictionary<string, Recipe> recipes = new Dictionary<string, Recipe>(); private readonly Dictionary<string, double> computed = new Dictionary<string, double>(); private readonly Dictionary<string, string> reasons = new Dictionary<string, string>(); private readonly string folder; private readonly ManualLogSource log; private readonly double markup; private static readonly CultureInfo Inv = CultureInfo.InvariantCulture; public string PricePath => Path.Combine(folder, "ItemValues.json"); public ValueCatalog(string folder, double markup, ManualLogSource log) { this.folder = folder; this.markup = markup; this.log = log; } public void Build() { //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Invalid comparison between Unknown and I4 Items.Clear(); byId.Clear(); recipes.Clear(); computed.Clear(); reasons.Clear(); prices = Defaults(); Directory.CreateDirectory(folder); if (File.Exists(PricePath)) { foreach (KeyValuePair<string, double> item in JsonConvert.DeserializeObject<Dictionary<string, double>>(File.ReadAllText(PricePath)) ?? throw new InvalidDataException("ItemValues.json must contain an object of prefab IDs and prices.")) { if (item.Value < 0.0 || double.IsInfinity(item.Value) || double.IsNaN(item.Value)) { throw new InvalidDataException("Invalid price for " + item.Key); } prices[item.Key] = item.Value; } } foreach (GameObject item2 in ObjectDB.instance.m_items) { if ((Object)(object)item2 == (Object)null) { continue; } ItemDrop component = item2.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null) && component.m_itemData != null) { ItemData itemData = component.m_itemData; if (itemData.m_shared != null && !string.IsNullOrEmpty(itemData.m_shared.m_name) && itemData.m_shared.m_icons != null && itemData.m_shared.m_icons.Length != 0 && !((Object)(object)itemData.m_shared.m_icons[0] == (Object)null) && (int)itemData.m_shared.m_itemType != 0 && (int)itemData.m_shared.m_itemType != 10 && !byId.ContainsKey(((Object)item2).name)) { CatalogItem catalogItem = new CatalogItem { Id = ((Object)item2).name, Prefab = item2, Template = itemData }; byId.Add(catalogItem.Id, catalogItem); } } } foreach (Recipe recipe in ObjectDB.instance.m_recipes) { if (!((Object)(object)recipe == (Object)null) && recipe.m_enabled && !((Object)(object)recipe.m_item == (Object)null) && recipe.m_amount > 0) { string name = ((Object)((Component)recipe.m_item).gameObject).name; if (!recipes.ContainsKey(name)) { recipes[name] = recipe; } } } foreach (CatalogItem value in byId.Values) { value.Value = Math.Round(Resolve(value.Id, new HashSet<string>()), 4); value.Reason = (reasons.ContainsKey(value.Id) ? reasons[value.Id] : "Configured value"); if (!prices.ContainsKey(value.Id)) { prices[value.Id] = value.Value; } if (value.Value > 0.0) { Items.Add(value); } } Items.Sort((CatalogItem a, CatalogItem b) => string.Compare(a.Name, b.Name, StringComparison.CurrentCultureIgnoreCase)); AtomicWrite(PricePath, JsonConvert.SerializeObject((object)prices.OrderBy((KeyValuePair<string, double> p) => p.Key).ToDictionary((KeyValuePair<string, double> p) => p.Key, (KeyValuePair<string, double> p) => p.Value), (Formatting)1)); ExportCsv(); log.LogInfo((object)("ItemUpgrader: valued " + Items.Count + " items; prices at " + PricePath)); } public CatalogItem Find(string id) { if (id == null || !byId.TryGetValue(id, out var value) || !(value.Value > 0.0)) { return null; } return value; } public CatalogItem Find(ItemData item) { if (item != null && !((Object)(object)item.m_dropPrefab == (Object)null)) { return Find(((Object)item.m_dropPrefab).name); } return null; } public double StakeValue(ItemData item, int count) { CatalogItem catalogItem = Find(item); if (catalogItem == null || count < 1) { return 0.0; } double num = catalogItem.Value; if (recipes.TryGetValue(catalogItem.Id, out var value) && item.m_quality > 1) { for (int i = 2; i <= Math.Min(item.m_quality, 100); i++) { double num2 = IngredientCost(value, i, new HashSet<string>()); num += num2 * markup; } } else if (item.m_quality > 1) { num *= 1.0 + 0.35 * (double)(Math.Min(item.m_quality, 100) - 1); } if (item.m_shared.m_useDurability) { float maxDurability = item.GetMaxDurability(); if (maxDurability > 0f) { num *= 0.25 + 0.75 * (double)Mathf.Clamp01(item.m_durability / maxDurability); } } return num * (double)count; } private double Resolve(string id, HashSet<string> visiting) { if (prices.TryGetValue(id, out var value)) { reasons[id] = "Assigned resource / configured value"; return value; } if (computed.TryGetValue(id, out value)) { return value; } if (!visiting.Add(id)) { return Fallback(id); } if (recipes.TryGetValue(id, out var value2)) { double num = IngredientCost(value2, 1, visiting); if (num > 0.0) { value = (num * markup + StationCost(value2)) / (double)Math.Max(1, value2.m_amount); reasons[id] = "Recipe ingredients + " + ((markup - 1.0) * 100.0).ToString("0", Inv) + "% labor + station effort / recipe yield"; } else { value = Fallback(id); reasons[id] = "Estimated: item type, tier and statistics (no priced recipe)"; } } else { value = Fallback(id); reasons[id] = "Estimated: item type, tier and statistics (no priced recipe)"; } visiting.Remove(id); computed[id] = value; return value; } private double IngredientCost(Recipe recipe, int quality, HashSet<string> visiting) { double num = 0.0; double num2 = double.MaxValue; if (recipe.m_resources == null) { return 0.0; } Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { if (val == null || (Object)(object)val.m_resItem == (Object)null) { continue; } int amount = val.GetAmount(quality); if (amount > 0) { double num3 = Resolve(((Object)((Component)val.m_resItem).gameObject).name, visiting) * (double)amount; if (num3 > 0.0) { num2 = Math.Min(num2, num3); } num += num3; } } if (!recipe.m_requireOnlyOneIngredient) { return num; } if (num2 != double.MaxValue) { return num2; } return 0.0; } private static double StationCost(Recipe recipe) { string text = (((Object)(object)recipe.m_craftingStation == (Object)null) ? "" : ((Object)((Component)recipe.m_craftingStation).gameObject).name.ToLowerInvariant()); double num = 2.0; if (text.Contains("workbench")) { num = 5.0; } if (text.Contains("cauldron")) { num = 12.0; } if (text.Contains("forge")) { num = 25.0; } if (text.Contains("blackforge")) { num = 90.0; } if (text.Contains("mage")) { num = 110.0; } if (text.Contains("north") || text.Contains("ice")) { num = 180.0; } return num * (double)Math.Max(1, recipe.m_minStationLevel); } private double Fallback(string id) { if (!byId.TryGetValue(id, out var value)) { return 10.0; } SharedData shared = value.Template.m_shared; string name = id.ToLowerInvariant(); int num = Math.Max(1, Math.Min(8, shared.m_toolTier + 1)); string[][] array = new string[8][] { new string[4] { "flint", "leather", "rag", "wood" }, new string[4] { "bronze", "troll", "copper", "tin" }, new string[4] { "iron", "root", "draugr", "abomination" }, new string[5] { "silver", "wolf", "fenris", "mountain", "drake" }, new string[5] { "blackmetal", "padded", "lox", "fuling", "goblin" }, new string[7] { "carapace", "mist", "seeker", "eitr", "dvergr", "jotun", "jotunn" }, new string[8] { "ash", "flametal", "morgen", "asksvin", "volture", "charred", "fader", "dvergrash" }, new string[8] { "north", "frost", "glacier", "ice", "winter", "boreal", "jormun", "nidhogg" } }; for (int i = 0; i < array.Length; i++) { if (array[i].Any((string k) => name.Contains(k))) { num = Math.Max(num, i + 1); } } double num2 = (new double[8] { 1.0, 3.0, 7.0, 12.0, 20.0, 35.0, 60.0, 95.0 })[num - 1]; switch (((object)Unsafe.As<ItemType, ItemType>(ref shared.m_itemType)/*cast due to .constrained prefix*/).ToString()) { case "Trophy": return 80.0 * num2; case "Fish": return 18.0 * num2; case "Consumable": return Math.Max(8.0 * num2, (double)(shared.m_food + shared.m_foodStamina + 2f * shared.m_foodEitr) * 0.6 * (double)Math.Max(1f, shared.m_foodBurnTime / 1200f)); case "Ammo": case "AmmoNonEquipable": return Math.Max(1.0, 2.0 * num2); case "Material": return Math.Max(5.0 * num2, shared.m_value); case "Trinket": return 150.0 * num2; case "Misc": return Math.Max(25.0 * num2, shared.m_value); case "Utility": return Math.Max(150.0 * num2, shared.m_value); default: return Math.Max(75.0 * num2, shared.m_armor * 20f + shared.m_blockPower * 5f + ((DamageTypes)(ref shared.m_damages)).GetTotalDamage() * 8f); } } private void ExportCsv() { StringBuilder stringBuilder = new StringBuilder("Prefab;Name;Value;Category;Basis\n"); foreach (CatalogItem item in Items.OrderBy((CatalogItem i) => i.Id)) { stringBuilder.Append(Csv(item.Id)).Append(';').Append(Csv(item.Name)) .Append(';') .Append(item.Value.ToString("0.####", Inv)) .Append(';') .Append(Csv(((object)Unsafe.As<ItemType, ItemType>(ref item.Template.m_shared.m_itemType)/*cast due to .constrained prefix*/).ToString())) .Append(';') .Append(Csv(item.Reason)) .Append('\n'); } AtomicWrite(Path.Combine(folder, "Catalog.csv"), stringBuilder.ToString()); } private static string Csv(string s) { return "\"" + (s ?? "").Replace("\"", "\"\"") + "\""; } private static void AtomicWrite(string path, string content) { string text = path + ".tmp"; File.WriteAllText(text, content, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true)); if (File.Exists(path)) { File.Replace(text, path, null); } else { File.Move(text, path); } } public static Dictionary<string, double> Defaults() { Dictionary<string, double> dictionary = new Dictionary<string, double>(StringComparer.Ordinal); string[] array = "\nWood=1;Stone=2;Resin=2;Coal=3;FineWood=7;RoundLog=4;ElderBark=12;YggdrasilWood=30;Blackwood=55;\nSwordCheat=0;MaceCheat=0;SledgeCheat=0;\nFlint=5;LeatherScraps=7;DeerHide=12;BoneFragments=5;Feathers=6;GreydwarfEye=7;NeckTail=9;RawMeat=9;DeerMeat=12;BoarMeat=9;\nRaspberry=4;Blueberries=6;Cloudberry=12;Mushroom=5;MushroomYellow=12;Dandelion=3;Honey=10;BeechSeeds=3;BirchSeeds=10;FirCone=5;PineCone=5;\nAncientSeed=50;Amber=5;AmberPearl=10;Ruby=20;Coins=1;TrollHide=35;SurtlingCore=90;\nCopperOre=24;TinOre=28;Copper=38;Tin=42;Bronze=135;CopperScrap=36;ScrapIron=65;Iron=85;\nEntrails=24;Bloodbag=28;Guck=35;Chain=120;WitheredBone=65;Chitin=40;Ooze=18;Root=90;TurnipSeeds=22;Turnip=12;CarrotSeeds=12;Carrot=8;\nSilverOre=95;Silver=120;Obsidian=45;FreezeGland=55;WolfPelt=50;WolfFang=65;WolfMeat=30;Crystal=40;FenrisHair=90;FenrisClaw=130;DragonEgg=350;\nBlackMetalScrap=90;BlackMetal=115;Barley=18;BarleyFlour=28;Flax=22;LinenThread=36;LoxMeat=55;LoxPelt=80;Needle=45;Tar=60;Bilebag=400;SoftTissue=170;\nJotunPuffs=38;Magecap=45;Sap=55;Eitr=340;Carapace=80;Mandible=150;SeekerMeat=65;HareMeat=60;ScaleHide=75;BlackCore=450;DvergrKeyFragment=650;DvergrKey=6500;DvergrNeedle=500;\nFlametalOre=220;FlametalOreNew=220;Flametal=270;FlametalNew=270;Ashwood=55;CharredBone=80;SulfurStone=95;Sulfur=95;ProustitePowder=120;MorgenHeart=850;MorgenSinew=500;\nAsksvinHide=160;AsksvinTail=130;AsksvinMeat=125;VoltureMeat=95;VoltureEgg=120;VoltureFeather=95;CelestialFeather=950;BonemawSerpentTooth=300;BonemawSerpentMeat=180;\nSmokePuff=65;Fiddleheadfern=70;Vineberry=70;MoltenCore=1000;GemstoneRed=2300;GemstoneBlue=2300;GemstoneGreen=2300;DvergrKeyAshlands=4500;BellFragment=800;\nSerpentMeat=70;SerpentScale=100;Egg=120;ChickenMeat=30;RottenMeat=3;RoyalJelly=90;MechanicalSpring=500;\nYmirRemains=120;Thunderstone=50;FishingRod=350;FishingBait=2;Megingjord=950;HelmetDverger=620;Wishbone=850;CryptKey=750;BeltStrength=950;\nTrophyBoar=50;TrophyDeer=60;TrophyNeck=45;TrophyGreydwarf=60;TrophyGreydwarfBrute=100;TrophyGreydwarfShaman=100;TrophySkeleton=80;TrophySkeletonPoison=140;TrophyTroll=250;\nTrophySurtling=160;TrophyLeech=150;TrophyDraugr=150;TrophyDraugrElite=260;TrophyBlob=130;TrophyAbomination=450;TrophyWraith=320;\nTrophyWolf=250;TrophyHatchling=300;TrophyFenring=450;TrophyCultist=650;TrophySGolem=650;TrophySerpent=650;\nTrophyGoblin=320;TrophyGoblinBrute=800;TrophyGoblinShaman=650;TrophyDeathsquito=250;TrophyLox=650;TrophyGrowth=450;\nTrophySeeker=550;TrophySeekerBrute=1000;TrophyGjall=1200;TrophyHare=400;TrophyDvergr=700;\nTrophyMorgen=1800;TrophyAsksvin=1100;TrophyVolture=900;TrophyCharredMelee=850;TrophyCharredArcher=850;TrophyCharredMage=1200;TrophyBonemawSerpent=1700;TrophyFallenValkyrie=2600;\nTrophyEikthyr=600;TrophyTheElder=1500;TrophyBonemass=3000;TrophyDragonQueen=5000;TrophyGoblinKing=8000;TrophySeekerQueen=14000;TrophyFader=24000;\nFish1=16;Fish2=24;Fish3=32;Fish4_cave=90;Fish5=80;Fish6=65;Fish7=85;Fish8=75;Fish9=150;Fish10=180;Fish11=200;Fish12=120;\nFishRaw=14;FishingBaitForest=12;FishingBaitSwamp=20;FishingBaitMountain=30;FishingBaitPlains=35;FishingBaitMistlands=55;FishingBaitOcean=45;FishingBaitAshlands=75;FishingBaitDeepNorth=90;\nAcorn=12;FulingTotem=600;GoblinTotem=600;TornSpirit=2000;QueenDrop=6000;FaderDrop=10000;EikthyrDrop=180;HardAntler=180;DragonTear=1000;\nBushSeeds=6;VineberrySeeds=110;AsksvinEgg=450;AsksvinEggWarm=450;BogWitchKvastur=500;BogWitchRat=100;\n".Split(new char[3] { ';', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Trim().Split('='); if (array2.Length == 2) { dictionary[array2[0].Trim()] = double.Parse(array2[1], Inv); } } return dictionary; } }