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 ChestItemsHoverDisplay v0.3.3
plugins/CDEV.ChestItemsHoverDisplay/CDEV.ChestItemsHoverDisplay.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("CDEV.ChestItemsHoverDisplay")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.3.0")] [assembly: AssemblyInformationalVersion("0.3.3+efb24945142928ac03192750576c1d4fe797e026")] [assembly: AssemblyProduct("CDEV.ChestItemsHoverDisplay")] [assembly: AssemblyTitle("CDEV.ChestItemsHoverDisplay")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.3.0")] [module: UnverifiableCode] [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 CDEV.ChestItemsHoverDisplay { internal class HoverInventoryPanel : MonoBehaviour { private struct SlotView { public GameObject Go; public Image Icon; public TextMeshProUGUI Count; public TextMeshProUGUI Quality; public RectTransform Durability; public Image DurabilityImage; } private struct Style { public TMP_FontAsset TitleFont; public Material TitleMaterial; public TMP_FontAsset CountFont; public Material CountMaterial; public Color CountColor; public TextAlignmentOptions CountAlignment; public TMP_FontAsset QualityFont; public Material QualityMaterial; public Color QualityColor; public TextAlignmentOptions QualityAlignment; public Sprite DurabilitySprite; public Color DurabilityColor; } private const float PadX = 12f; private const float PadY = 16f; private const float TitleSize = 16f; private const float CellSpacing = 2f; private const int MinCell = 16; private const float HoverTextGap = 6f; private RectTransform _root; private RectTransform _gridRoot; private GridLayoutGroup _grid; private TextMeshProUGUI _title; private List<SlotView> _slots; private readonly List<int> _brokenSlots = new List<int>(8); private Style _style; private HoverSource _source; private string _localizedTitle = string.Empty; private int _gridW; private int _gridH; private int _cell; private int _settingsVersion = -1; private Vector2 _areaSize; private bool _dirty = true; private bool _built; private static readonly string[] s_stackCache = BuildCache("x", 128); private static readonly string[] s_qualityCache = BuildCache(string.Empty, 16); private static string[] BuildCache(string prefix, int n) { string[] array = new string[n + 1]; for (int i = 0; i <= n; i++) { array[i] = prefix + i; } return array; } private void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown _root = (RectTransform)((Component)this).transform; _slots = new List<SlotView>(32); Build(); } private void OnDestroy() { _source?.Unbind(); _source = null; } private void Build() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Expected O, but got Unknown //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown //IL_0222: 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_0240: Expected O, but got Unknown if (!_built) { _built = true; _style = FindStyle(); _root.anchorMin = new Vector2(0.5f, 0.5f); _root.anchorMax = new Vector2(0.5f, 0.5f); Image val = ((Component)this).gameObject.AddComponent<Image>(); ((Graphic)val).color = new Color(0f, 0f, 0f, 0.66f); ((Graphic)val).raycastTarget = false; ContentSizeFitter val2 = ((Component)this).gameObject.AddComponent<ContentSizeFitter>(); val2.horizontalFit = (FitMode)2; val2.verticalFit = (FitMode)2; VerticalLayoutGroup val3 = ((Component)this).gameObject.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)val3).padding = new RectOffset(6, 6, 5, 6); ((HorizontalOrVerticalLayoutGroup)val3).spacing = 5f; ((LayoutGroup)val3).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)val3).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)val3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false; _title = NewText("Title", ((Component)this).transform, _style.TitleFont, _style.TitleMaterial); GameObject gameObject = ((Component)_title).gameObject; ((TMP_Text)_title).fontSize = 16f; ((TMP_Text)_title).fontStyle = (FontStyles)1; ((Graphic)_title).color = Color.white; ((TMP_Text)_title).alignment = (TextAlignmentOptions)4097; ((TMP_Text)_title).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)_title).overflowMode = (TextOverflowModes)0; ((TMP_Text)_title).richText = true; ((Graphic)_title).raycastTarget = false; LayoutElement val4 = gameObject.AddComponent<LayoutElement>(); val4.minHeight = 16f; val4.preferredHeight = 16f; GameObject val5 = new GameObject("Grid", new Type[1] { typeof(RectTransform) }); val5.transform.SetParent(((Component)this).transform, false); _gridRoot = (RectTransform)val5.transform; ContentSizeFitter val6 = val5.AddComponent<ContentSizeFitter>(); val6.horizontalFit = (FitMode)2; val6.verticalFit = (FitMode)2; _grid = val5.AddComponent<GridLayoutGroup>(); _grid.spacing = new Vector2(2f, 2f); ((LayoutGroup)_grid).padding = new RectOffset(0, 0, 0, 0); _grid.startCorner = (Corner)0; _grid.startAxis = (Axis)0; ((LayoutGroup)_grid).childAlignment = (TextAnchor)0; _grid.constraint = (Constraint)1; _grid.constraintCount = 1; ((Component)this).gameObject.SetActive(false); } } private static Style FindStyle() { //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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0058: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: 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_0197: 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_01e6: Unknown result type (might be due to invalid IL or missing references) Style result = new Style { CountColor = Color.white, CountAlignment = (TextAlignmentOptions)1028, QualityColor = new Color(1f, 0.85f, 0.4f), QualityAlignment = (TextAlignmentOptions)260, DurabilityColor = new Color(0.4f, 0.85f, 0.3f) }; TMP_Text val = (TMP_Text)(object)(((Object)(object)Hud.instance != (Object)null) ? Hud.instance.m_hoverName : null); if ((Object)(object)val != (Object)null) { result.TitleFont = val.font; result.TitleMaterial = val.fontSharedMaterial; } InventoryGrid val2 = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_playerGrid : null); InventoryElement val3 = (((Object)(object)val2 != (Object)null && (Object)(object)val2.m_elementPrefab != (Object)null) ? val2.m_elementPrefab.GetComponent<InventoryElement>() : null); if ((Object)(object)val3 != (Object)null) { if ((Object)(object)val3.m_amount != (Object)null) { result.CountFont = val3.m_amount.font; result.CountMaterial = val3.m_amount.fontSharedMaterial; result.CountColor = ((Graphic)val3.m_amount).color; result.CountAlignment = val3.m_amount.alignment; } if ((Object)(object)val3.m_quality != (Object)null) { result.QualityFont = val3.m_quality.font; result.QualityMaterial = val3.m_quality.fontSharedMaterial; result.QualityColor = ((Graphic)val3.m_quality).color; result.QualityAlignment = val3.m_quality.alignment; } if ((Object)(object)val3.m_durability != (Object)null && (Object)(object)val3.m_durability.m_barImage != (Object)null) { result.DurabilitySprite = val3.m_durability.m_barImage.sprite; result.DurabilityColor = ((Graphic)val3.m_durability.m_barImage).color; } } if ((Object)(object)result.CountFont == (Object)null) { result.CountFont = result.TitleFont; result.CountMaterial = result.TitleMaterial; } if ((Object)(object)result.QualityFont == (Object)null) { result.QualityFont = result.CountFont; result.QualityMaterial = result.CountMaterial; } return result; } private static void ApplyFont(TMP_Text text, TMP_FontAsset font, Material material) { if (!((Object)(object)font == (Object)null)) { text.font = font; if ((Object)(object)material != (Object)null) { text.fontSharedMaterial = material; } } } private SlotView CreateSlot(int idx) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Expected O, but got Unknown //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Expected O, but got Unknown //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Slot" + idx, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)_gridRoot, false); Image val2 = val.AddComponent<Image>(); ((Graphic)val2).color = new Color(1f, 1f, 1f, 0.08f); ((Graphic)val2).raycastTarget = false; GameObject val3 = new GameObject("Icon", new Type[1] { typeof(RectTransform) }); val3.transform.SetParent(val.transform, false); Stretch((RectTransform)val3.transform, 0f); Image val4 = val3.AddComponent<Image>(); ((Graphic)val4).raycastTarget = false; val4.preserveAspect = true; TextMeshProUGUI val5 = NewText("Count", val.transform, _style.CountFont, _style.CountMaterial); Stretch((RectTransform)((TMP_Text)val5).transform, 2f); ((Graphic)val5).color = _style.CountColor; ((TMP_Text)val5).alignment = _style.CountAlignment; SetupCellText(val5); TextMeshProUGUI val6 = NewText("Quality", val.transform, _style.QualityFont, _style.QualityMaterial); Stretch((RectTransform)((TMP_Text)val6).transform, 2f); ((Graphic)val6).color = _style.QualityColor; ((TMP_Text)val6).alignment = _style.QualityAlignment; SetupCellText(val6); GameObject val7 = new GameObject("Durability", new Type[1] { typeof(RectTransform) }); val7.transform.SetParent(val.transform, false); RectTransform val8 = (RectTransform)val7.transform; val8.anchorMin = new Vector2(0.1f, 0.04f); val8.anchorMax = new Vector2(0.9f, 0.1f); val8.offsetMin = Vector2.zero; val8.offsetMax = Vector2.zero; Image val9 = val7.AddComponent<Image>(); val9.sprite = _style.DurabilitySprite; ((Graphic)val9).color = _style.DurabilityColor; ((Graphic)val9).raycastTarget = false; val7.SetActive(false); return new SlotView { Go = val, Icon = val4, Count = val5, Quality = val6, Durability = val8, DurabilityImage = val9 }; } private static void Stretch(RectTransform rt, float inset) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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) rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; rt.offsetMin = new Vector2(inset, 0f); rt.offsetMax = new Vector2(0f - inset, 0f); } private static TextMeshProUGUI NewText(string name, Transform parent, TMP_FontAsset font, Material material) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.SetActive(false); val.transform.SetParent(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); ApplyFont((TMP_Text)(object)val2, font, material); val.SetActive(true); return val2; } private static void SetupCellText(TextMeshProUGUI text) { ((Graphic)text).raycastTarget = false; ((TMP_Text)text).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)text).overflowMode = (TextOverflowModes)0; ((TMP_Text)text).richText = false; ((Behaviour)text).enabled = false; } public void Hide() { if (_built) { if (((Component)this).gameObject.activeSelf) { ((Component)this).gameObject.SetActive(false); } _source?.Unbind(); _source = null; _dirty = true; } } public void Show(HoverSource source) { //IL_00d9: 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_0110: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) if (!_built) { Build(); } if (source != _source) { _source?.Unbind(); _source = source; _dirty = true; } source.Poll(); bool flag = source.ConsumeTitleDirty(); if (flag) { string text = source.TitleKey ?? string.Empty; _localizedTitle = ((Localization.instance != null) ? Localization.instance.Localize(text) : text); } bool flag2 = source.ConsumeDirty(); if (flag2) { _dirty = true; } if (_settingsVersion != Plugin.SettingsVersion) { _settingsVersion = Plugin.SettingsVersion; ApplyPosition(); flag = true; _dirty = true; } if (flag || flag2) { UpdateTitle(); } if (Plugin.CfgPosition.Value == PanelPosition.UnderHoverText) { FollowHoverText(); } int width = source.Width; int height = source.Height; Vector2 val = AreaSize(); if (width != _gridW || height != _gridH || val != _areaSize) { _gridW = width; _gridH = height; _areaSize = val; _grid.constraintCount = width; _dirty = true; } bool flag3 = false; if (_dirty) { ApplyCellSize(); Rebuild(); flag3 = true; } if (Plugin.CfgHideWhenEmpty.Value && source.ItemCount == 0) { if (((Component)this).gameObject.activeSelf) { ((Component)this).gameObject.SetActive(false); } return; } if (!((Component)this).gameObject.activeSelf) { ((Component)this).gameObject.SetActive(true); } if (_brokenSlots.Count > 0) { Color color = (Color)((Mathf.Sin(Time.time * 10f) > 0f) ? Color.red : new Color(0f, 0f, 0f, 0f)); for (int i = 0; i < _brokenSlots.Count; i++) { ((Graphic)_slots[_brokenSlots[i]].DurabilityImage).color = color; } } if (flag3) { LayoutRebuilder.ForceRebuildLayoutImmediate(_root); } } private void UpdateTitle() { if (!((Object)(object)_title == (Object)null) && _source != null) { if (Plugin.CfgShowFillCount.Value && _source.Capacity > 0) { ((TMP_Text)_title).text = _localizedTitle + " <color=#B4B4B4>" + _source.ItemCount + "/" + _source.Capacity + "</color>"; } else { ((TMP_Text)_title).text = _localizedTitle; } } } private void ApplyPosition() { //IL_003d: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) float num = Plugin.CfgDistance.Value; switch (Plugin.CfgPosition.Value) { case PanelPosition.Above: _root.pivot = new Vector2(0.5f, 0f); _root.anchoredPosition = new Vector2(0f, num); break; case PanelPosition.Left: _root.pivot = new Vector2(1f, 0.5f); _root.anchoredPosition = new Vector2(0f - num, 0f); break; case PanelPosition.UnderHoverText: _root.pivot = new Vector2(0f, 1f); break; default: _root.pivot = new Vector2(0.5f, 1f); _root.anchoredPosition = new Vector2(0f, 0f - num); break; } } private void FollowHoverText() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0063: 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_0089: 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) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) TMP_Text val = (TMP_Text)(object)(((Object)(object)Hud.instance != (Object)null) ? Hud.instance.m_hoverName : null); Transform parent = ((Transform)_root).parent; RectTransform val2 = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || !((Behaviour)val).isActiveAndEnabled) { return; } Bounds textBounds = val.textBounds; if (!(((Bounds)(ref textBounds)).size.x <= 0f) && !(((Bounds)(ref textBounds)).size.y <= 0f)) { Vector3 val3 = ((Transform)val.rectTransform).TransformPoint(new Vector3(((Bounds)(ref textBounds)).min.x, ((Bounds)(ref textBounds)).min.y, 0f)); Vector3 val4 = ((Transform)val2).InverseTransformPoint(val3); Vector2 val5 = default(Vector2); ((Vector2)(ref val5))..ctor(Mathf.Round(val4.x), Mathf.Round(val4.y - 6f)); if (_root.anchoredPosition != val5) { _root.anchoredPosition = val5; } } } private Vector2 AreaSize() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)(((Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_rootObject != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); ? val2; if (!((Object)(object)val != (Object)null)) { val2 = new Vector2((float)Screen.width, (float)Screen.height); } else { Rect rect = val.rect; val2 = ((Rect)(ref rect)).size; } Vector2 val3 = (Vector2)val2; return val3 * ((float)Plugin.CfgMaxScreenPercent.Value / 100f); } private void ApplyCellSize() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(1, _gridW); int num2 = Mathf.Max(1, _gridH); float num3 = (_areaSize.x - 12f - 2f * (float)(num - 1)) / (float)num; float num4 = (_areaSize.y - 16f - 16f - 2f * (float)(num2 - 1)) / (float)num2; int num5 = Mathf.Min(Plugin.CfgCellSize.Value, Mathf.FloorToInt(Mathf.Min(num3, num4))); num5 = Mathf.Max(16, num5); if (num5 != _cell) { _cell = num5; _grid.cellSize = new Vector2((float)num5, (float)num5); float fontSize = Mathf.Max(9f, Mathf.Round((float)num5 * 0.35f)); for (int i = 0; i < _slots.Count; i++) { ((TMP_Text)_slots[i].Count).fontSize = fontSize; ((TMP_Text)_slots[i].Quality).fontSize = fontSize; } } } private void Rebuild() { //IL_0296: 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) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) _dirty = false; _brokenSlots.Clear(); int num = _gridW * _gridH; float fontSize = Mathf.Max(9f, Mathf.Round((float)_cell * 0.35f)); while (_slots.Count < num) { SlotView item = CreateSlot(_slots.Count); ((TMP_Text)item.Count).fontSize = fontSize; ((TMP_Text)item.Quality).fontSize = fontSize; _slots.Add(item); } bool value = Plugin.CfgShowDurability.Value; bool value2 = Plugin.CfgShowQuality.Value; for (int i = 0; i < _slots.Count; i++) { SlotView slotView = _slots[i]; if (i >= num) { if (slotView.Go.activeSelf) { slotView.Go.SetActive(false); } continue; } ItemData itemAt = _source.GetItemAt(i % _gridW, i / _gridW); Sprite val = PickIcon(itemAt); slotView.Icon.sprite = val; ((Behaviour)slotView.Icon).enabled = (Object)(object)val != (Object)null; int num2 = itemAt?.m_stack ?? 0; bool flag = num2 > 1 || (itemAt != null && itemAt.m_shared != null && itemAt.m_shared.m_maxStackSize > 1); if (flag) { ((TMP_Text)slotView.Count).text = ((num2 >= 0 && num2 < s_stackCache.Length) ? s_stackCache[num2] : ("x" + num2)); } ((Behaviour)slotView.Count).enabled = flag; bool flag2 = value2 && itemAt != null && itemAt.m_shared != null && itemAt.m_shared.m_maxQuality > 1; if (flag2) { int quality = itemAt.m_quality; ((TMP_Text)slotView.Quality).text = ((quality >= 0 && quality < s_qualityCache.Length) ? s_qualityCache[quality] : quality.ToString()); } ((Behaviour)slotView.Quality).enabled = flag2; bool flag3 = value && itemAt != null && itemAt.m_shared != null && itemAt.m_shared.m_useDurability && itemAt.m_durability < itemAt.GetMaxDurability(); if (flag3) { bool flag4 = itemAt.m_durability <= 0f; float num3 = (flag4 ? 1f : Mathf.Clamp01(itemAt.GetDurabilityPercentage())); slotView.Durability.anchorMax = new Vector2(0.1f + 0.8f * num3, slotView.Durability.anchorMax.y); ((Graphic)slotView.DurabilityImage).color = _style.DurabilityColor; if (flag4) { _brokenSlots.Add(i); } } if (((Component)slotView.Durability).gameObject.activeSelf != flag3) { ((Component)slotView.Durability).gameObject.SetActive(flag3); } if (!slotView.Go.activeSelf) { slotView.Go.SetActive(true); } } } private static Sprite PickIcon(ItemData it) { if (it == null || it.m_shared == null) { return null; } Sprite[] icons = it.m_shared.m_icons; if (icons == null || icons.Length == 0) { return null; } int num = it.m_variant; if (num < 0) { num = 0; } if (num >= icons.Length) { num = icons.Length - 1; } return icons[num]; } } internal abstract class HoverSource { private bool _dirty = true; private bool _titleDirty = true; public abstract string TitleKey { get; } public abstract int Width { get; } public abstract int Height { get; } public abstract int ItemCount { get; } public abstract int Capacity { get; } public abstract ItemData GetItemAt(int x, int y); public virtual void Poll() { } public abstract void Unbind(); protected void MarkDirty(bool titleToo) { _dirty = true; _titleDirty |= titleToo; } public bool ConsumeDirty() { bool dirty = _dirty; _dirty = false; return dirty; } public bool ConsumeTitleDirty() { bool titleDirty = _titleDirty; _titleDirty = false; return titleDirty; } } internal sealed class ContainerSource : HoverSource { private Container _container; private Inventory _inventory; private string _titleKey; public Container Target => _container; public override string TitleKey => _titleKey; public override int Width { get { if (_inventory == null) { return 1; } return Mathf.Max(1, _inventory.GetWidth()); } } public override int Height { get { if (_inventory == null) { return 1; } return Mathf.Max(1, _inventory.GetHeight()); } } public override int ItemCount { get { if (_inventory == null) { return 0; } return _inventory.NrOfItems(); } } public override int Capacity { get { if (_inventory == null) { return 0; } return _inventory.GetWidth() * _inventory.GetHeight(); } } public bool Bind(Container container, string titleKey) { if ((Object)(object)container != (Object)(object)_container) { Unbind(); _container = container; _inventory = container.GetInventory(); if (_inventory != null) { Inventory inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(OnInventoryChanged)); } MarkDirty(titleToo: true); } if (_titleKey != titleKey) { _titleKey = titleKey; MarkDirty(titleToo: true); } return _inventory != null; } public override ItemData GetItemAt(int x, int y) { Inventory inventory = _inventory; if (inventory == null) { return null; } return inventory.GetItemAt(x, y); } public override void Unbind() { if (_inventory != null) { Inventory inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Remove(inventory.m_onChanged, new Action(OnInventoryChanged)); } _inventory = null; _container = null; MarkDirty(titleToo: true); } private void OnInventoryChanged() { MarkDirty(titleToo: false); } } internal sealed class ArmorStandSource : HoverSource { private readonly List<ItemData> _items = new List<ItemData>(16); private readonly List<int> _order = new List<int>(16); private ArmorStand _stand; private ZNetView _nview; private uint _revision; public ArmorStand Target => _stand; public override string TitleKey { get { if (!((Object)(object)_stand != (Object)null)) { return string.Empty; } return _stand.m_name; } } public override int Width => Mathf.Max(1, _items.Count); public override int Height => 1; public override int ItemCount => _items.Count; public override int Capacity { get { if (!((Object)(object)_stand != (Object)null)) { return 0; } return _stand.m_slots.Count; } } public bool Bind(ArmorStand stand) { if ((Object)(object)stand != (Object)(object)_stand) { Unbind(); _stand = stand; _nview = (((Object)(object)stand.m_netViewOverride != (Object)null) ? stand.m_netViewOverride : ((Component)stand).GetComponent<ZNetView>()); MarkDirty(titleToo: true); } if ((Object)(object)_nview != (Object)null) { return _nview.IsValid(); } return false; } public override void Poll() { if (!((Object)(object)_nview == (Object)null) && _nview.IsValid()) { uint dataRevision = _nview.GetZDO().DataRevision; if (dataRevision != _revision) { _revision = dataRevision; Reload(); MarkDirty(titleToo: false); } } } public override ItemData GetItemAt(int x, int y) { if (y != 0 || x < 0 || x >= _items.Count) { return null; } return _items[x]; } public override void Unbind() { _stand = null; _nview = null; _revision = uint.MaxValue; _items.Clear(); _order.Clear(); MarkDirty(titleToo: true); } private void Reload() { _items.Clear(); _order.Clear(); ZDO zDO = _nview.GetZDO(); int count = _stand.m_slots.Count; for (int i = 0; i < count; i++) { if (_stand.GetAttachedItem(i) != 0) { InsertByPriority(i); } } if ((Object)(object)ObjectDB.instance == (Object)null) { return; } for (int j = 0; j < _order.Count; j++) { int num = _order[j]; GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(_stand.GetAttachedItem(num)); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if (!((Object)(object)val == (Object)null)) { ItemData val2 = val.m_itemData.Clone(); val2.m_dropPrefab = itemPrefab; ItemDrop.LoadFromZDO(val2, zDO, num); _items.Add(val2); } } } private void InsertByPriority(int slot) { //IL_0011: 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) int num = Priority(_stand.m_slots[slot].m_slot); int num2 = _order.Count; while (num2 > 0 && Priority(_stand.m_slots[_order[num2 - 1]].m_slot) > num) { num2--; } _order.Insert(num2, slot); } private static int Priority(VisSlot slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected I4, but got Unknown return (int)slot switch { 6 => 0, 4 => 1, 5 => 2, 7 => 3, 8 => 4, 1 => 5, 0 => 6, 3 => 7, 2 => 8, _ => 9, }; } } internal enum PanelPosition { Below, Above, Left, UnderHoverText } [BepInPlugin("cdev.valheim.chestitemshoverdisplay", "CDEV.ChestItemsHoverDisplay", "0.3.3")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "cdev.valheim.chestitemshoverdisplay"; public const string PluginName = "CDEV.ChestItemsHoverDisplay"; public const string PluginVersion = "0.3.3"; internal static ManualLogSource Log; internal static Plugin Instance; internal static HoverInventoryPanel Panel; internal static ConfigEntry<bool> CfgEnabled; internal static ConfigEntry<int> CfgCellSize; internal static ConfigEntry<int> CfgMaxScreenPercent; internal static ConfigEntry<bool> CfgHideWhenEmpty; internal static ConfigEntry<bool> CfgRespectPrivateChests; internal static ConfigEntry<KeyboardShortcut> CfgHoldKey; internal static ConfigEntry<PanelPosition> CfgPosition; internal static ConfigEntry<int> CfgDistance; internal static ConfigEntry<bool> CfgShowFillCount; internal static ConfigEntry<bool> CfgShowDurability; internal static ConfigEntry<bool> CfgShowQuality; internal static int SettingsVersion; internal static KeyCode HoldMain; internal static KeyCode[] HoldModifiers = (KeyCode[])(object)new KeyCode[0]; private Harmony _harmony; private void Awake() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_00e9: 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_014e: Expected O, but got Unknown //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "Enabled", true, "Master toggle for the hover inventory panel."); CfgCellSize = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "CellSize", 40, new ConfigDescription("Pixel size of each grid cell. Big chests use smaller cells to stay within MaxScreenPercent.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(24, 96), Array.Empty<object>())); CfgMaxScreenPercent = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "MaxScreenPercent", 50, new ConfigDescription("The panel never gets wider or taller than this share of the screen; cells shrink to fit.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(20, 100), Array.Empty<object>())); CfgHideWhenEmpty = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "HideWhenEmpty", true, "Hide the panel when the hovered container is empty."); CfgRespectPrivateChests = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "RespectPrivateChests", true, "Hide preview for private chests the local player cannot access, or chests inside wards the local player is not permitted in."); CfgHoldKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Display", "HoldKeyToShow", KeyboardShortcut.Empty, "Optional key (or key combination) that must be held to show the panel. Empty / None = always show while hovering."); CfgPosition = ((BaseUnityPlugin)this).Config.Bind<PanelPosition>("Display", "Position", PanelPosition.Below, "Where the panel sits: Below / Above / Left of the crosshair (Distance away), or UnderHoverText - right under the object's name and key hints, which the game draws right of the crosshair."); CfgDistance = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "Distance", 80, new ConfigDescription("Pixels between the crosshair and the near edge of the panel (Below, Above, Left).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 600), Array.Empty<object>())); CfgShowFillCount = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowFillCount", true, "Show how many slots are used next to the name, e.g. 12/32."); CfgShowDurability = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowDurability", true, "Show the durability bar of worn items, as in the inventory."); CfgShowQuality = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowQuality", true, "Show the quality level of items that can be upgraded, as in the inventory."); MigrateVerticalOffset(); CacheHoldKey(); CfgHoldKey.SettingChanged += delegate { CacheHoldKey(); }; ((BaseUnityPlugin)this).Config.SettingChanged += delegate { SettingsVersion++; }; _harmony = new Harmony("cdev.valheim.chestitemshoverdisplay"); _harmony.PatchAll(typeof(Plugin).Assembly); } private void MigrateVerticalOffset() { ConfigEntry<int> val = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "VerticalOffset", -80, "Replaced by Position and Distance."); int value = val.Value; ((BaseUnityPlugin)this).Config.Remove(((ConfigEntryBase)val).Definition); if (value != -80) { CfgPosition.Value = ((value > 0) ? PanelPosition.Above : PanelPosition.Below); CfgDistance.Value = Mathf.Clamp(Mathf.Abs(value), 0, 600); } ((BaseUnityPlugin)this).Config.Save(); } private static void CacheHoldKey() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = CfgHoldKey.Value; HoldMain = ((KeyboardShortcut)(ref value)).MainKey; HoldModifiers = ((KeyboardShortcut)(ref value)).Modifiers.ToArray(); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)Panel != (Object)null) { Object.Destroy((Object)(object)((Component)((Component)Panel).transform.parent).gameObject); } Panel = null; } internal static HoverInventoryPanel GetOrCreatePanel() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown if ((Object)(object)Panel != (Object)null) { return Panel; } if ((Object)(object)Hud.instance == (Object)null || (Object)(object)Hud.instance.m_rootObject == (Object)null) { return null; } GameObject val = new GameObject("CDEV_HoverInventoryPanel", new Type[1] { typeof(RectTransform) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent(Hud.instance.m_rootObject.transform, false); ((Transform)val2).SetAsFirstSibling(); val2.anchorMin = new Vector2(0.5f, 0.5f); val2.anchorMax = new Vector2(0.5f, 0.5f); val2.pivot = new Vector2(0.5f, 0.5f); val2.sizeDelta = Vector2.zero; val2.anchoredPosition = Vector2.zero; GameObject val3 = new GameObject("Panel", new Type[1] { typeof(RectTransform) }); val3.transform.SetParent((Transform)(object)val2, false); Panel = val3.AddComponent<HoverInventoryPanel>(); return Panel; } } [HarmonyPatch(typeof(Hud), "UpdateCrosshair")] internal static class HudUpdateCrosshairPatch { private static readonly Func<Container, long, bool> s_checkAccess = AccessTools.MethodDelegate<Func<Container, long, bool>>(AccessTools.Method(typeof(Container), "CheckAccess", new Type[1] { typeof(long) }, (Type[])null), (object)null, true); private static readonly FieldRef<Container, ZNetView> s_containerNView = AccessTools.FieldRefAccess<Container, ZNetView>("m_nview"); private const float AccessRecheckSeconds = 0.5f; private static readonly ContainerSource s_containerSource = new ContainerSource(); private static readonly ArmorStandSource s_standSource = new ArmorStandSource(); private static GameObject s_lastHover; private static Container s_hoverContainer; private static Vagon s_hoverVagon; private static ArmorStand s_hoverStand; private static Object s_accessTarget; private static bool s_accessOk; private static float s_accessRecheckAt; private static bool s_errorLogged; private static void Postfix(Player player) { try { Run(player); } catch (Exception arg) { if (!s_errorLogged) { s_errorLogged = true; Plugin.Log.LogError((object)$"The hover preview failed and is hidden (further errors are not logged): {arg}"); } try { if ((Object)(object)Plugin.Panel != (Object)null) { Plugin.Panel.Hide(); } } catch (Exception) { } } } private static void Run(Player player) { HoverSource hoverSource = (((Object)(object)player != (Object)null && Plugin.CfgEnabled.Value && !IsWindowOpen() && HoldKeyAllows()) ? Pick(player) : null); if (hoverSource == null) { if ((Object)(object)Plugin.Panel != (Object)null) { Plugin.Panel.Hide(); } return; } HoverInventoryPanel orCreatePanel = Plugin.GetOrCreatePanel(); if ((Object)(object)orCreatePanel != (Object)null) { orCreatePanel.Show(hoverSource); } } private static HoverSource Pick(Player player) { GameObject hoverObject = ((Humanoid)player).GetHoverObject(); if ((Object)(object)hoverObject == (Object)null) { return null; } Resolve(hoverObject); if ((Object)(object)s_hoverContainer != (Object)null) { ZNetView val = s_containerNView.Invoke(s_hoverContainer); if ((Object)(object)val == (Object)null || !val.IsValid() || !HasAccess((Component)(object)s_hoverContainer, s_hoverContainer, player)) { return null; } string titleKey = (((Object)(object)s_hoverVagon != (Object)null) ? s_hoverVagon.m_name : s_hoverContainer.m_name); if (!s_containerSource.Bind(s_hoverContainer, titleKey)) { return null; } return s_containerSource; } if ((Object)(object)s_hoverStand != (Object)null) { if (!HasAccess((Component)(object)s_hoverStand, null, player)) { return null; } if (!s_standSource.Bind(s_hoverStand)) { return null; } return s_standSource; } return null; } private static bool HoldKeyAllows() { //IL_0000: 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) if ((int)Plugin.HoldMain == 0) { return true; } if (ZInput.instance == null || !Held(Plugin.HoldMain)) { return false; } KeyCode[] holdModifiers = Plugin.HoldModifiers; for (int i = 0; i < holdModifiers.Length; i++) { if (!Held(holdModifiers[i])) { return false; } } return true; } private static bool Held(KeyCode code) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0017: 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: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) KeyCode val = ForZInput(code); Key val2 = default(Key); if (((int)val >= 323 && (int)val <= 329) || (ZInput.TryKeyCodeToKey(val, ref val2) && (int)val2 > 0)) { return ZInput.GetKey(val, false); } return false; } private static KeyCode ForZInput(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) if ((int)key != 326) { if ((int)key != 327) { return key; } return (KeyCode)326; } return (KeyCode)327; } private static bool IsWindowOpen() { if (!InventoryGui.IsVisible() && !Minimap.IsOpen() && !Menu.IsVisible() && !StoreGui.IsVisible() && !TextInput.IsVisible() && !Console.IsVisible() && !UnifiedPopup.IsVisible() && !Hud.IsPieceSelectionVisible() && !Hud.InRadial() && !PlayerCustomizaton.IsBarberGuiVisible() && !GameCamera.InFreeFly()) { if ((Object)(object)TextViewer.instance != (Object)null) { return TextViewer.instance.IsVisible(); } return false; } return true; } private static void Resolve(GameObject hovering) { if (!((Object)(object)hovering == (Object)(object)s_lastHover)) { s_lastHover = hovering; s_hoverVagon = hovering.GetComponentInParent<Vagon>(); s_hoverContainer = hovering.GetComponentInParent<Container>(); if ((Object)(object)s_hoverContainer == (Object)null && (Object)(object)s_hoverVagon != (Object)null) { s_hoverContainer = s_hoverVagon.m_container; } s_hoverStand = (((Object)(object)s_hoverContainer == (Object)null) ? hovering.GetComponentInParent<ArmorStand>() : null); } } private static bool HasAccess(Component target, Container container, Player player) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.CfgRespectPrivateChests.Value) { return true; } float unscaledTime = Time.unscaledTime; if ((Object)(object)target == s_accessTarget && unscaledTime < s_accessRecheckAt) { return s_accessOk; } s_accessTarget = (Object)(object)target; s_accessRecheckAt = unscaledTime + 0.5f; s_accessOk = ((Object)(object)container == (Object)null || s_checkAccess == null || s_checkAccess(container, player.GetPlayerID())) && PrivateArea.CheckAccess(target.transform.position, 0f, false, false); return s_accessOk; } } internal static class BuildInfo { public const string Name = "CDEV.ChestItemsHoverDisplay"; public const string Guid = "cdev.valheim.chestitemshoverdisplay"; public const string Version = "0.3.3"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }