Пример #1
0
        public override void Update(double deltaTime)
        {
            if (GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y)
            {
                CreateGUI();
            }

            Cam.MoveCamera((float)deltaTime, true, true);
            Vector2 mousePos = Cam.ScreenToWorld(PlayerInput.MousePosition);

            mousePos.Y = -mousePos.Y;

            foreach (EditorNode node in nodeList)
            {
                if (PlayerInput.PrimaryMouseButtonDown())
                {
                    NodeConnection?connection = node.GetConnectionOnMouse(mousePos);
                    if (connection != null && connection.Type.NodeSide == NodeConnectionType.Side.Right)
                    {
                        if (connection.Type != NodeConnectionType.Out)
                        {
                            if (connection.ConnectedTo.Any())
                            {
                                return;
                            }
                        }

                        DraggedConnection = connection;
                    }
                }

                // ReSharper disable once AssignmentInConditionalExpression
                if (node.IsHighlighted = node.HeaderRectangle.Contains(mousePos))
                {
                    if (PlayerInput.PrimaryMouseButtonDown())
                    {
                        // Ctrl + clicking the headers add them to the "selection" that allows us to drag multiple nodes at once
                        if (PlayerInput.IsCtrlDown())
                        {
                            if (selectedNodes.Contains(node))
                            {
                                selectedNodes.Remove(node);
                            }
                            else
                            {
                                selectedNodes.Add(node);
                            }

                            node.IsSelected = selectedNodes.Contains(node);
                            break;
                        }

                        draggedNode = node;
                        dragOffset  = draggedNode.Position - mousePos;
                        foreach (EditorNode selectedNode in selectedNodes)
                        {
                            if (!markedNodes.ContainsKey(selectedNode))
                            {
                                markedNodes.Add(selectedNode, selectedNode.Position - mousePos);
                            }
                        }
                    }
                }

                if (PlayerInput.SecondaryMouseButtonClicked())
                {
                    NodeConnection?connection = node.GetConnectionOnMouse(mousePos);
                    if (node.GetDrawRectangle().Contains(mousePos) || connection != null)
                    {
                        CreateContextMenu(node, node.GetConnectionOnMouse(mousePos));
                        break;
                    }
                }
            }

            if (PlayerInput.SecondaryMouseButtonClicked())
            {
                foreach (var selectedNode in selectedNodes)
                {
                    selectedNode.IsSelected = false;
                }

                selectedNodes.Clear();
            }

            if (draggedNode != null)
            {
                if (!PlayerInput.PrimaryMouseButtonHeld())
                {
                    draggedNode = null;
                    markedNodes.Clear();
                }
                else
                {
                    Vector2 offsetChange = Vector2.Zero;
                    draggedNode.IsHighlighted = true;
                    draggedNode.Position      = mousePos + dragOffset;

                    if (PlayerInput.KeyHit(Keys.Up))
                    {
                        offsetChange.Y--;
                    }

                    if (PlayerInput.KeyHit(Keys.Down))
                    {
                        offsetChange.Y++;
                    }

                    if (PlayerInput.KeyHit(Keys.Left))
                    {
                        offsetChange.X--;
                    }

                    if (PlayerInput.KeyHit(Keys.Right))
                    {
                        offsetChange.X++;
                    }

                    dragOffset += offsetChange;

                    foreach (var(editorNode, offset) in markedNodes.Where(pair => pair.Key != draggedNode))
                    {
                        editorNode.Position = mousePos + offset;
                    }

                    if (offsetChange != Vector2.Zero)
                    {
                        foreach (var(key, value) in markedNodes.ToList())
                        {
                            markedNodes[key] = value + offsetChange;
                        }
                    }
                }
            }

            if (DraggedConnection != null)
            {
                if (!PlayerInput.PrimaryMouseButtonHeld())
                {
                    foreach (EditorNode node in nodeList)
                    {
                        var nodeOnMouse = node.GetConnectionOnMouse(mousePos);
                        if (nodeOnMouse != null && nodeOnMouse != DraggedConnection && nodeOnMouse.Type.NodeSide == NodeConnectionType.Side.Left)
                        {
                            if (!DraggedConnection.CanConnect(nodeOnMouse))
                            {
                                continue;
                            }

                            nodeOnMouse.ClearConnections();
                            DraggedConnection.Parent.Connect(DraggedConnection, nodeOnMouse);
                            break;
                        }
                    }

                    DraggedConnection = null;
                }
                else
                {
                    DraggingPosition = mousePos;
                }
            }
            else
            {
                DraggingPosition = Vector2.Zero;
            }

            if (contextMenu != null)
            {
                Rectangle expandedRect = contextMenu.Rect;
                expandedRect.Inflate(20, 20);
                if (!expandedRect.Contains(PlayerInput.MousePosition))
                {
                    contextMenu = null;
                }
            }

            if (PlayerInput.MidButtonHeld())
            {
                Vector2 moveSpeed = PlayerInput.MouseSpeed * (float)deltaTime * 60.0f / Cam.Zoom;
                moveSpeed.X   = -moveSpeed.X;
                Cam.Position += moveSpeed;
            }

            base.Update(deltaTime);
        }
