5 using Microsoft.Xna.Framework;
9 internal partial class CircuitBoxWire : CircuitBoxSelectable, ICircuitBoxIdentifiable
11 public CircuitBoxConnection From, To;
12 public readonly Option<Item> BackingWire;
14 public readonly Color Color;
15 public readonly ItemPrefab UsedItemPrefab;
17 public ushort ID {
get; }
19 public CircuitBoxWire(CircuitBox circuitBox, ushort Id, Option<Item> backingItem, CircuitBoxConnection from, CircuitBoxConnection to, ItemPrefab prefab)
24 BackingWire = backingItem;
25 Color = prefab.SpriteColor;
26 UsedItemPrefab = prefab;
28 Renderer =
new CircuitBoxWireRenderer(Option.Some(
this), to.AnchorPoint, from.AnchorPoint, Color, circuitBox.WireSprite);
30 EnsureWireConnected();
33 public XElement Save()
35 XElement element =
new XElement(
"Wire",
36 new XAttribute(
"id", ID),
37 new XAttribute(
"backingitemid", BackingWire.TryUnwrap(out var item) ? ItemSlotIndexPair.Serialize(item) :
string.Empty),
38 new XAttribute(
"prefab", UsedItemPrefab.Identifier));
40 XElement fromElement = CircuitBoxConnectorIdentifier.FromConnection(From).Save(
"From"),
41 toElement = CircuitBoxConnectorIdentifier.FromConnection(To).Save(
"To");
43 element.Add(fromElement);
44 element.Add(toElement);
49 public static Option<CircuitBoxWire> TryLoadFromXML(ContentXElement element, CircuitBox circuitBox)
51 ushort
id = element.GetAttributeUInt16(
"id", ICircuitBoxIdentifiable.NullComponentID);
52 var backingItemIdOption = ItemSlotIndexPair.TryDeserializeFromXML(element,
"backingitemid");
53 Identifier usedPrefabIdentifier = element.GetAttributeIdentifier(
"prefab", Identifier.Empty);
55 if (!ItemPrefab.Prefabs.TryGet(usedPrefabIdentifier, out var itemPrefab))
57 DebugConsole.ThrowErrorAndLogToGA(
"CircuitBoxWire.TryLoadFromXML:PrefabNotFound",
58 $
"Failed to find prefab used to create wire with identifier {usedPrefabIdentifier} for CircuitBoxWire with ID {id}");
62 Option<Item> backingItem = Option.None;
63 if (backingItemIdOption.TryUnwrap(out var backingItemIdPair))
65 if (backingItemIdPair.FindItemInContainer(circuitBox.WireContainer) is { } item)
67 backingItem = Option.Some(item);
71 DebugConsole.ThrowErrorAndLogToGA(
"CircuitBoxWire.TryLoadFromXML:IdNotFound",
72 $
"Failed to find item with ID {backingItemIdPair} for CircuitBoxWire with ID {id}");
77 Option<CircuitBoxConnection> From = Option.None,
80 foreach (ContentXElement subElement
in element.Elements())
82 switch (subElement.Name.ToString().ToLowerInvariant())
85 var fromIdentifier = CircuitBoxConnectorIdentifier.Load(subElement);
86 if (fromIdentifier.FindConnection(circuitBox).TryUnwrap(out var fromConnection))
88 From = Option.Some(fromConnection);
92 var toIdentifier = CircuitBoxConnectorIdentifier.Load(subElement);
93 if (toIdentifier.FindConnection(circuitBox).TryUnwrap(out var toConnection))
95 To = Option.Some(toConnection);
101 if (From.TryUnwrap(out var from) && To.TryUnwrap(out var to))
103 return Option.Some(
new CircuitBoxWire(circuitBox,
id, backingItem, from, to, itemPrefab));
106 DebugConsole.ThrowErrorAndLogToGA(
"CircuitBoxWire.TryLoadFromXML:MissingFromOrTo",
107 $
"Failed to load CircuitBoxWire with ID {id}, missing \"From\" or \"To\" connection.");
112 public void EnsureWireConnected()
114 EnsureExternalConnection(From, To);
115 EnsureExternalConnection(To, From);
117 if (!BackingWire.TryUnwrap(out var item) || item.GetComponent<
Wire>() is not { } wire) {
return; }
119 wire.DropOnConnect =
false;
121 From.Connection.ConnectWire(wire);
122 To.Connection.ConnectWire(wire);
124 wire.Connect(From.Connection, 0, addNode:
false, sendNetworkEvent:
false);
125 wire.Connect(To.Connection, 1, addNode:
false, sendNetworkEvent:
false);
127 static void EnsureExternalConnection(CircuitBoxConnection one, CircuitBoxConnection two)
131 case CircuitBoxInputConnection input:
133 if (input.ExternallyConnectedTo.Contains(two)) {
break; }
134 input.ExternallyConnectedTo.Add(two);
137 case CircuitBoxOutputConnection output:
139 if (output.ExternallyConnectedFrom.Contains(two)) {
break; }
140 output.ExternallyConnectedFrom.Add(two);
143 case CircuitBoxNodeConnection node when two is CircuitBoxOutputConnection output:
145 if (node.Connection.CircuitBoxConnections.Contains(output)) {
break; }
146 node.Connection.CircuitBoxConnections.Add(output);
149 case CircuitBoxNodeConnection node when two is CircuitBoxInputConnection input:
151 if (!node.Connection.CircuitBoxConnections.Contains(input))
153 node.Connection.CircuitBoxConnections.Add(input);
155 if (!node.ExternallyConnectedFrom.Contains(input))
157 node.ExternallyConnectedFrom.Add(input);
168 if (GameMain.NetworkMember is { IsClient: true }) {
return; }
170 if (!BackingWire.TryUnwrap(out var wireItem)) {
return; }
172 if (Entity.Spawner is { } spawner && Screen.Selected is not { IsEditor: true })
174 spawner.AddEntityToRemoveQueue(wireItem);
178 Wire? wire = wireItem.GetComponent<
Wire>();
179 if (wire is not
null)
181 From.Connection.DisconnectWire(wire);
182 To.Connection.DisconnectWire(wire);
188 public static ItemPrefab DefaultWirePrefab => ItemPrefab.Prefabs[Tags.RedWire];
189 public static ItemPrefab SelectedWirePrefab = DefaultWirePrefab;
190 public static readonly Color DefaultWireColor = DefaultWirePrefab.SpriteColor;