CrabUI
Loading...
Searching...
No Matches
CUIAttachedItems.cs
1using System;
2using System.Reflection;
3using System.Runtime.CompilerServices;
4using System.Collections.Generic;
5using System.Collections.Immutable;
6using System.Linq;
7
8using Barotrauma;
9using HarmonyLib;
10using Microsoft.Xna.Framework;
11using System.IO;
12
13namespace CrabUI
14{
15
16 public class AttachedItems
17 {
18 public static void InitStatic()
19 {
20 CUI.OnDispose += () =>
21 {
22 All.Clear();
23 PrefabMapping.Clear();
24 PrevSelected.Clear();
25 Selected.Clear();
26 };
27 }
28
29 public static Dictionary<ushort, AttachedItemHandle> All = new();
30 public static Dictionary<int, Type> PrefabMapping = new();
31
32 public static HashSet<AttachedItemHandle> PrevSelected = new();
33 public static HashSet<AttachedItemHandle> Selected = new();
34
35 public static void UpdateAll()
36 {
37 Selected.Clear();
38
39 if (Character.Controlled is { } controlled)
40 {
41 if (controlled.SelectedItem != null && controlled.CanInteractWith(controlled.SelectedItem))
42 {
43 if (All.ContainsKey(controlled.SelectedItem.ID))
44 {
45 Selected.Add(All[controlled.SelectedItem.ID]);
46 }
47
48 UpdateItem(controlled.SelectedItem);
49 }
50 if (controlled.Inventory != null)
51 {
52 foreach (Item item in controlled.Inventory.AllItems)
53 {
54 if (controlled.HasEquippedItem(item))
55 {
56 if (All.ContainsKey(item.ID)) Selected.Add(All[item.ID]);
57 UpdateItem(item);
58 }
59 }
60 }
61 }
62
63 foreach (var handle in Selected.Except(PrevSelected)) handle.Select();
64 foreach (var handle in PrevSelected.Except(Selected)) handle.Deselect();
65 (PrevSelected, Selected) = (Selected, PrevSelected);
66 }
67
68 public static void UpdateItem(Item item)
69 {
70 if (All.ContainsKey(item.ID))
71 {
72 All[item.ID].Update();
73 }
74 }
75
76 public static void ShakeTheRefs()
77 {
78 List<ushort> keys = new List<ushort>(All.Keys);
79 foreach (ushort key in keys)
80 {
81 if (All[key].IsDead) All.Remove(key);
82 }
83 }
84
85 public static void Connect(Item item, CUIComponent component, Action<Item, CUIComponent> callback = null)
86 {
87 if (item == null || component == null) return;
88
89 AttachedItemHandle handle = component.AttachedItemHandle;
90 handle ??= new AttachedItemHandle(item, component);
91 if (callback != null) handle.OnUpdate += callback;
92 component.AttachedItemHandle = handle;
93
94 //ShakeTheRefs();
95
96 All[item.ID] = handle;
97 }
98
99 public static void ConnectPrefabs(ItemPrefab prefab, Type CUIType) => ConnectPrefabs(prefab.Identifier, CUIType);
100 public static void ConnectPrefabs(string prefabName, Type CUIType) => ConnectPrefabs(new Identifier(prefabName), CUIType);
101 public static void ConnectPrefabs(Identifier prefabId, Type CUIType)
102 {
103 if (CUIType == null) return;
104
105 PrefabMapping[prefabId.HashCode] = CUIType;
106
107 foreach (Item item in Item.ItemList)
108 {
109 ConnectIfMapped(item);
110 }
111 }
112
113 internal static void ConnectIfMapped(Item item)
114 {
115 Type CUIType = PrefabMapping.GetValueOrDefault(item.Prefab.Identifier.HashCode);
116 if (item == null || CUIType == null) return;
117
118 CUIComponent component = (CUIComponent)Activator.CreateInstance(CUIType);
119
120 AttachedItemHandle handle = component.AttachedItemHandle;
121 handle ??= new AttachedItemHandle(item, component);
122 component.AttachedItemHandle = handle;
123
124 All[item.ID] = handle;
125 }
126 }
127
128 /// <summary>
129 /// Link between Item and CUIComponent
130 /// </summary>
132 {
133 private WeakReference<Item> Reference;
134 public CUIComponent Component { get; set; }
135 public Item Item
136 {
137 get
138 {
139 if (Reference == null) return null;
140 if (Reference.TryGetTarget(out Item target)) return target;
141 else return null;
142 }
143 set => Reference = new WeakReference<Item>(value);
144 }
145 public bool IsDead => Component == null;
146 /// <summary>
147 /// Called on Item.UpdateHud
148 /// </summary>
149 public event Action<Item, CUIComponent> OnUpdate;
150 /// <summary>
151 /// Called when item hud is opened
152 /// </summary>
153 public event Action<Item, CUIComponent> OnSelect;
154 /// <summary>
155 /// Called when item hud is closed
156 /// </summary>
157 public event Action<Item, CUIComponent> OnDeselect;
158
159
160 public Action<Item, CUIComponent> AddOnUpdate { set => OnUpdate += value; }
161 public Action<Item, CUIComponent> AddOnSelect { set => OnSelect += value; }
162 public Action<Item, CUIComponent> AddOnDeselect { set => OnDeselect += value; }
163
164 internal void Update() => OnUpdate?.Invoke(Item, Component);
165 internal void Select() => OnSelect?.Invoke(Item, Component);
166 internal void Deselect() => OnDeselect?.Invoke(Item, Component);
167 public AttachedItemHandle() { }
168 public AttachedItemHandle(Item item, CUIComponent component)
169 {
170 this.Item = item;
171 Component = component;
172 }
173 }
174}
Link between Item and CUIComponent.
Action< Item, CUIComponent > OnUpdate
Called on Item.UpdateHud.
Action< Item, CUIComponent > OnDeselect
Called when item hud is closed.
Action< Item, CUIComponent > OnSelect
Called when item hud is opened.
Base class for all components.