Пример #2
0
        private static void UpdateHighlightedListBox(List <MapEntity> highlightedEntities, bool wiringMode)
        {
            if (highlightedEntities == null || highlightedEntities.Count < 2)
            {
                highlightedListBox = null;
                return;
            }
            if (highlightedListBox != null)
            {
                if (GUI.MouseOn == highlightedListBox || highlightedListBox.IsParentOf(GUI.MouseOn))
                {
                    return;
                }
                if (highlightedEntities.SequenceEqual(highlightedList))
                {
                    return;
                }
            }

            highlightedList = highlightedEntities;

            highlightedListBox = new GUIListBox(new RectTransform(new Point(180, highlightedEntities.Count * 18 + 5), GUI.Canvas)
            {
                MaxSize           = new Point(int.MaxValue, 256),
                ScreenSpaceOffset = PlayerInput.MousePosition.ToPoint() + new Point(15)
            }, style: "GUIToolTip");

            foreach (MapEntity entity in highlightedEntities)
            {
                var tooltip = string.Empty;

                if (wiringMode && entity is Item item)
                {
                    var wire = item.GetComponent <Wire>();
                    if (wire?.Connections != null)
                    {
                        for (var i = 0; i < wire.Connections.Length; i++)
                        {
                            var conn = wire.Connections[i];
                            if (conn != null)
                            {
                                string[] tags   = { "[item]", "[pin]" };
                                string[] values = { conn.Item?.Name, conn.Name };
                                tooltip += TextManager.GetWithVariables("wirelistformat", tags, values);
                            }
                            if (i != wire.Connections.Length - 1)
                            {
                                tooltip += '\n';
                            }
                        }
                    }
                }

                var textBlock = new GUITextBlock(new RectTransform(new Point(highlightedListBox.Content.Rect.Width, 15), highlightedListBox.Content.RectTransform),
                                                 ToolBox.LimitString(entity.Name, GUI.SmallFont, 140), font: GUI.SmallFont)
                {
                    ToolTip  = tooltip,
                    UserData = entity
                };
            }

            highlightedListBox.OnSelected = (GUIComponent component, object obj) =>
            {
                MapEntity entity = obj as MapEntity;

                if (PlayerInput.IsCtrlDown() && !wiringMode)
                {
                    if (selectedList.Contains(entity))
                    {
                        RemoveSelection(entity);
                    }
                    else
                    {
                        AddSelection(entity);
                    }

                    return(true);
                }
                SelectEntity(entity);

                return(true);
            };
        }
