Client LuaCsForBarotrauma
BarotraumaShared/SharedSource/CircuitBox/CircuitBoxComponent.cs
1 #nullable enable
2 
3 using System;
4 using System.Collections.Immutable;
5 using System.Linq;
6 using System.Xml.Linq;
8 using Microsoft.Xna.Framework;
9 
10 namespace Barotrauma
11 {
12  internal partial class CircuitBoxComponent : CircuitBoxNode, ICircuitBoxIdentifiable
13  {
14  public readonly Item Item;
15  public ushort ID { get; }
16 
17  public readonly ItemPrefab UsedResource;
18 
19  public CircuitBoxComponent(ushort id, Item item, Vector2 position, CircuitBox circuitBox, ItemPrefab usedResource): base(circuitBox)
20  {
21  if (item.Connections is null)
22  {
23  throw new ArgumentNullException(nameof(item.Connections), $"Tried to load a CircuitBoxNode with an item \"{item.Prefab.Name}\" that has no connections.");
24  }
25 
26  var conns = item.Connections.Select(connection => new CircuitBoxNodeConnection(Vector2.Zero, this, connection, circuitBox)).ToList();
27 
28  Vector2 size = CalculateSize(conns);
29 
30  ID = id;
31  Item = item;
32  Size = size;
33  Connectors = conns.Cast<CircuitBoxConnection>().ToImmutableArray();
34  Position = position;
35  UsedResource = usedResource;
36  UpdatePositions();
37  }
38 
39  public static Option<CircuitBoxComponent> TryLoadFromXML(ContentXElement element, CircuitBox circuitBox)
40  {
41  ushort id = element.GetAttributeUInt16("id", ICircuitBoxIdentifiable.NullComponentID);
42  Vector2 position = element.GetAttributeVector2("position", Vector2.Zero);
43  var itemIdOption = ItemSlotIndexPair.TryDeserializeFromXML(element, "backingitemid");
44  Identifier usedResourceIdentifier = element.GetAttributeIdentifier("usedresource", Identifier.Empty);
45 
46  if (!itemIdOption.TryUnwrap(out var itemId) || itemId.FindItemInContainer(circuitBox.ComponentContainer) is not { } backingItem)
47  {
48  DebugConsole.ThrowErrorAndLogToGA("CircuitBoxComponent.TryLoadFromXML:IdNotFound",
49  $"Failed to find item with ID {itemId} for CircuitBoxNode with ID {id}");
50  return Option.None;
51  }
52 
53  if (!ItemPrefab.Prefabs.TryGet(usedResourceIdentifier, out var usedResource))
54  {
55  DebugConsole.ThrowErrorAndLogToGA("CircuitBoxComponent.TryLoadXML:UsedResourceNotFound",
56  $"Failed to find item prefab with identifier {usedResourceIdentifier} for CircuitBoxNode with ID {id}");
57  return Option.None;
58  }
59 
60  return Option.Some(new CircuitBoxComponent(id, backingItem, position, circuitBox, usedResource));
61  }
62 
63  public XElement Save()
64  {
65  return new XElement("Component",
66  new XAttribute("id", ID),
67  new XAttribute("position", XMLExtensions.Vector2ToString(Position)),
68  new XAttribute("backingitemid", ItemSlotIndexPair.Serialize(Item)),
69  new XAttribute("usedresource", UsedResource.Identifier));
70  }
71 
72  public void Remove()
73  {
74  if (Entity.Spawner is { } spawner && Screen.Selected is not { IsEditor: true })
75  {
76  spawner.AddEntityToRemoveQueue(Item);
77  return;
78  }
79 
80  // if EntitySpawner is not available
81  Item.Remove();
82  }
83  }
84 }