private void CreateNodes(XElement element, ref bool hadNodes, EditorNode?parent = null, int ident = 0) { EditorNode?lastNode = null; foreach (XElement subElement in element.Elements()) { bool skip = true; switch (subElement.Name.ToString().ToLowerInvariant()) { case "failure": case "success": case "option": CreateNodes(subElement, ref hadNodes, parent, ident); break; default: skip = false; break; } if (!skip) { Vector2 defaultNodePos = new Vector2(-16000, -16000); EditorNode newNode; Type? t = Type.GetType($"Barotrauma.{subElement.Name}"); if (t != null && EditorNode.IsInstanceOf(t, typeof(EventAction))) { newNode = new EventNode(t, subElement.Name.ToString()) { Position = new Vector2(ident, 0), ID = CreateID() }; } else { newNode = new CustomNode(subElement.Name.ToString()) { Position = new Vector2(ident, 0), ID = CreateID() }; foreach (XAttribute attribute in subElement.Attributes()) { newNode.Connections.Add(new NodeConnection(newNode, NodeConnectionType.Value, attribute.Name.ToString(), typeof(string))); } } Vector2 npos = subElement.GetAttributeVector2("_npos", defaultNodePos); if (npos != defaultNodePos) { newNode.Position = npos; } else { hadNodes = false; } XElement?parentElement = subElement.Parent; foreach (XElement xElement in subElement.Elements()) { if (xElement.Name.ToString().ToLowerInvariant() == "option") { NodeConnection optionConnection = new NodeConnection(newNode, NodeConnectionType.Option) { OptionText = xElement.GetAttributeString("text", string.Empty), EndConversation = xElement.GetAttributeBool("endconversation", false) }; newNode.Connections.Add(optionConnection); } } foreach (NodeConnection connection in newNode.Connections) { if (connection.Type == NodeConnectionType.Value) { foreach (XAttribute attribute in subElement.Attributes()) { if (string.Equals(connection.Attribute, attribute.Name.ToString(), StringComparison.InvariantCultureIgnoreCase) && connection.ValueType != null) { if (connection.ValueType.IsEnum) { Array values = Enum.GetValues(connection.ValueType); foreach (object? @enum in values) { if (string.Equals(@enum?.ToString(), attribute.Value, StringComparison.InvariantCultureIgnoreCase)) { connection.OverrideValue = @enum; } } } else { connection.OverrideValue = Convert.ChangeType(attribute.Value, connection.ValueType); } } } } } if (npos == defaultNodePos) { hadNodes = false; bool Predicate(EditorNode node) => Rectangle.Union(node.GetDrawRectangle(), node.HeaderRectangle).Intersects(Rectangle.Union(newNode.GetDrawRectangle(), newNode.HeaderRectangle)); while (nodeList.Any(Predicate)) { EditorNode?otherNode = nodeList.Find(Predicate); if (otherNode != null) { newNode.Position += new Vector2(128, otherNode.GetDrawRectangle().Height + otherNode.HeaderRectangle.Height + new Random().Next(128, 256)); } } } if (parentElement?.FirstElement() == subElement) { switch (parentElement?.Name.ToString().ToLowerInvariant()) { case "failure": parent?.Connect(newNode, NodeConnectionType.Failure); break; case "success": parent?.Connect(newNode, NodeConnectionType.Success); break; case "option": if (parent != null) { NodeConnection?activateConnection = newNode.Connections.Find(connection => connection.Type == NodeConnectionType.Activate); NodeConnection?optionConnection = parent.Connections.FirstOrDefault(connection => connection.Type == NodeConnectionType.Option && string.Equals(connection.OptionText, parentElement.GetAttributeString("text", string.Empty), StringComparison.Ordinal)); if (activateConnection != null) { optionConnection?.ConnectedTo.Add(activateConnection); } } break; default: parent?.Connect(newNode, NodeConnectionType.Add); break; } } else { lastNode?.Connect(newNode, NodeConnectionType.Next); } lastNode = newNode; nodeList.Add(newNode); ident += 600; CreateNodes(subElement, ref hadNodes, newNode, ident); } else { } } }
public void LoadConnections(XElement element) { foreach (XElement subElement in element.Elements()) { int id = subElement.GetAttributeInt("i", -1); string?connectionType = subElement.GetAttributeString("type", null); bool endConversation = subElement.GetAttributeBool("endconversation", false); if (id < 0) { continue; } NodeConnection?connection = Connections.Find(c => c.ID == id); if (connection == null) { if (string.Equals(connectionType, NodeConnectionType.Option.Label, StringComparison.InvariantCultureIgnoreCase)) { connection = new NodeConnection(this, NodeConnectionType.Option) { ID = id, EndConversation = endConversation }; Connections.Add(connection); } else { continue; } } string?optionText = subElement.GetAttributeString("optiontext", null); string?overrideValue = subElement.GetAttributeString("overridevalue", null); string?valueType = subElement.GetAttributeString("valuetype", null); if (optionText != null) { connection.OptionText = optionText; } if (overrideValue != null && valueType != null) { Type?type = Type.GetType(valueType); if (type != null) { if (type.IsEnum) { Array enums = Enum.GetValues(type); foreach (object? @enum in enums) { if (string.Equals(@enum?.ToString(), overrideValue, StringComparison.InvariantCultureIgnoreCase)) { connection.OverrideValue = @enum; } } } else { connection.OverrideValue = Convert.ChangeType(overrideValue, type); } } } foreach (XElement connectedTo in subElement.Elements()) { int id2 = connectedTo.GetAttributeInt("i", -1); int node = connectedTo.GetAttributeInt("node", -1); if (id2 < 0 || node < 0) { continue; } EditorNode? otherNode = EventEditorScreen.nodeList.Find(editorNode => editorNode.ID == node); NodeConnection?otherConnection = otherNode?.Connections.Find(c => c.ID == id2); if (otherConnection != null) { connection.ConnectedTo.Add(otherConnection); } } } }