Пример #3
0
        public static void UpdateEditor(Camera cam)
        {
            if (highlightedListBox != null)
            {
                highlightedListBox.UpdateManually((float)Timing.Step);
            }

            if (editingHUD != null)
            {
                if (FilteredSelectedList.Count == 0 || editingHUD.UserData != FilteredSelectedList[0])
                {
                    foreach (GUIComponent component in editingHUD.Children)
                    {
                        var textBox = component as GUITextBox;
                        if (textBox == null)
                        {
                            continue;
                        }
                        textBox.Deselect();
                    }
                    editingHUD = null;
                }
            }
            FilteredSelectedList.Clear();
            if (selectedList.Count == 0)
            {
                return;
            }
            foreach (var e in selectedList)
            {
                if (e is Gap gap && gap.ConnectedDoor != null)
                {
                    continue;
                }
                FilteredSelectedList.Add(e);
            }
            var first = FilteredSelectedList.FirstOrDefault();

            if (first != null)
            {
                first.UpdateEditing(cam);
                if (first.ResizeHorizontal || first.ResizeVertical)
                {
                    first.UpdateResizing(cam);
                }
            }

            if (PlayerInput.IsCtrlDown())
            {
                if (PlayerInput.KeyHit(Keys.N))
                {
                    float minX = selectedList[0].WorldRect.X, maxX = selectedList[0].WorldRect.Right;
                    for (int i = 0; i < selectedList.Count; i++)
                    {
                        minX = Math.Min(minX, selectedList[i].WorldRect.X);
                        maxX = Math.Max(maxX, selectedList[i].WorldRect.Right);
                    }

                    float centerX = (minX + maxX) / 2.0f;
                    foreach (MapEntity me in selectedList)
                    {
                        me.FlipX(false);
                        me.Move(new Vector2((centerX - me.WorldPosition.X) * 2.0f, 0.0f));
                    }
                }
                else if (PlayerInput.KeyHit(Keys.M))
                {
                    float minY = selectedList[0].WorldRect.Y - selectedList[0].WorldRect.Height, maxY = selectedList[0].WorldRect.Y;
                    for (int i = 0; i < selectedList.Count; i++)
                    {
                        minY = Math.Min(minY, selectedList[i].WorldRect.Y - selectedList[i].WorldRect.Height);
                        maxY = Math.Max(maxY, selectedList[i].WorldRect.Y);
                    }

                    float centerY = (minY + maxY) / 2.0f;
                    foreach (MapEntity me in selectedList)
                    {
                        me.FlipY(false);
                        me.Move(new Vector2(0.0f, (centerY - me.WorldPosition.Y) * 2.0f));
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Update the selection logic in submarine editor
        /// </summary>
        public static void UpdateSelecting(Camera cam)
        {
            if (resizing)
            {
                if (selectedList.Count == 0)
                {
                    resizing = false;
                }
                return;
            }

            foreach (MapEntity e in mapEntityList)
            {
                e.isHighlighted = false;
            }

            if (DisableSelect)
            {
                DisableSelect = false;
                return;
            }

            if (GUI.MouseOn != null || !PlayerInput.MouseInsideWindow)
            {
                if (highlightedListBox == null ||
                    (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn)))
                {
                    UpdateHighlightedListBox(null, false);
                    return;
                }
            }

            if (MapEntityPrefab.Selected != null)
            {
                selectionPos = Vector2.Zero;
                selectedList.Clear();
                return;
            }
            if (GUI.KeyboardDispatcher.Subscriber == null)
            {
                if (PlayerInput.KeyDown(Keys.Delete))
                {
                    selectedList.ForEach(e =>
                    {
                        //orphaned wires may already have been removed
                        if (!e.Removed)
                        {
                            e.Remove();
                        }
                    });
                    selectedList.Clear();
                }

                if (PlayerInput.IsCtrlDown())
                {
                    if (PlayerInput.KeyHit(Keys.C))
                    {
                        Copy(selectedList);
                    }
                    else if (PlayerInput.KeyHit(Keys.X))
                    {
                        Cut(selectedList);
                    }
                    else if (PlayerInput.KeyHit(Keys.V))
                    {
                        Paste(cam.WorldViewCenter);
                    }
                    else if (PlayerInput.KeyHit(Keys.G))
                    {
                        if (selectedList.Any())
                        {
                            if (SelectionGroups.ContainsKey(selectedList.Last()))
                            {
                                // Ungroup all selected
                                selectedList.ForEach(e => SelectionGroups.Remove(e));
                            }
                            else
                            {
                                foreach (var entity in selectedList)
                                {
                                    // Remove the old group, if any
                                    SelectionGroups.Remove(entity);
                                    // Create a group that can be accessed with any member
                                    SelectionGroups.Add(entity, selectedList);
                                }
                            }
                        }
                    }
                    else if (PlayerInput.KeyHit(Keys.Z))
                    {
                        SetPreviousRects(e => e.rectMemento.Undo());
                    }
                    else if (PlayerInput.KeyHit(Keys.R))
                    {
                        SetPreviousRects(e => e.rectMemento.Redo());
                    }

                    void SetPreviousRects(Func <MapEntity, Rectangle> memoryMethod)
                    {
                        foreach (var e in SelectedList)
                        {
                            if (e.rectMemento != null)
                            {
                                Point diff = memoryMethod(e).Location - e.Rect.Location;
                                // We have to call the move method, because there's a lot more than just storing the rect (in some cases)
                                // We also have to reassign the rect, because the move method does not set the width and height. They might have changed too.
                                // The Rect property is virtual and it's overridden for structs. Setting the rect via the property should automatically recreate the sections for resizable structures.
                                e.Move(diff.ToVector2());
                                e.Rect = e.rectMemento.Current;
                            }
                        }
                    }
                }
            }

            Vector2   position          = cam.ScreenToWorld(PlayerInput.MousePosition);
            MapEntity highLightedEntity = null;

            if (startMovingPos == Vector2.Zero)
            {
                List <MapEntity> highlightedEntities = new List <MapEntity>();
                if (highlightedListBox != null && highlightedListBox.IsParentOf(GUI.MouseOn))
                {
                    highLightedEntity = GUI.MouseOn.UserData as MapEntity;
                }
                else
                {
                    foreach (MapEntity e in mapEntityList)
                    {
                        if (!e.SelectableInEditor)
                        {
                            continue;
                        }

                        if (e.IsMouseOn(position))
                        {
                            int i = 0;
                            while (i < highlightedEntities.Count &&
                                   e.Sprite != null &&
                                   (highlightedEntities[i].Sprite == null || highlightedEntities[i].SpriteDepth < e.SpriteDepth))
                            {
                                i++;
                            }

                            highlightedEntities.Insert(i, e);

                            if (i == 0)
                            {
                                highLightedEntity = e;
                            }
                        }
                    }

                    UpdateHighlighting(highlightedEntities);
                }

                if (highLightedEntity != null)
                {
                    highLightedEntity.isHighlighted = true;
                }
            }

            if (GUI.KeyboardDispatcher.Subscriber == null)
            {
                int up    = PlayerInput.KeyDown(Keys.Up) ? 1 : 0,
                    down  = PlayerInput.KeyDown(Keys.Down) ? -1 : 0,
                    left  = PlayerInput.KeyDown(Keys.Left) ? -1 : 0,
                    right = PlayerInput.KeyDown(Keys.Right) ? 1 : 0;

                int xKeysDown = (left + right);
                int yKeysDown = (up + down);

                if (xKeysDown != 0 || yKeysDown != 0)
                {
                    keyDelay += (float)Timing.Step;
                }
                else
                {
                    keyDelay = 0;
                }

                Vector2 nudgeAmount = Vector2.Zero;

                if (keyDelay >= 0.5f)
                {
                    nudgeAmount.Y = yKeysDown;
                    nudgeAmount.X = xKeysDown;
                }

                if (PlayerInput.KeyHit(Keys.Up))
                {
                    nudgeAmount.Y = 1f;
                }
                if (PlayerInput.KeyHit(Keys.Down))
                {
                    nudgeAmount.Y = -1f;
                }
                if (PlayerInput.KeyHit(Keys.Left))
                {
                    nudgeAmount.X = -1f;
                }
                if (PlayerInput.KeyHit(Keys.Right))
                {
                    nudgeAmount.X = 1f;
                }
                if (nudgeAmount != Vector2.Zero)
                {
                    foreach (MapEntity entityToNudge in selectedList)
                    {
                        entityToNudge.Move(nudgeAmount);
                    }
                }
            }
            else
            {
                keyDelay = 0;
            }

            bool isShiftDown = PlayerInput.IsShiftDown();

            //started moving selected entities
            if (startMovingPos != Vector2.Zero)
            {
                Item targetContainer = GetPotentialContainer(position, selectedList);

                if (targetContainer != null)
                {
                    targetContainer.IsHighlighted = true;
                }

                if (PlayerInput.PrimaryMouseButtonReleased())
                {
                    //mouse released -> move the entities to the new position of the mouse

                    Vector2 moveAmount = position - startMovingPos;

                    if (!isShiftDown)
                    {
                        moveAmount.X = (float)(moveAmount.X > 0.0f ? Math.Floor(moveAmount.X / Submarine.GridSize.X) : Math.Ceiling(moveAmount.X / Submarine.GridSize.X)) * Submarine.GridSize.X;
                        moveAmount.Y = (float)(moveAmount.Y > 0.0f ? Math.Floor(moveAmount.Y / Submarine.GridSize.Y) : Math.Ceiling(moveAmount.Y / Submarine.GridSize.Y)) * Submarine.GridSize.Y;
                    }

                    if (Math.Abs(moveAmount.X) >= Submarine.GridSize.X || Math.Abs(moveAmount.Y) >= Submarine.GridSize.Y || isShiftDown)
                    {
                        if (!isShiftDown)
                        {
                            moveAmount = Submarine.VectorToWorldGrid(moveAmount);
                        }

                        //clone
                        if (PlayerInput.IsCtrlDown())
                        {
                            var clones = Clone(selectedList);
                            selectedList = clones;
                            selectedList.ForEach(c => c.Move(moveAmount));
                        }
                        else // move
                        {
                            List <MapEntity> deposited = new List <MapEntity>();
                            foreach (MapEntity e in selectedList)
                            {
                                if (e.rectMemento == null)
                                {
                                    e.rectMemento = new Memento <Rectangle>();
                                    e.rectMemento.Store(e.Rect);
                                }
                                e.Move(moveAmount);

                                if (isShiftDown && e is Item item && targetContainer != null)
                                {
                                    if (targetContainer.OwnInventory.TryPutItem(item, Character.Controlled))
                                    {
                                        GUI.PlayUISound(GUISoundType.DropItem);
                                        deposited.Add(item);
                                    }
                                    else
                                    {
                                        GUI.PlayUISound(GUISoundType.PickItemFail);
                                    }
                                }
                                e.rectMemento.Store(e.Rect);
                            }

                            deposited.ForEach(entity => { selectedList.Remove(entity); });
                        }
                    }
                    startMovingPos = Vector2.Zero;
                }
            }
            //started dragging a "selection rectangle"
            else if (selectionPos != Vector2.Zero)
            {
                selectionSize.X = position.X - selectionPos.X;
                selectionSize.Y = selectionPos.Y - position.Y;

                List <MapEntity> newSelection = new List <MapEntity>();// FindSelectedEntities(selectionPos, selectionSize);
                if (Math.Abs(selectionSize.X) > Submarine.GridSize.X || Math.Abs(selectionSize.Y) > Submarine.GridSize.Y)
                {
                    newSelection = FindSelectedEntities(selectionPos, selectionSize);
                }
                else
                {
                    if (highLightedEntity != null)
                    {
                        if (SelectionGroups.TryGetValue(highLightedEntity, out List <MapEntity> group))
                        {
                            newSelection.AddRange(group);
                        }
                        else
                        {
                            newSelection.Add(highLightedEntity);
                        }
                    }
                }

                if (PlayerInput.PrimaryMouseButtonReleased())
                {
                    if (PlayerInput.IsCtrlDown())
                    {
                        foreach (MapEntity e in newSelection)
                        {
                            if (selectedList.Contains(e))
                            {
                                RemoveSelection(e);
                            }
                            else
                            {
                                AddSelection(e);
                            }
                        }
                    }
                    else
                    {
                        selectedList = new List <MapEntity>(newSelection);
                        //selectedList.Clear();
                        //newSelection.ForEach(e => AddSelection(e));
                        foreach (var entity in newSelection)
                        {
                            HandleDoorGapLinks(entity,
                                               onGapFound: (door, gap) =>
                            {
                                door.RefreshLinkedGap();
                                if (!selectedList.Contains(gap))
                                {
                                    selectedList.Add(gap);
                                }
                            },
                                               onDoorFound: (door, gap) =>
                            {
                                if (!selectedList.Contains(door.Item))
                                {
                                    selectedList.Add(door.Item);
                                }
                            });
                        }
                    }

                    //select wire if both items it's connected to are selected
                    var selectedItems = selectedList.Where(e => e is Item).Cast <Item>().ToList();
                    foreach (Item item in selectedItems)
                    {
                        if (item.Connections == null)
                        {
                            continue;
                        }
                        foreach (Connection c in item.Connections)
                        {
                            foreach (Wire w in c.Wires)
                            {
                                if (w == null || selectedList.Contains(w.Item))
                                {
                                    continue;
                                }

                                if (w.OtherConnection(c) != null && selectedList.Contains(w.OtherConnection(c).Item))
                                {
                                    selectedList.Add(w.Item);
                                }
                            }
                        }
                    }

                    selectionPos  = Vector2.Zero;
                    selectionSize = Vector2.Zero;
                }
            }
            //default, not doing anything specific yet
            else
            {
                if (PlayerInput.PrimaryMouseButtonHeld() &&
                    PlayerInput.KeyUp(Keys.Space) &&
                    (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn))))
                {
                    //if clicking a selected entity, start moving it
                    foreach (MapEntity e in selectedList)
                    {
                        if (e.IsMouseOn(position))
                        {
                            startMovingPos = position;
                        }
                    }
                    selectionPos = position;

                    //stop camera movement to prevent accidental dragging or rect selection
                    Screen.Selected.Cam.StopMovement();
                }
            }
        }
Пример #5
0
        private void DrawWidgets(SpriteBatch spriteBatch)
        {
            float widgetSize = Image == null ? 100f : Math.Max(Image.Width, Image.Height) / 2f;

            int width = 3;
            int size  = 32;

            if (DrawTarget == DrawTargetType.World)
            {
                width = Math.Max(width, (int)(width / Screen.Selected.Cam.Zoom));
            }

            Widget currentWidget = GetWidget("transform", size, width, widget =>
            {
                widget.MouseDown += () =>
                {
                    widget.color = GUI.Style.Green;
                    prevAngle    = Rotation;
                    disableMove  = true;
                };
                widget.Deselected += () =>
                {
                    widget.color = Color.Yellow;
                    disableMove  = false;
                };
                widget.MouseHeld += (deltaTime) =>
                {
                    Rotation       = GetRotationAngle(Position) + (float)Math.PI / 2f;
                    float distance = Vector2.Distance(Position, GetMousePos());
                    Scale          = Math.Abs(distance) / widgetSize;
                    if (PlayerInput.IsShiftDown())
                    {
                        const float rotationStep = (float)(Math.PI / 4f);
                        Rotation = (float)Math.Round(Rotation / rotationStep) * rotationStep;
                    }

                    if (PlayerInput.IsCtrlDown())
                    {
                        const float scaleStep = 0.1f;
                        Scale = (float)Math.Round(Scale / scaleStep) * scaleStep;
                    }

                    UpdateRectangle();
                };
                widget.PreUpdate += (deltaTime) =>
                {
                    if (DrawTarget != DrawTargetType.World)
                    {
                        return;
                    }

                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                    widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos);
                };
                widget.PostUpdate += (deltaTime) =>
                {
                    if (DrawTarget != DrawTargetType.World)
                    {
                        return;
                    }

                    widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos);
                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                };
                widget.PreDraw += (sprtBtch, deltaTime) =>
                {
                    widget.tooltip = $"Scale: {Math.Round(Scale, 2)}\n" +
                                     $"Rotation: {(int) MathHelper.ToDegrees(Rotation)}";
                    float rotation = Rotation - (float)Math.PI / 2f;
                    widget.DrawPos = Position + new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * (Scale * widgetSize);
                    widget.Update(deltaTime);
                };
            });

            currentWidget.Draw(spriteBatch, (float)Timing.Step);
            GUI.DrawLine(spriteBatch, Position, currentWidget.DrawPos, GUI.Style.Green, width: width);
        }
