예제 #1
0
        private void ExportChildNodes(EditorNode startNode, XElement parent)
        {
            XElement?newElement = startNode.ToXML();

            if (newElement == null)
            {
                return;
            }
            parent.Add(newElement);

            EditorNode?success = startNode.GetNext(NodeConnectionType.Success);
            EditorNode?failure = startNode.GetNext(NodeConnectionType.Failure);
            EditorNode?add     = startNode.GetNext(NodeConnectionType.Add);

            Tuple <EditorNode?, string?, bool>[] options = startNode is EventNode eNode?eNode.GetOptions() : new Tuple <EditorNode?, string?, bool> [0];

            if (success != null)
            {
                XElement successElement = new XElement("Success");
                ExportChildNodes(success, successElement);
                newElement.Add(successElement);
            }

            if (failure != null)
            {
                XElement failureElement = new XElement("Failure");
                ExportChildNodes(failure, failureElement);
                newElement.Add(failureElement);
            }

            if (add is CustomNode custom)
            {
                ExportChildNodes(custom, newElement);
            }

            foreach (var(node, text, end) in options)
            {
                XElement optionElement = new XElement("Option");
                optionElement.Add(new XAttribute("text", text));
                if (end)
                {
                    optionElement.Add(new XAttribute("endconversation", true));
                }

                if (node != null)
                {
                    ExportChildNodes((EventNode)node, optionElement);
                }

                newElement.Add(optionElement);
            }

            EditorNode?next = startNode.GetNext();

            if (next != null)
            {
                ExportChildNodes(next, parent);
            }
        }
예제 #2
0
        private void CreateContextMenu(EditorNode node, NodeConnection?connection = null)
        {
            if (GUIContextMenu.CurrentContextMenu != null)
            {
                return;
            }

            GUIContextMenu.CreateContextMenu(
                new ContextMenuOption("EventEditor.Edit", isEnabled: node is ValueNode || connection?.Type == NodeConnectionType.Value || connection?.Type == NodeConnectionType.Option, onSelected: delegate
            {
                CreateEditMenu(node as ValueNode, connection);
            }),
                new ContextMenuOption("EventEditor.MarkEnding", isEnabled: connection != null && connection.Type == NodeConnectionType.Option, onSelected: delegate
            {
                if (connection == null)
                {
                    return;
                }

                connection.EndConversation = !connection.EndConversation;
            }),
                new ContextMenuOption("EventEditor.RemoveConnection", isEnabled: connection != null, onSelected: delegate
            {
                if (connection == null)
                {
                    return;
                }

                connection.ClearConnections();
                connection.OverrideValue = null;
                connection.OptionText    = connection.OptionText;
            }),
                new ContextMenuOption("EventEditor.AddOption", isEnabled: node.CanAddConnections, onSelected: node.AddOption),
                new ContextMenuOption("EventEditor.RemoveOption", isEnabled: connection != null && node.RemovableTypes.Contains(connection.Type), onSelected: delegate
            {
                connection?.Parent.RemoveOption(connection);
            }),
                new ContextMenuOption("EventEditor.Delete", isEnabled: true, onSelected: delegate
            {
                nodeList.Remove(node);
                node.ClearConnections();
            }));
        }
예제 #3
0
        private void Load(XElement saveElement)
        {
            nodeList.Clear();
            projectName = saveElement.GetAttributeString("name", TextManager.Get("EventEditor.Unnamed"));
            foreach (XElement element in saveElement.Elements())
            {
                switch (element.Name.ToString().ToLowerInvariant())
                {
                case "nodes":
                {
                    foreach (XElement subElement in element.Elements())
                    {
                        EditorNode?node = EditorNode.Load(subElement);
                        if (node != null)
                        {
                            nodeList.Add(node);
                        }
                    }

                    break;
                }

                case "allconnections":
                {
                    foreach (XElement subElement in element.Elements())
                    {
                        int        id   = subElement.GetAttributeInt("i", -1);
                        EditorNode?node = nodeList.Find(editorNode => editorNode.ID == id);
                        node?.LoadConnections(subElement);
                    }

                    break;
                }
                }
            }
        }
