1 using System.Collections.Generic;
2 using System.Collections.Immutable;
4 using Microsoft.Xna.Framework;
5 using Microsoft.Xna.Framework.Graphics;
16 get {
return activateButton; }
19 private GUIComponent inputInventoryHolder, outputInventoryHolder;
24 private bool pendingState;
40 partial
void InitProjSpecific(XElement _)
49 OnItemLoadedProjSpecific();
57 RelativeSpacing = 0.08f
62 TextAlignment = Alignment.
Center,
63 AutoScaleHorizontal =
true
66 var topFrame =
new GUIFrame(
new RectTransform(
new Vector2(1f, 0.375f), paddedFrame.RectTransform), style:
null);
71 var queueLabelLayout =
new GUILayoutGroup(
new RectTransform(
new Vector2(0.43f, 1f), inputLabelArea.RectTransform), childAnchor:
Anchor.CenterLeft, isHorizontal:
true)
74 RelativeSpacing = 0.05f
76 var queueLabel =
new GUITextBlock(
new RectTransform(Vector2.One, queueLabelLayout.RectTransform), TextManager.Get(
"deconstructor.inputqueue"), font: GUIStyle.SubHeadingFont) { Padding = Vector4.Zero };
77 queueLabel.
RectTransform.
Resize(
new Point((
int) queueLabel.Font.MeasureString(queueLabel.Text).X, queueLabel.RectTransform.Rect.Height));
78 new GUIFrame(
new RectTransform(Vector2.One, queueLabelLayout.RectTransform), style:
"HorizontalLine");
80 var inputLabelLayout =
new GUILayoutGroup(
new RectTransform(
new Vector2(0.57f, 1f), inputLabelArea.RectTransform), childAnchor:
Anchor.CenterLeft, isHorizontal:
true)
83 RelativeSpacing = 0.05f
85 var inputLabel =
new GUITextBlock(
new RectTransform(Vector2.One, inputLabelLayout.RectTransform), TextManager.Get(
"deconstructor.input",
"uilabel.input"), font: GUIStyle.SubHeadingFont) { Padding = Vector4.Zero };
86 inputLabel.
RectTransform.
Resize(
new Point((
int) inputLabel.Font.MeasureString(inputLabel.Text).X, inputLabel.RectTransform.Rect.Height));
87 new GUIFrame(
new RectTransform(Vector2.One, inputLabelLayout.RectTransform), style:
"HorizontalLine");
89 var inputArea =
new GUILayoutGroup(
new RectTransform(
new Vector2(1f, 1f), topFrame.RectTransform,
Anchor.CenterLeft), childAnchor:
Anchor.BottomLeft, isHorizontal:
true) { Stretch =
true, RelativeSpacing = 0.05f };
92 inputInventoryHolder =
new GUIFrame(
new RectTransform(
new Vector2(0.7f, 1f), inputArea.RectTransform), style:
null);
97 activateButton =
new GUIButton(
new RectTransform(
new Vector2(0.95f, 0.8f), buttonContainer.RectTransform), TextManager.Get(
"DeconstructorDeconstruct"), style:
"DeviceButton")
100 TextBlock = { AutoScaleHorizontal =
true },
101 OnClicked = OnActivateButtonClicked
104 TextManager.Get(
"DeconstructorNoPower"), textColor: GUIStyle.Orange, textAlignment: Alignment.Center, color: Color.Black, style:
"OuterGlow", wrap:
true)
106 HoverColor = Color.Black,
107 IgnoreLayoutGroups =
true,
109 CanBeFocused =
false,
110 AutoScaleHorizontal =
true
114 var bottomFrame =
new GUIFrame(
new RectTransform(
new Vector2(1f, 0.375f), paddedFrame.RectTransform), style:
null);
120 RelativeSpacing = 0.05f
122 var outputLabel =
new GUITextBlock(
new RectTransform(
new Vector2(0f, 1.0f), outputLabelArea.RectTransform), TextManager.Get(
"uilabel.output"), font: GUIStyle.SubHeadingFont) { Padding = Vector4.Zero };
123 outputLabel.
RectTransform.
Resize(
new Point((
int) outputLabel.Font.MeasureString(outputLabel.Text).X, outputLabel.RectTransform.Rect.Height));
124 new GUIFrame(
new RectTransform(Vector2.One, outputLabelArea.RectTransform), style:
"HorizontalLine");
126 var outputArea =
new GUILayoutGroup(
new RectTransform(
new Vector2(1f, 1f), bottomFrame.RectTransform,
Anchor.CenterLeft), childAnchor:
Anchor.BottomLeft, isHorizontal:
true) { Stretch =
true, RelativeSpacing = 0.05f };
143 infoArea =
new GUITextBlock(
new RectTransform(
new Vector2(0.95f, 0.95f), infoAreaContainer.RectTransform),
string.Empty, wrap:
true);
151 infoArea.
Text =
string.Empty;
159 activateButton.
Text = TextManager.Get(
"DeconstructorCancel");
160 infoArea.
Text =
string.Empty;
163 bool outputsFound =
false;
164 foreach (var (inputItem, deconstructItem) in GetAvailableOutputs(checkRequiredOtherItems:
true))
167 if (!
string.IsNullOrEmpty(deconstructItem.ActivateButtonText))
169 LocalizedString buttonText = TextManager.Get(deconstructItem.ActivateButtonText).
Fallback(deconstructItem.ActivateButtonText);
171 if (!
string.IsNullOrEmpty(deconstructItem.InfoText))
173 infoText = TextManager.Get(deconstructItem.InfoText).
Fallback(deconstructItem.InfoText);
175 inputItem.GetComponent<
GeneticMaterial>()?.ModifyDeconstructInfo(
this, ref buttonText, ref infoText);
176 activateButton.
Text = buttonText;
177 if (infoArea !=
null)
179 infoArea.
Text = infoText;
185 if (!outputsFound && infoArea !=
null)
187 foreach (var (inputItem, deconstructItem) in GetAvailableOutputs(checkRequiredOtherItems:
false))
189 if (deconstructItem.RequiredOtherItem.Any() && !
string.IsNullOrEmpty(deconstructItem.InfoTextOnOtherItemMissing))
191 LocalizedString missingItemName = TextManager.Get(
"entityname." + deconstructItem.RequiredOtherItem.First());
192 infoArea.
Text = TextManager.GetWithVariable(deconstructItem.InfoTextOnOtherItemMissing,
"[itemname]", missingItemName);
210 if (!(linkedTo is
Item { DisplaySideBySideWhenLinked:
true } linkedItem)) {
continue; }
211 if (!linkedItem.Components.Any()) {
continue; }
213 var itemContainer = linkedItem.GetComponent<
ItemContainer>();
214 if (itemContainer?.
GuiFrame ==
null || itemContainer.AllowUIOverlap) {
continue; }
217 var padding = (int) (8 * GUI.Scale);
223 return base.Select(character);
228 if (container.
Inventory is
null) {
return; }
232 private void RefreshOutputDisplay(ImmutableArray<Item> items)
234 const string outputItemCountUserData =
"OutputItemCount";
235 const string questionMarkUserData =
"UnknownItemOutput";
237 if (outputDisplayListBox is
null || inputContainer.
Inventory is
null) {
return; }
239 Dictionary<Identifier, int> itemCounts =
new Dictionary<Identifier, int>();
240 Dictionary<Identifier, GUIComponent> children =
new Dictionary<Identifier, GUIComponent>();
242 bool addQuestionMark =
false;
246 if (child.UserData is Identifier it)
248 children.Add(it, child);
252 if (outputDisplayListBox.
Content.
FindChild(questionMarkUserData) is { } foundChild)
257 foreach (
Item it
in items)
259 if (it.Prefab.RandomDeconstructionOutput)
261 addQuestionMark =
true;
265 foreach (DeconstructItem deconstructItem
in it.Prefab.DeconstructItems)
267 if (!deconstructItem.IsValidDeconstructor(
item)) {
continue; }
268 float percentageHealth = it.Condition / it.MaxCondition;
269 if (percentageHealth < deconstructItem.MinCondition || percentageHealth > deconstructItem.MaxCondition) {
continue; }
270 RegisterItem(deconstructItem.ItemIdentifier, deconstructItem.Amount);
281 void RegisterItem(Identifier identifier,
int amount = 1)
283 if (itemCounts.ContainsKey(identifier))
285 itemCounts[identifier] += amount;
288 itemCounts.Add(identifier, amount);
292 foreach (var (it, child) in children)
294 if (!itemCounts.ContainsKey(it))
300 foreach (var (it, amount) in itemCounts)
302 if (!children.TryGetValue(it, out GUIComponent child))
304 child = CreateOutputDisplayItem(it, outputDisplayListBox.
Content);
307 if (child is
null) {
continue; }
308 UpdateOutputDisplayItemCount(child, amount);
313 CreateQuestionMark(outputDisplayListBox.
Content);
316 static void CreateQuestionMark(GUIComponent parent)
318 GUIFrame itemFrame =
new GUIFrame(
new RectTransform(
new Vector2(0.1f, 1f), parent.RectTransform), style:
null)
320 UserData = questionMarkUserData,
321 ToolTip = TextManager.Get(
"deconstructor.unknownitemsoutput")
324 GUIFrame questionMarkFrame =
new GUIFrame(
new RectTransform(Vector2.One, itemFrame.RectTransform, scaleBasis:
ScaleBasis.Smallest, anchor:
Anchor.Center), style:
"GUIFrameListBox")
326 CanBeFocused =
false,
330 new GUITextBlock(
new RectTransform(Vector2.One, questionMarkFrame.RectTransform, anchor:
Anchor.Center), text:
"?", textAlignment: Alignment.Center, font: GUIStyle.LargeFont)
336 static GUIComponent CreateOutputDisplayItem(Identifier identifier, GUIComponent parent)
338 ItemPrefab prefab = ItemPrefab.Find(
null, identifier);
339 if (prefab is
null) {
return null; }
341 GUIFrame itemFrame =
new GUIFrame(
new RectTransform(
new Vector2(0.1f, 1f), parent.RectTransform), style:
null)
343 UserData = identifier,
344 ToolTip = prefab.CreateTooltipText()
347 Sprite icon = prefab.InventoryIcon ?? prefab.Sprite;
348 Color iconColor = prefab.InventoryIcon is
null ? prefab.SpriteColor : prefab.InventoryIconColor;
350 GUIImage itemIcon =
new GUIImage(
new RectTransform(Vector2.One, itemFrame.RectTransform, scaleBasis:
ScaleBasis.Smallest, anchor:
Anchor.Center), sprite: icon, scaleToFit:
true)
357 new GUITextBlock(
new RectTransform(
new Vector2(0.5f, 0.5f), itemIcon.RectTransform, anchor:
Anchor.BottomRight),
"", font: GUIStyle.Font, textAlignment: Alignment.BottomRight)
359 UserData = outputItemCountUserData,
361 CanBeFocused =
false,
362 Padding = Vector4.Zero,
363 TextColor = Color.White,
369 static void UpdateOutputDisplayItemCount(GUIComponent component,
int count)
371 if (!(component.FindChild(outputItemCountUserData, recursive:
true) is GUITextBlock textBlock)) {
return; }
373 textBlock.Text = TextManager.GetWithVariable(
"campaignstore.quantity",
"[amount]", count.ToString());
377 partial
void OnItemLoadedProjSpecific()
387 private void DrawOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent)
389 overlayComponent.RectTransform.SetAsLastChild();
391 if (!(inputContainer?.Inventory?.visualSlots is { } visualSlots)) {
return; }
406 void DrawProgressBar(VisualSlot slot)
408 GUI.DrawRectangle(spriteBatch,
410 slot.Rect.X, slot.Rect.Y + (
int)(slot.Rect.Height * (1.0f - progressState)),
411 slot.Rect.Width, (
int)(slot.Rect.Height * progressState)),
412 GUIStyle.Green * 0.5f, isFilled:
true);
421 private bool OnActivateButtonClicked(
GUIButton button,
object obj)
426 var disallowedItem = inputContainer.
Inventory.
FindItem(i => !i.AllowDeconstruct, recursive:
false);
439 if (GameMain.Client !=
null)
442 item.CreateClientEvent(
this);
const ushort NullEntityID
static Entity FindEntityByID(ushort ID)
Find an entity based on the ID
Action< GUIComponent > OnAddedToGUIUpdateList
GUIComponent FindChild(Func< GUIComponent, bool > predicate, bool recursive=false)
RectTransform RectTransform
IEnumerable< GUIComponent > Children
GUIComponent that can be used to render custom content on the UI
override void RemoveChild(GUIComponent child)
GUIFrame Content
A frame that contains the contents of the listbox. The frame itself is not rendered.
RectTransform RectTransform
If set, the inventory is automatically positioned inside the rect
Item FindItem(Func< Item, bool > predicate, bool recursive)
virtual IEnumerable< Item > AllItems
All items contained in the inventory. Stacked items are returned as individual instances....
int FindIndex(Item item)
Find the index of the first slot the item is contained in.
Item GetItemAt(int index)
Get the item stored in the specified inventory slot. If the slot contains a stack of items,...
override LocalizedString Name
void SetActive(bool active, Character user=null, bool createNetworkEvent=false)
override void OnResolutionChanged()
override void UpdateHUDComponentSpecific(Character character, float deltaTime, Camera cam)
string ActivateButtonText
override void CreateGUI()
Overload this method and implement. The method is automatically called when the resolution changes.
override bool RecreateGUIOnResolutionChange
bool DeconstructItemsSimultaneously
void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData=null)
override bool Select(Character character)
ItemContainer InputContainer
void ClientEventRead(IReadMessage msg, float sendingTime)
readonly ItemInventory Inventory
LocalizedString Fallback(LocalizedString fallback, bool useDefaultLanguageIfFound=true)
Use this text instead if the original text cannot be found.
readonly List< MapEntity > linkedTo
void ShowBorderHighlight(Color color, float fadeInDuration, float fadeOutDuration, float scaleUpAmount=0.5f)
Highlights an UI element of some kind. Generally used in tutorials.
Interface for entities that the clients can send events to the server
Interface for entities that the server can send events to the clients
void WriteBoolean(bool val)