Пример #6
0
        public void Update(float deltaTime)
        {
            if (!EditorMode)
            {
                return;
            }

            foreach (EditorImage image in Images)
            {
                image.Update(deltaTime);
            }

            if (PlayerInput.PrimaryMouseButtonDown())
            {
                EditorImage?hover = Images.FirstOrDefault(img => img.IsMouseOn());
                if (hover != null)
                {
                    foreach (EditorImage image in Images)
                    {
                        image.Selected = false;
                    }

                    hover.Selected = true;
                }
            }

            if (PlayerInput.KeyHit(Keys.Delete) || (PlayerInput.IsCtrlDown() && PlayerInput.KeyHit(Keys.D)))
            {
                Images.RemoveAll(img => img.Selected);
                UpdateImageCategories();
            }

            if (PlayerInput.KeyHit(Keys.Space))
            {
                foreach (EditorImage image in Images)
                {
                    if (image.Selected)
                    {
                        if (image.DrawTarget == EditorImage.DrawTargetType.World)
                        {
                            Vector2 pos = image.Position;
                            pos.Y = -pos.Y;
                            pos   = Screen.Selected.Cam.WorldToScreen(pos);
                            if (PlayerInput.IsShiftDown())
                            {
                                pos = new Vector2(GameMain.GraphicsWidth / 2f, GameMain.GraphicsHeight / 2f);
                            }

                            image.Position   = pos;
                            image.DrawTarget = EditorImage.DrawTargetType.Camera;
                            image.Scale     *= Screen.Selected.Cam.Zoom;
                            image.UpdateRectangle();
                        }
                        else
                        {
                            Vector2 pos = Screen.Selected.Cam.ScreenToWorld(image.Position);
                            pos.Y            = -pos.Y;
                            image.Position   = pos;
                            image.DrawTarget = EditorImage.DrawTargetType.World;
                            image.Scale     /= Screen.Selected.Cam.Zoom;
                            image.UpdateRectangle();
                        }
                    }
                }

                UpdateImageCategories();
            }

            MapEntity.DisableSelect = true;
        }
