2 using System.Collections.Generic;
14 using Microsoft.Xna.Framework;
16 using Terraria.GameContent.UI.Elements;
20 namespace Loot.UI.Tabs.CraftingTab
22 internal class CraftingComponentSelector<T> : GuiPanel where T :
ModItem 24 public virtual string NotFoundString() =>
"No components found in inventory";
25 public virtual int ComponentsPerPage() => 5;
27 private readonly List<UIElement> _components =
new List<UIElement>();
28 private readonly GuiArrowButton _arrowLeft;
29 private readonly GuiArrowButton _arrowRight;
30 private GuiItemButton _lastSelected;
32 internal List<CraftingComponentLink> ComponentLinks =
new List<CraftingComponentLink>();
33 internal Func<Item, IEnumerable<CraftingComponentLink>> FindComponents;
34 internal Func<CraftingComponentLink, Item, bool> VerifyComponent;
35 internal Func<CraftingComponentLink, bool> OnComponentClick;
37 private int _maxOffset;
38 private int _currentOffset;
40 public CraftingComponentSelector()
42 _arrowLeft =
new GuiArrowButton(GuiArrowButton.ArrowDirection.LEFT) { HoverText =
"Previous" };
43 _arrowRight =
new GuiArrowButton(GuiArrowButton.ArrowDirection.RIGHT) { HoverText =
"Next" };
44 OnComponentClick += _OnComponentClick;
45 FindComponents += _FindComponents;
46 VerifyComponent += _VerifyComponent;
49 public override void OnInitialize()
52 _arrowLeft.Activate();
53 _arrowLeft.Left.Set(-_arrowLeft.Width.Pixels, 0);
54 _arrowLeft.WhenClicked += delegate (UIMouseEvent evt, UIElement element, GuiArrowButton btn)
57 btn.CanBeClicked = _maxOffset > 0 && _currentOffset > 0;
58 _arrowRight.CanBeClicked = _maxOffset > 0 && _currentOffset < _maxOffset;
59 CalculateAvailableComponents();
63 _arrowRight.Activate();
64 _arrowRight.Left.Set(Width.Pixels, 0);
65 _arrowRight.WhenClicked += delegate (UIMouseEvent evt, UIElement element, GuiArrowButton btn)
68 _arrowLeft.CanBeClicked = _maxOffset > 0 && _currentOffset > 0;
69 btn.CanBeClicked = _maxOffset > 0 && _currentOffset < _maxOffset;
70 CalculateAvailableComponents();
78 private bool _OnComponentClick(CraftingComponentLink link)
81 CalculateAvailableComponents();
82 return link?.Component.modItem is
MagicalCube && link.Component.stack > 0;
85 private bool _VerifyComponent(CraftingComponentLink link, Item item)
88 if (!(link.Component.modItem is T))
93 var component = link.Component.modItem;
102 strategy = cube.GetRollingStrategy(item, props);
106 strategy = essence.GetRollingStrategy(item, props);
109 var ctx = GetContext(item);
110 ctx.Strategy = strategy;
112 return preRolledLines?.All(x => x.CanRoll(ctx)) ??
false;
115 private IEnumerable<CraftingComponentLink> _FindComponents(Item item)
117 return Main.LocalPlayer.inventory.GetDistinctModItems<T>()
121 component.item.stack = Main.LocalPlayer.inventory.CountItemStack(component.item.type,
true);
122 return new CraftingComponentLink(component.item, CraftingComponentLink.ComponentSource.Inventory);
126 public bool IsAvailable(
int type)
128 return ComponentLinks.Any(x => x.Component.type == type);
131 public IEnumerable<CraftingComponentLink> GetComponentLinks(
int type)
133 return ComponentLinks.Where(x => x.Component.type == type);
137 public void DeselectPreviousComponent()
139 if (_lastSelected != null)
141 _lastSelected.DrawScale = 0.75f;
142 _lastSelected.DynamicScaling =
true;
143 _lastSelected.DrawColor = null;
144 _lastSelected = null;
148 private void SetSelectedComponent(UIElement element)
150 if (element != null && element is GuiItemButton itemButton)
152 DeselectPreviousComponent();
153 itemButton.DrawScale = 0.88f;
154 itemButton.DynamicScaling =
false;
155 itemButton.DrawColor = Color.White;
156 _lastSelected = itemButton;
165 Player = Main.LocalPlayer
169 public void CalculateAvailableComponents(Item item = null)
172 ComponentLinks.Clear();
174 ComponentLinks = FindComponents?.GetInvocationList().SelectMany(x => (IEnumerable<CraftingComponentLink>)x.DynamicInvoke(item)).ToList() ??
new List<CraftingComponentLink>();
176 if (item != null && !item.IsAir)
177 ComponentLinks = ComponentLinks.Where(x => VerifyComponent?.GetInvocationList().Select(y => (
bool)y.DynamicInvoke(x, item)).All(z => z) ??
false)
180 var selection = ComponentLinks.AsEnumerable();
182 var foundCount = selection.Count();
183 _maxOffset = (int)Math.Floor(foundCount / (ComponentsPerPage() + 1f));
184 if (_maxOffset < _currentOffset) _currentOffset = _maxOffset;
186 if (_currentOffset > 0)
188 selection = selection.Skip(_currentOffset * ComponentsPerPage());
191 var items = selection.Take(ComponentsPerPage()).ToList();
193 _arrowLeft.CanBeClicked = _maxOffset > 0 && _currentOffset > 0;
194 _arrowRight.CanBeClicked = _maxOffset > 0 && _currentOffset < _maxOffset;
196 foreach (var link
in items)
198 var name = link.Component.Name;
199 var type = link.Component.type;
200 var stack = link.Component.stack;
202 var button =
new GuiItemButton(GuiButton.ButtonType.StoneOuterBevel, type, stack, hintOnHover: $
"Click to use {name}")
204 Left =
new StyleDimension(15f, 0f),
205 DrawBackground =
false,
208 ShowOnlyHintOnHover =
true 210 button.OnMouseOver += (evt, element) => { Main.PlaySound(12); };
211 button.OnClick += (evt, element) =>
213 if (OnComponentClick?.GetInvocationList().All(x => (
bool)x.DynamicInvoke(link)) ??
false)
215 SetSelectedComponent(element);
219 _components.Add(button);
222 UpdateComponentFrame();
225 private void UpdateComponentFrame()
227 Frame.RemoveAllChildren();
228 if (!_components.Any())
230 Frame.Append(
new UIText(NotFoundString()));
240 var elementSet = _components.ToList();
241 foreach (var element
in elementSet)
245 element.RightOf(elementSet[i - 1]);
247 Frame.Append(element);
Defines a context in which a Modifier might be rolled Which fields are available (not null) depends o...
Defines properties that will be used when an item is being rolled in a IRollingStrategy<T> These can ...
A cube of sealing is used to lock modifiers in place on an item
Defines a magical cube A magical cube is used to change modifiers on an item
static ModifierPool GetPool(ModifierContext context)
virtual List< Modifier > PreRoll(ModifierPool drawPool, ModifierContext modifierContext, RollingStrategyProperties properties)
Defines a rerolling cube that opens the rerolling UI on right click The method M:GetRollingStrategy c...