예제 #4
0
        private void CreateContextMenu(EditorNode node, NodeConnection?connection = null)
        {
            contextMenu = new GUIListBox(new RectTransform(new Vector2(0.1f, 0.1f), GUI.Canvas)
            {
                ScreenSpaceOffset = PlayerInput.MousePosition.ToPoint()
            }, style: "GUIToolTip")
            {
                Padding = new Vector4(5)
            };

            new GUITextBlock(new RectTransform(Point.Zero, contextMenu.Content.RectTransform),
                             TextManager.Get("EventEditor.Edit"), font: GUI.SmallFont)
            {
                UserData = "edit", Enabled = node is ValueNode || connection?.Type == NodeConnectionType.Value || connection?.Type == NodeConnectionType.Option
            };

            new GUITextBlock(new RectTransform(Point.Zero, contextMenu.Content.RectTransform),
                             TextManager.Get("EventEditor.MarkEnding"), font: GUI.SmallFont)
            {
                UserData = "markend", Enabled = connection != null && connection.Type == NodeConnectionType.Option
            };

            new GUITextBlock(new RectTransform(Point.Zero, contextMenu.Content.RectTransform),
                             TextManager.Get("EventEditor.RemoveConnection"), font: GUI.SmallFont)
            {
                UserData = "remcon", Enabled = connection != null
            };

            new GUITextBlock(new RectTransform(Point.Zero, contextMenu.Content.RectTransform),
                             TextManager.Get("EventEditor.AddOption"), font: GUI.SmallFont)
            {
                UserData = "addoption", Enabled = node.CanAddConnections
            };

            new GUITextBlock(new RectTransform(Point.Zero, contextMenu.Content.RectTransform),
                             TextManager.Get("EventEditor.RemoveOption"), font: GUI.SmallFont)
            {
                UserData = "removeoption", Enabled = connection != null && node.RemovableTypes.Contains(connection.Type)
            };

            new GUITextBlock(new RectTransform(Point.Zero, contextMenu.Content.RectTransform),
                             TextManager.Get("EventEditor.Delete"), font: GUI.SmallFont)
            {
                UserData = "delete", Enabled = true
            };

            foreach (var guiComponent in contextMenu.Content.Children)
            {
                if (guiComponent is GUITextBlock child)
                {
                    if (!child.Enabled)
                    {
                        child.TextColor *= 0.5f;
                    }
                }
            }

            foreach (GUIComponent c in contextMenu.Content.Children)
            {
                if (c is GUITextBlock block)
                {
                    block.RectTransform.NonScaledSize = new Point((int)(block.TextSize.X + block.Padding.X * 2), (int)(18 * GUI.Scale));
                }
            }

            int biggestSize = contextMenu.Content.Children.Max(c => c.Rect.Width + (int)contextMenu.Padding.X * 2);

            contextMenu.Content.Children.ForEach(c => c.RectTransform.MinSize = new Point(biggestSize, c.Rect.Height));
            contextMenu.RectTransform.NonScaledSize = new Point(biggestSize, (int)(contextMenu.Content.Children.Sum(c => c.Rect.Height) + (contextMenu.Padding.X * 2)));

            contextMenu.OnSelected = (component, obj) =>
            {
                if (!component.Enabled)
                {
                    return(false);
                }

                switch (obj as string)
                {
                case "edit":
                    CreateEditMenu(node as ValueNode, connection);
                    break;

                case "markend" when connection != null:
                    connection.EndConversation = !connection.EndConversation;
                    break;

                case "remcon" when connection != null:
                    connection.ClearConnections();
                    connection.OverrideValue = null;
                    connection.OptionText    = connection.OptionText;
                    break;

                case "addoption":
                    node.AddOption();
                    break;

                case "removeoption":
                    connection?.Parent.RemoveOption(connection);
                    break;

                case "delete":
                    nodeList.Remove(node);
                    node.ClearConnections();

                    break;
                }

                contextMenu = null;
                return(true);
            };
        }
예제 #5
0
        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
                {
                }
            }
        }