Пример #7
0
        /// <summary>
        /// Update the selection logic in submarine editor
        /// </summary>
        public static void UpdateSelecting(Camera cam)
        {
            if (resizing)
            {
                if (selectedList.Count == 0)
                {
                    resizing = false;
                }
                return;
            }

            foreach (MapEntity e in mapEntityList)
            {
                e.isHighlighted = false;
            }

            if (DisableSelect)
            {
                DisableSelect = false;
                return;
            }

            if (GUI.MouseOn != null || !PlayerInput.MouseInsideWindow)
            {
                if (highlightedListBox == null ||
                    (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn)))
                {
                    UpdateHighlightedListBox(null, false);
                    return;
                }
            }

            if (MapEntityPrefab.Selected != null)
            {
                selectionPos = Vector2.Zero;
                selectedList.Clear();
                return;
            }
            if (GUI.KeyboardDispatcher.Subscriber == null)
            {
                if (PlayerInput.KeyHit(Keys.Delete))
                {
                    if (selectedList.Any())
                    {
                        SubEditorScreen.StoreCommand(new AddOrDeleteCommand(selectedList, true));
                    }
                    selectedList.ForEach(e => { if (!e.Removed)
                                                {
                                                    e.Remove();
                                                }
                                         });
                    selectedList.Clear();
                }

                if (PlayerInput.IsCtrlDown())
                {
#if DEBUG
                    if (PlayerInput.KeyHit(Keys.D))
                    {
                        bool terminate = false;
                        foreach (MapEntity entity in selectedList)
                        {
                            if (entity is Item item && item.GetComponent <Planter>() is { } planter)
                            {
                                planter.Update(1.0f, cam);
                                for (var i = 0; i < planter.GrowableSeeds.Length; i++)
                                {
                                    Growable  seed = planter.GrowableSeeds[i];
                                    PlantSlot slot = planter.PlantSlots.ContainsKey(i) ? planter.PlantSlots[i] : Planter.NullSlot;
                                    if (seed == null)
                                    {
                                        continue;
                                    }

                                    seed.CreateDebugHUD(planter, slot);
                                    terminate = true;
                                    break;
                                }
                            }

                            if (terminate)
                            {
                                break;
                            }
                        }
                    }
#endif
                    if (PlayerInput.KeyHit(Keys.C))
                    {
                        Copy(selectedList);
                    }
                    else if (PlayerInput.KeyHit(Keys.X))
                    {
                        Cut(selectedList);
                    }
                    else if (PlayerInput.KeyHit(Keys.V))
                    {
                        Paste(cam.WorldViewCenter);
                    }
                    else if (PlayerInput.KeyHit(Keys.G))
                    {
                        if (selectedList.Any())
                        {
                            if (SelectionGroups.ContainsKey(selectedList.Last()))
                            {
                                // Ungroup all selected
                                selectedList.ForEach(e => SelectionGroups.Remove(e));
                            }
                            else
                            {
                                foreach (var entity in selectedList)
                                {
                                    // Remove the old group, if any
                                    SelectionGroups.Remove(entity);
                                    // Create a group that can be accessed with any member
                                    SelectionGroups.Add(entity, selectedList);
                                }
                            }
                        }
                    }
                }
            }

            Vector2   position          = cam.ScreenToWorld(PlayerInput.MousePosition);
            MapEntity highLightedEntity = null;
            if (startMovingPos == Vector2.Zero)
            {
                List <MapEntity> highlightedEntities = new List <MapEntity>();
                if (highlightedListBox != null && highlightedListBox.IsParentOf(GUI.MouseOn))
                {
                    highLightedEntity = GUI.MouseOn.UserData as MapEntity;
                }
                else
                {
                    foreach (MapEntity e in mapEntityList)
                    {
                        if (!e.SelectableInEditor)
                        {
                            continue;
                        }

                        if (e.IsMouseOn(position))
                        {
                            int i = 0;
                            while (i < highlightedEntities.Count &&
                                   e.Sprite != null &&
                                   (highlightedEntities[i].Sprite == null || highlightedEntities[i].SpriteDepth < e.SpriteDepth))
                            {
                                i++;
                            }

                            highlightedEntities.Insert(i, e);

                            if (i == 0)
                            {
                                highLightedEntity = e;
                            }
                        }
                    }

                    UpdateHighlighting(highlightedEntities);
                }

                if (highLightedEntity != null)
                {
                    highLightedEntity.isHighlighted = true;
                }
            }

            if (GUI.KeyboardDispatcher.Subscriber == null)
            {
                int up    = PlayerInput.KeyDown(Keys.Up) ? 1 : 0,
                    down  = PlayerInput.KeyDown(Keys.Down) ? -1 : 0,
                    left  = PlayerInput.KeyDown(Keys.Left) ? -1 : 0,
                    right = PlayerInput.KeyDown(Keys.Right) ? 1 : 0;

                int xKeysDown = (left + right);
                int yKeysDown = (up + down);

                if (xKeysDown != 0 || yKeysDown != 0)
                {
                    keyDelay += (float)Timing.Step;
                }
                else
                {
                    keyDelay = 0;
                }

                Vector2 nudgeAmount = Vector2.Zero;

                if (keyDelay >= 0.5f)
                {
                    nudgeAmount.Y = yKeysDown;
                    nudgeAmount.X = xKeysDown;
                }

                if (PlayerInput.KeyHit(Keys.Up))
                {
                    nudgeAmount.Y = 1f;
                }
                if (PlayerInput.KeyHit(Keys.Down))
                {
                    nudgeAmount.Y = -1f;
                }
                if (PlayerInput.KeyHit(Keys.Left))
                {
                    nudgeAmount.X = -1f;
                }
                if (PlayerInput.KeyHit(Keys.Right))
                {
                    nudgeAmount.X = 1f;
                }
                if (nudgeAmount != Vector2.Zero)
                {
                    foreach (MapEntity entityToNudge in selectedList)
                    {
                        entityToNudge.Move(nudgeAmount);
                    }
                }
            }
            else
            {
                keyDelay = 0;
            }

            bool isShiftDown = PlayerInput.IsShiftDown();

            //started moving selected entities
            if (startMovingPos != Vector2.Zero)
            {
                Item targetContainer = GetPotentialContainer(position, selectedList);

                if (targetContainer != null)
                {
                    targetContainer.IsHighlighted = true;
                }

                if (PlayerInput.PrimaryMouseButtonReleased())
                {
                    //mouse released -> move the entities to the new position of the mouse

                    Vector2 moveAmount = position - startMovingPos;

                    if (!isShiftDown)
                    {
                        moveAmount.X = (float)(moveAmount.X > 0.0f ? Math.Floor(moveAmount.X / Submarine.GridSize.X) : Math.Ceiling(moveAmount.X / Submarine.GridSize.X)) * Submarine.GridSize.X;
                        moveAmount.Y = (float)(moveAmount.Y > 0.0f ? Math.Floor(moveAmount.Y / Submarine.GridSize.Y) : Math.Ceiling(moveAmount.Y / Submarine.GridSize.Y)) * Submarine.GridSize.Y;
                    }

                    if (Math.Abs(moveAmount.X) >= Submarine.GridSize.X || Math.Abs(moveAmount.Y) >= Submarine.GridSize.Y || isShiftDown)
                    {
                        if (!isShiftDown)
                        {
                            moveAmount = Submarine.VectorToWorldGrid(moveAmount);
                        }

                        //clone
                        if (PlayerInput.IsCtrlDown())
                        {
                            var clones = Clone(selectedList).Where(c => c != null).ToList();
                            selectedList = clones;
                            SubEditorScreen.StoreCommand(new AddOrDeleteCommand(clones, false));
                            selectedList.ForEach(c => c.Move(moveAmount));
                        }
                        else // move
                        {
                            var oldRects = selectedList.Select(e => e.Rect).ToList();
                            List <MapEntity> deposited = new List <MapEntity>();
                            foreach (MapEntity e in selectedList)
                            {
                                e.Move(moveAmount);

                                if (isShiftDown && e is Item item && targetContainer != null)
                                {
                                    if (targetContainer.OwnInventory.TryPutItem(item, Character.Controlled))
                                    {
                                        SoundPlayer.PlayUISound(GUISoundType.DropItem);
                                        deposited.Add(item);
                                    }
                                    else
                                    {
                                        SoundPlayer.PlayUISound(GUISoundType.PickItemFail);
                                    }
                                }
                            }

                            SubEditorScreen.StoreCommand(new TransformCommand(new List <MapEntity>(selectedList), selectedList.Select(entity => entity.Rect).ToList(), oldRects, false));
                            if (deposited.Any() && deposited.Any(entity => entity is Item))
                            {
                                var depositedItems = deposited.Where(entity => entity is Item).Cast <Item>().ToList();
                                SubEditorScreen.StoreCommand(new InventoryPlaceCommand(targetContainer.OwnInventory, depositedItems, false));
                            }

                            deposited.ForEach(entity => { selectedList.Remove(entity); });
                        }
                    }
                    startMovingPos = Vector2.Zero;
                }
            }
            //started dragging a "selection rectangle"
            else if (selectionPos != Vector2.Zero)
            {
                selectionSize.X = position.X - selectionPos.X;
                selectionSize.Y = selectionPos.Y - position.Y;

                List <MapEntity> newSelection = new List <MapEntity>();// FindSelectedEntities(selectionPos, selectionSize);
                if (Math.Abs(selectionSize.X) > Submarine.GridSize.X || Math.Abs(selectionSize.Y) > Submarine.GridSize.Y)
                {
                    newSelection = FindSelectedEntities(selectionPos, selectionSize);
                }
                else
                {
                    if (highLightedEntity != null)
                    {
                        if (SelectionGroups.TryGetValue(highLightedEntity, out List <MapEntity> group))
                        {
                            newSelection.AddRange(group);
                        }
                        else
                        {
                            newSelection.Add(highLightedEntity);
                        }
                    }
                }

                if (PlayerInput.PrimaryMouseButtonReleased())
                {
                    if (PlayerInput.IsCtrlDown())
                    {
                        foreach (MapEntity e in newSelection)
                        {
                            if (selectedList.Contains(e))
                            {
                                RemoveSelection(e);
                            }
                            else
                            {
                                AddSelection(e);
                            }
                        }
                    }
                    else
                    {
                        selectedList = new List <MapEntity>(newSelection);
                        //selectedList.Clear();
                        //newSelection.ForEach(e => AddSelection(e));
                        foreach (var entity in newSelection)
                        {
                            HandleDoorGapLinks(entity,
                                               onGapFound: (door, gap) =>
                            {
                                door.RefreshLinkedGap();
                                if (!selectedList.Contains(gap))
                                {
                                    selectedList.Add(gap);
                                }
                            },
                                               onDoorFound: (door, gap) =>
                            {
                                if (!selectedList.Contains(door.Item))
                                {
                                    selectedList.Add(door.Item);
                                }
                            });
                        }
                    }

                    //select wire if both items it's connected to are selected
                    var selectedItems = selectedList.Where(e => e is Item).Cast <Item>().ToList();
                    foreach (Item item in selectedItems)
                    {
                        if (item.Connections == null)
                        {
                            continue;
                        }
                        foreach (Connection c in item.Connections)
                        {
                            foreach (Wire w in c.Wires)
                            {
                                if (w == null || selectedList.Contains(w.Item))
                                {
                                    continue;
                                }

                                if (w.OtherConnection(c) != null && selectedList.Contains(w.OtherConnection(c).Item))
                                {
                                    selectedList.Add(w.Item);
                                }
                            }
                        }
                    }

                    selectionPos  = Vector2.Zero;
                    selectionSize = Vector2.Zero;
                }
            }
            //default, not doing anything specific yet
            else
            {
                if (PlayerInput.PrimaryMouseButtonHeld() &&
                    PlayerInput.KeyUp(Keys.Space) &&
                    (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn))))
                {
                    //if clicking a selected entity, start moving it
                    foreach (MapEntity e in selectedList)
                    {
                        if (e.IsMouseOn(position))
                        {
                            startMovingPos = position;
                        }
                    }
                    selectionPos = position;

                    //stop camera movement to prevent accidental dragging or rect selection
                    Screen.Selected.Cam.StopMovement();
                }
            }
        }
Пример #8
0
        public void ReceiveCommandInput(char command)
        {
            if (Text == null)
            {
                Text = "";
            }

            // Prevent alt gr from triggering any of these as that combination is often needed for special characters
            if (PlayerInput.IsAltDown())
            {
                return;
            }

            switch (command)
            {
            case '\b' when !Readonly:     //backspace
                if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
                {
                    SetText(string.Empty, false);
                    CaretIndex = Text.Length;
                }
                else if (selectedCharacters > 0)
                {
                    RemoveSelectedText();
                }
                else if (Text.Length > 0 && CaretIndex > 0)
                {
                    CaretIndex--;
                    SetText(Text.Remove(CaretIndex, 1));
                    CalculateCaretPos();
                    ClearSelection();
                }
                OnTextChanged?.Invoke(this, Text);
                break;

            case (char)0x3:     // ctrl-c
                CopySelectedText();
                break;

            case (char)0x16 when !Readonly:     // ctrl-v
                string text = GetCopiedText();
                RemoveSelectedText();
                if (SetText(Text.Insert(CaretIndex, text)))
                {
                    CaretIndex = Math.Min(Text.Length, CaretIndex + text.Length);
                    OnTextChanged?.Invoke(this, Text);
                }
                break;

            case (char)0x18:     // ctrl-x
                CopySelectedText();
                if (!Readonly)
                {
                    RemoveSelectedText();
                }
                break;

            case (char)0x1:     // ctrl-a
                if (PlayerInput.IsCtrlDown())
                {
                    SelectAll();
                }
                break;

            case (char)0x1A when !Readonly && !SubEditorScreen.IsSubEditor():     // ctrl-z
                text = memento.Undo();
                if (text != Text)
                {
                    ClearSelection();
                    SetText(text, false);
                    CaretIndex = Text.Length;
                    OnTextChanged?.Invoke(this, Text);
                }
                break;

            case (char)0x12 when !Readonly && !SubEditorScreen.IsSubEditor():     // ctrl-r
                text = memento.Redo();
                if (text != Text)
                {
                    ClearSelection();
                    SetText(text, false);
                    CaretIndex = Text.Length;
                    OnTextChanged?.Invoke(this, Text);
                }
                break;
            }
        }