public void DrawPinnedEvent(SpriteBatch spriteBatch)
        {
            if (PinnedEvent != null)
            {
                Rectangle rect = DrawEvent(spriteBatch, PinnedEvent, null);

                if (rect != Rectangle.Empty)
                {
                    if (rect.Contains(PlayerInput.MousePosition) && !isDragging)
                    {
                        GUI.MouseCursor = CursorState.Move;
                        if (PlayerInput.PrimaryMouseButtonDown() || PlayerInput.PrimaryMouseButtonHeld())
                        {
                            isDragging = true;
                        }

                        if (PlayerInput.SecondaryMouseButtonClicked() || PlayerInput.SecondaryMouseButtonHeld())
                        {
                            PinnedEvent = null;
                            isDragging  = false;
                        }
                    }
                }

                if (isDragging)
                {
                    GUI.MouseCursor = CursorState.Dragging;
                    pinnedPosition  = PlayerInput.MousePosition - (new Vector2(rect.Width / 2.0f, -24));
                    if (!PlayerInput.PrimaryMouseButtonHeld())
                    {
                        isDragging = false;
                    }
                }
            }
        }
예제 #2
0
        public override void UpdatePlacing(Camera cam)
        {
            if (PlayerInput.SecondaryMouseButtonClicked())
            {
                selected = null;
                return;
            }

            Vector2   position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub);
            Vector2   size     = ScaledSize;
            Rectangle newRect  = new Rectangle((int)position.X, (int)position.Y, (int)size.X, (int)size.Y);

            if (placePosition == Vector2.Zero)
            {
                if (PlayerInput.PrimaryMouseButtonHeld())
                {
                    placePosition = Submarine.MouseToWorldGrid(cam, Submarine.MainSub);
                }

                newRect.X = (int)position.X;
                newRect.Y = (int)position.Y;
            }
            else
            {
                Vector2 placeSize = size;
                if (ResizeHorizontal)
                {
                    placeSize.X = position.X - placePosition.X;
                }
                if (ResizeVertical)
                {
                    placeSize.Y = placePosition.Y - position.Y;
                }

                //don't allow resizing width/height to less than the grid size
                if (ResizeHorizontal && Math.Abs(placeSize.X) < Submarine.GridSize.X)
                {
                    placeSize.X = Submarine.GridSize.X;
                }
                if (ResizeVertical && Math.Abs(placeSize.Y) < Submarine.GridSize.Y)
                {
                    placeSize.Y = Submarine.GridSize.Y;
                }

                newRect = Submarine.AbsRect(placePosition, placeSize);
                if (PlayerInput.PrimaryMouseButtonReleased())
                {
                    newRect.Location -= MathUtils.ToPoint(Submarine.MainSub.Position);
                    new Structure(newRect, this, Submarine.MainSub)
                    {
                        Submarine = Submarine.MainSub
                    };

                    selected = null;
                    return;
                }
            }
        }
예제 #3
0
        protected override void Update(float deltaTime)
        {
            if (!Visible)
            {
                return;
            }
            base.Update(deltaTime);
            if (Rect.Contains(PlayerInput.MousePosition) && CanBeSelected && CanBeFocused && Enabled && GUI.IsMouseOn(this))
            {
                State = Selected ?
                        ComponentState.HoverSelected :
                        ComponentState.Hover;
                if (PlayerInput.PrimaryMouseButtonDown())
                {
                    OnButtonDown?.Invoke();
                }
                if (PlayerInput.PrimaryMouseButtonHeld())
                {
                    if (OnPressed != null)
                    {
                        if (OnPressed())
                        {
                            State = ComponentState.Pressed;
                        }
                    }
                    else
                    {
                        State = ComponentState.Pressed;
                    }
                }
                else if (PlayerInput.PrimaryMouseButtonClicked())
                {
                    GUI.PlayUISound(GUISoundType.Click);
                    if (OnClicked != null)
                    {
                        if (OnClicked(this, UserData))
                        {
                            State = ComponentState.Selected;
                        }
                    }
                    else
                    {
                        Selected = !Selected;
                    }
                }
            }
            else
            {
                State = Selected ? ComponentState.Selected : ComponentState.None;
            }

            foreach (GUIComponent child in Children)
            {
                child.State = State;
            }
        }
예제 #4
0
        public void Update(float deltaTime)
        {
            if (!Selected)
            {
                return;
            }

            if (widgets.Values.Any(w => w.IsSelected))
            {
                return;
            }

            if (PlayerInput.PrimaryMouseButtonDown() && !disableMove && IsMouseOn())
            {
                isDragging = true;
            }

            if (isDragging)
            {
                Camera cam = Screen.Selected.Cam;
                if (PlayerInput.MouseSpeed != Vector2.Zero)
                {
                    Vector2 mouseSpeed = PlayerInput.MouseSpeed;
                    if (DrawTarget == DrawTargetType.World)
                    {
                        mouseSpeed /= cam.Zoom;
                    }

                    Position += mouseSpeed;
                    UpdateRectangle();
                }
            }

            if (PlayerInput.KeyDown(Keys.OemPlus) || PlayerInput.KeyDown(Keys.Up))
            {
                Opacity += 0.01f;
            }

            if (PlayerInput.KeyDown(Keys.OemMinus) || PlayerInput.KeyDown(Keys.Down))
            {
                Opacity -= 0.01f;
            }

            if (PlayerInput.KeyHit(Keys.D0))
            {
                Opacity = 1f;
            }

            Opacity = Math.Clamp(Opacity, 0, 1f);

            if (!PlayerInput.PrimaryMouseButtonHeld())
            {
                isDragging = false;
            }
        }
        public virtual void UpdatePlacing(Camera cam)
        {
            if (PlayerInput.SecondaryMouseButtonClicked())
            {
                selected = null;
                return;
            }

            Vector2 placeSize = Submarine.GridSize;

            if (placePosition == Vector2.Zero)
            {
                Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub);

                if (PlayerInput.PrimaryMouseButtonHeld())
                {
                    placePosition = position;
                }
            }
            else
            {
                Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub);

                if (ResizeHorizontal)
                {
                    placeSize.X = position.X - placePosition.X;
                }
                if (ResizeVertical)
                {
                    placeSize.Y = placePosition.Y - position.Y;
                }

                Rectangle newRect = Submarine.AbsRect(placePosition, placeSize);
                newRect.Width  = (int)Math.Max(newRect.Width, Submarine.GridSize.X);
                newRect.Height = (int)Math.Max(newRect.Height, Submarine.GridSize.Y);

                if (Submarine.MainSub != null)
                {
                    newRect.Location -= MathUtils.ToPoint(Submarine.MainSub.Position);
                }

                if (PlayerInput.PrimaryMouseButtonReleased())
                {
                    CreateInstance(newRect);
                    placePosition = Vector2.Zero;
                    if (!PlayerInput.IsShiftDown())
                    {
                        selected = null;
                    }
                }

                newRect.Y = -newRect.Y;
            }
        }
예제 #6
0
        partial void UpdateProjSpecific(double deltaTime)
        {
            if (ConversationAction.FadeScreenToBlack)
            {
                fadeToBlackState = Math.Min(fadeToBlackState + (float)deltaTime, 1.0f);
            }
            else
            {
                fadeToBlackState = Math.Max(fadeToBlackState - (float)deltaTime, 0.0f);
            }

            if (!PlayerInput.PrimaryMouseButtonHeld())
            {
                Inventory.DraggingSlot = null;
                Inventory.DraggingItems.Clear();
            }
        }
예제 #7
0
 public virtual void Update(float deltaTime)
 {
     PreUpdate?.Invoke(deltaTime);
     if (!enabled)
     {
         return;
     }
     if (IsMouseOver || (!RequireMouseOn && selectedWidgets.Contains(this) && PlayerInput.PrimaryMouseButtonHeld()))
     {
         Hovered?.Invoke();
         System.Diagnostics.Debug.WriteLine("hovered");
         if (RequireMouseOn || PlayerInput.PrimaryMouseButtonDown())
         {
             if ((multiselect && !selectedWidgets.Contains(this)) || selectedWidgets.None())
             {
                 selectedWidgets.Add(this);
                 Selected?.Invoke();
             }
         }
     }
     else if (selectedWidgets.Contains(this))
     {
         System.Diagnostics.Debug.WriteLine("selectedWidgets.Contains(this) -> remove");
         selectedWidgets.Remove(this);
         Deselected?.Invoke();
     }
     if (IsSelected)
     {
         if (PlayerInput.PrimaryMouseButtonDown())
         {
             MouseDown?.Invoke();
         }
         if (PlayerInput.PrimaryMouseButtonHeld())
         {
             MouseHeld?.Invoke(deltaTime);
         }
         if (PlayerInput.PrimaryMouseButtonClicked())
         {
             MouseUp?.Invoke();
         }
     }
     PostUpdate?.Invoke(deltaTime);
 }
예제 #8
0
        protected override void Update(float deltaTime)
        {
            if (!Visible)
            {
                return;
            }

            base.Update(deltaTime);

            if (GUI.MouseOn == this && Enabled)
            {
                State = Selected ?
                        ComponentState.HoverSelected :
                        ComponentState.Hover;

                if (PlayerInput.PrimaryMouseButtonHeld())
                {
                    State = ComponentState.Selected;
                }

                if (PlayerInput.PrimaryMouseButtonClicked())
                {
                    if (radioButtonGroup == null)
                    {
                        Selected = !Selected;
                    }
                    else if (!selected)
                    {
                        Selected = true;
                    }
                }
            }
            else if (selected)
            {
                State = ComponentState.Selected;
            }
            else
            {
                State = ComponentState.None;
            }
        }
예제 #9
0
        public override void Update(double deltaTime)
        {
            cam.MoveCamera((float)deltaTime, allowMove: true, allowZoom: GUI.MouseOn == null);

            if (GUI.MouseOn is null && PlayerInput.PrimaryMouseButtonHeld())
            {
                sizeRefPosition = cam.ScreenToWorld(PlayerInput.MousePosition);
            }

            if (PlayerInput.SecondaryMouseButtonClicked())
            {
                CreateContextMenu();
            }

            if (selectedPrefab != null && emitter != null)
            {
                emitter.Emit((float)deltaTime, Vector2.Zero);
            }

            GameMain.ParticleManager.Update((float)deltaTime);
        }
예제 #10
0
        public bool IsDown()
        {
            switch (MouseButton)
            {
            case MouseButton.None:
                return(PlayerInput.KeyDown(Key));

            case MouseButton.PrimaryMouse:
                return(PlayerInput.PrimaryMouseButtonHeld());

            case MouseButton.SecondaryMouse:
                return(PlayerInput.SecondaryMouseButtonHeld());

            case MouseButton.LeftMouse:
                return(PlayerInput.LeftButtonHeld());

            case MouseButton.RightMouse:
                return(PlayerInput.RightButtonHeld());

            case MouseButton.MiddleMouse:
                return(PlayerInput.MidButtonHeld());

            case MouseButton.MouseButton4:
                return(PlayerInput.Mouse4ButtonHeld());

            case MouseButton.MouseButton5:
                return(PlayerInput.Mouse5ButtonHeld());

            case MouseButton.MouseWheelUp:     // No real way of "holding" a mouse wheel key, but then again it makes no sense to bind the key to this kind of task.
                return(PlayerInput.MouseWheelUpClicked());

            case MouseButton.MouseWheelDown:
                return(PlayerInput.MouseWheelDownClicked());
            }

            return(false);
        }
예제 #11
0
        protected override void Update(float deltaTime)
        {
            if (!Visible)
            {
                return;
            }

            if (flashTimer > 0.0f)
            {
                flashTimer -= deltaTime;
            }
            if (!Enabled)
            {
                return;
            }

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

            if (MouseRect.Contains(PlayerInput.MousePosition) && (GUI.MouseOn == null || (!(GUI.MouseOn is GUIButton) && GUI.IsMouseOn(this))))
            {
                State = ComponentState.Hover;
                if (PlayerInput.PrimaryMouseButtonDown())
                {
                    mouseHeldInside = true;
                    Select();
                }
                else
                {
                    isSelecting = PlayerInput.PrimaryMouseButtonHeld();
                }
                if (PlayerInput.DoubleClicked())
                {
                    SelectAll();
                }
                if (isSelecting)
                {
                    if (!MathUtils.NearlyEqual(PlayerInput.MouseSpeed.X, 0))
                    {
                        CaretIndex = textBlock.GetCaretIndexFromScreenPos(PlayerInput.MousePosition);
                        CalculateCaretPos();
                        CalculateSelection();
                    }
                }
            }
            else
            {
                if ((PlayerInput.LeftButtonClicked() || PlayerInput.RightButtonClicked()) && selected)
                {
                    if (!mouseHeldInside)
                    {
                        Deselect();
                    }
                    mouseHeldInside = false;
                }
                isSelecting = false;
                State       = ComponentState.None;
            }
            if (!isSelecting)
            {
                isSelecting = PlayerInput.KeyDown(Keys.LeftShift) || PlayerInput.KeyDown(Keys.RightShift);
            }

            if (CaretEnabled)
            {
                if (textBlock.OverflowClipActive)
                {
                    if (CaretScreenPos.X < textBlock.Rect.X + textBlock.Padding.X)
                    {
                        textBlock.TextPos = new Vector2(textBlock.TextPos.X + ((textBlock.Rect.X + textBlock.Padding.X) - CaretScreenPos.X), textBlock.TextPos.Y);
                        CalculateCaretPos();
                    }
                    else if (CaretScreenPos.X > textBlock.Rect.Right - textBlock.Padding.Z)
                    {
                        textBlock.TextPos = new Vector2(textBlock.TextPos.X - (CaretScreenPos.X - (textBlock.Rect.Right - textBlock.Padding.Z)), textBlock.TextPos.Y);
                        CalculateCaretPos();
                    }
                }
                caretTimer  += deltaTime;
                caretVisible = ((caretTimer * 1000.0f) % 1000) < 500;
                if (caretVisible && caretPosDirty)
                {
                    CalculateCaretPos();
                }
            }

            if (GUI.KeyboardDispatcher.Subscriber == this)
            {
                State = ComponentState.Selected;
                Character.DisableControls = true;
                if (OnEnterPressed != null && PlayerInput.KeyHit(Keys.Enter))
                {
                    OnEnterPressed(this, Text);
                }
            }
            else if (Selected)
            {
                Deselect();
            }

            textBlock.State = State;
        }
예제 #12
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);
        }
예제 #13
0
        protected override void Update(float deltaTime)
        {
            if (!Visible)
            {
                return;
            }

            if (!enabled)
            {
                return;
            }

            Frame.State = GUI.MouseOn == Frame ? ComponentState.Hover : ComponentState.None;
            if (Frame.State == ComponentState.Hover && PlayerInput.PrimaryMouseButtonHeld())
            {
                Frame.State = ComponentState.Pressed;
            }

            if (IsBooleanSwitch &&
                (!PlayerInput.PrimaryMouseButtonHeld() || (GUI.MouseOn != this && !IsParentOf(GUI.MouseOn))))
            {
                int dir = Math.Sign(barScroll - (minValue + maxValue) / 2.0f);
                if (dir == 0)
                {
                    dir = 1;
                }
                if ((barScroll <= maxValue && dir > 0) ||
                    (barScroll > minValue && dir < 0))
                {
                    BarScroll += dir * 0.1f;
                }
            }

            if (DraggingBar == this)
            {
                GUI.ForceMouseOn(this);
                if (dragStartPos == null)
                {
                    dragStartPos = PlayerInput.MousePosition;
                }

                if (!PlayerInput.PrimaryMouseButtonHeld())
                {
                    if (IsBooleanSwitch && GUI.MouseOn == Bar && Vector2.Distance(dragStartPos.Value, PlayerInput.MousePosition) < 5)
                    {
                        BarScroll = BarScroll > 0.5f ? 0.0f : 1.0f;
                        OnMoved?.Invoke(this, BarScroll);
                    }
                    OnReleased?.Invoke(this, BarScroll);
                    DraggingBar  = null;
                    dragStartPos = null;
                }
                if ((isHorizontal && PlayerInput.MousePosition.X > Rect.X && PlayerInput.MousePosition.X < Rect.Right) ||
                    (!isHorizontal && PlayerInput.MousePosition.Y > Rect.Y && PlayerInput.MousePosition.Y < Rect.Bottom))
                {
                    MoveButton(PlayerInput.MouseSpeed);
                }
            }
            else if (GUI.MouseOn == Frame)
            {
                if (PlayerInput.PrimaryMouseButtonClicked())
                {
                    DraggingBar?.OnReleased?.Invoke(DraggingBar, DraggingBar.BarScroll);
                    if (IsBooleanSwitch)
                    {
                        MoveButton(new Vector2(
                                       Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Rect.Width,
                                       Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Rect.Height));
                    }
                    else
                    {
                        MoveButton(new Vector2(
                                       Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Bar.Rect.Width,
                                       Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Bar.Rect.Height));
                    }
                }
            }
        }
예제 #14
0
        public override void UpdatePlacing(Camera cam)
        {
            Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub);

            if (PlayerInput.SecondaryMouseButtonClicked())
            {
                selected = null;
                return;
            }

            var potentialContainer = MapEntity.GetPotentialContainer(position);

            if (!ResizeHorizontal && !ResizeVertical)
            {
                if (PlayerInput.PrimaryMouseButtonClicked())
                {
                    var item = new Item(new Rectangle((int)position.X, (int)position.Y, (int)(sprite.size.X * Scale), (int)(sprite.size.Y * Scale)), this, Submarine.MainSub)
                    {
                        Submarine = Submarine.MainSub
                    };
                    item.SetTransform(ConvertUnits.ToSimUnits(Submarine.MainSub == null ? item.Position : item.Position - Submarine.MainSub.Position), 0.0f);
                    item.FindHull();
                    item.Submarine = Submarine.MainSub;

                    if (PlayerInput.IsShiftDown())
                    {
                        if (potentialContainer?.OwnInventory?.TryPutItem(item, Character.Controlled) ?? false)
                        {
                            SoundPlayer.PlayUISound(GUISoundType.PickItem);
                        }
                    }

                    SubEditorScreen.StoreCommand(new AddOrDeleteCommand(new List <MapEntity> {
                        item
                    }, false));

                    placePosition = Vector2.Zero;
                    return;
                }
            }
            else
            {
                Vector2 placeSize = size * Scale;

                if (placePosition == Vector2.Zero)
                {
                    if (PlayerInput.PrimaryMouseButtonHeld())
                    {
                        placePosition = position;
                    }
                }
                else
                {
                    if (ResizeHorizontal)
                    {
                        placeSize.X = Math.Max(position.X - placePosition.X, size.X);
                    }
                    if (ResizeVertical)
                    {
                        placeSize.Y = Math.Max(placePosition.Y - position.Y, size.Y);
                    }

                    if (PlayerInput.PrimaryMouseButtonReleased())
                    {
                        var item = new Item(new Rectangle((int)placePosition.X, (int)placePosition.Y, (int)placeSize.X, (int)placeSize.Y), this, Submarine.MainSub);
                        placePosition = Vector2.Zero;

                        item.Submarine = Submarine.MainSub;
                        item.SetTransform(ConvertUnits.ToSimUnits(Submarine.MainSub == null ? item.Position : item.Position - Submarine.MainSub.Position), 0.0f);
                        item.FindHull();

                        //selected = null;
                        return;
                    }

                    position = placePosition;
                }
            }

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


            //if (PlayerInput.GetMouseState.RightButton == ButtonState.Pressed) selected = null;
        }
        protected override void Update(float deltaTime)
        {
            if (Draggable)
            {
                GUIComponent parent = GUI.MouseOn?.Parent?.Parent;
                if ((GUI.MouseOn == InnerFrame || InnerFrame.IsParentOf(GUI.MouseOn)) && !(GUI.MouseOn is GUIButton || GUI.MouseOn is GUIColorPicker || GUI.MouseOn is GUITextBox || parent is GUITextBox))
                {
                    GUI.MouseCursor = CursorState.Move;
                    if (PlayerInput.PrimaryMouseButtonDown())
                    {
                        DraggingPosition = RectTransform.ScreenSpaceOffset.ToVector2() - PlayerInput.MousePosition;
                    }
                }

                if (PlayerInput.PrimaryMouseButtonHeld() && DraggingPosition != Vector2.Zero)
                {
                    GUI.MouseCursor = CursorState.Dragging;
                    RectTransform.ScreenSpaceOffset = (PlayerInput.MousePosition + DraggingPosition).ToPoint();
                }
                else
                {
                    DraggingPosition = Vector2.Zero;
                }
            }

            if (type == Type.InGame)
            {
                Vector2 initialPos = new Vector2(0.0f, GameMain.GraphicsHeight);
                Vector2 defaultPos = new Vector2(0.0f, HUDLayoutSettings.InventoryAreaLower.Y - InnerFrame.Rect.Height - 20 * GUI.Scale);
                Vector2 endPos     = new Vector2(GameMain.GraphicsWidth, defaultPos.Y);

                if (!closing)
                {
                    Point step = Vector2.SmoothStep(initialPos, defaultPos, openState).ToPoint();
                    InnerFrame.RectTransform.AbsoluteOffset = step;
                    if (BackgroundIcon != null)
                    {
                        BackgroundIcon.RectTransform.AbsoluteOffset = new Point(InnerFrame.Rect.Location.X - (int)(BackgroundIcon.Rect.Size.X / 1.25f), (int)defaultPos.Y - BackgroundIcon.Rect.Size.Y / 2);
                        if (!MathUtils.NearlyEqual(openState, 1.0f))
                        {
                            BackgroundIcon.Color = ToolBox.GradientLerp(openState, Color.Transparent, Color.White);
                        }
                    }
                    if (!(Screen.Selected is RoundSummaryScreen) && !MessageBoxes.Any(mb => mb.UserData is RoundSummary))
                    {
                        openState = Math.Min(openState + deltaTime * 2.0f, 1.0f);
                    }

                    if (GUI.MouseOn != InnerFrame && !InnerFrame.IsParentOf(GUI.MouseOn) && AutoClose)
                    {
                        inGameCloseTimer += deltaTime;
                    }

                    if (inGameCloseTimer >= inGameCloseTime)
                    {
                        Close();
                    }
                }
                else
                {
                    openState += deltaTime * 2.0f;
                    Point step = Vector2.SmoothStep(defaultPos, endPos, openState - 1.0f).ToPoint();
                    InnerFrame.RectTransform.AbsoluteOffset = step;
                    if (BackgroundIcon != null)
                    {
                        BackgroundIcon.Color *= 0.9f;
                    }
                    if (openState >= 2.0f)
                    {
                        if (Parent != null)
                        {
                            Parent.RemoveChild(this);
                        }
                        if (MessageBoxes.Contains(this))
                        {
                            MessageBoxes.Remove(this);
                        }
                    }
                }

                if (newBackgroundIcon != null)
                {
                    if (!iconSwitching)
                    {
                        if (BackgroundIcon != null)
                        {
                            BackgroundIcon.Color *= 0.9f;
                            if (BackgroundIcon.Color.A == 0)
                            {
                                BackgroundIcon = null;
                                iconSwitching  = true;
                                RemoveChild(BackgroundIcon);
                            }
                        }
                        else
                        {
                            iconSwitching = true;
                        }
                        iconState = 0;
                    }
                    else
                    {
                        newBackgroundIcon.SetAsFirstChild();
                        newBackgroundIcon.RectTransform.AbsoluteOffset = new Point(InnerFrame.Rect.Location.X - (int)(newBackgroundIcon.Rect.Size.X / 1.25f), (int)defaultPos.Y - newBackgroundIcon.Rect.Size.Y / 2);
                        newBackgroundIcon.Color = ToolBox.GradientLerp(iconState, Color.Transparent, Color.White);
                        if (newBackgroundIcon.Color.A == 255)
                        {
                            BackgroundIcon = newBackgroundIcon;
                            BackgroundIcon.SetAsFirstChild();
                            newBackgroundIcon = null;
                            iconSwitching     = false;
                        }

                        iconState = Math.Min(iconState + deltaTime * 2.0f, 1.0f);
                    }
                }
            }
        }
예제 #16
0
        private void UpdateChildrenRect()
        {
            //dragging
            if (CanDragElements && draggedElement != null)
            {
                if (!PlayerInput.PrimaryMouseButtonHeld())
                {
                    OnRearranged?.Invoke(this, draggedElement.UserData);
                    draggedElement = null;
                    RepositionChildren();
                }
                else
                {
                    draggedElement.RectTransform.AbsoluteOffset = isHorizontal ?
                                                                  draggedReferenceOffset + new Point((int)PlayerInput.MousePosition.X - draggedReferenceRectangle.Center.X, 0) :
                                                                  draggedReferenceOffset + new Point(0, (int)PlayerInput.MousePosition.Y - draggedReferenceRectangle.Center.Y);

                    int index     = Content.RectTransform.GetChildIndex(draggedElement.RectTransform);
                    int currIndex = index;

                    if (isHorizontal)
                    {
                        while (currIndex > 0 && PlayerInput.MousePosition.X < draggedReferenceRectangle.Left)
                        {
                            currIndex--;
                            draggedReferenceRectangle.X -= draggedReferenceRectangle.Width;
                            draggedReferenceOffset.X    -= draggedReferenceRectangle.Width;
                        }
                        while (currIndex < Content.CountChildren - 1 && PlayerInput.MousePosition.X > draggedReferenceRectangle.Right)
                        {
                            currIndex++;
                            draggedReferenceRectangle.X += draggedReferenceRectangle.Width;
                            draggedReferenceOffset.X    += draggedReferenceRectangle.Width;
                        }
                    }
                    else
                    {
                        while (currIndex > 0 && PlayerInput.MousePosition.Y < draggedReferenceRectangle.Top)
                        {
                            currIndex--;
                            draggedReferenceRectangle.Y -= draggedReferenceRectangle.Height;
                            draggedReferenceOffset.Y    -= draggedReferenceRectangle.Height;
                        }
                        while (currIndex < Content.CountChildren - 1 && PlayerInput.MousePosition.Y > draggedReferenceRectangle.Bottom)
                        {
                            currIndex++;
                            draggedReferenceRectangle.Y += draggedReferenceRectangle.Height;
                            draggedReferenceOffset.Y    += draggedReferenceRectangle.Height;
                        }
                    }

                    if (currIndex != index)
                    {
                        draggedElement.RectTransform.RepositionChildInHierarchy(currIndex);
                    }

                    return;
                }
            }

            if (SelectTop)
            {
                foreach (GUIComponent child in Content.Children)
                {
                    child.CanBeFocused = !selected.Contains(child);
                    if (!child.CanBeFocused)
                    {
                        child.State = ComponentState.None;
                    }
                }
            }

            if (SelectTop && Content.Children.Any() && scrollToElement == null)
            {
                GUIComponent component = Content.Children.FirstOrDefault(c => (c.Rect.Y - Content.Rect.Y) / (float)c.Rect.Height > -0.1f);

                if (component != null && !selected.Contains(component))
                {
                    int index = Content.Children.ToList().IndexOf(component);
                    if (index >= 0)
                    {
                        Select(index, false, false, takeKeyBoardFocus: true);
                    }
                }
            }

            for (int i = 0; i < Content.CountChildren; i++)
            {
                var child = Content.RectTransform.GetChild(i)?.GUIComponent;
                if (child == null || !child.Visible)
                {
                    continue;
                }

                // selecting
                if (Enabled && CanBeFocused && child.CanBeFocused && child.Rect.Contains(PlayerInput.MousePosition) && GUI.IsMouseOn(child))
                {
                    child.State = ComponentState.Hover;

                    var mouseDown = useMouseDownToSelect ? PlayerInput.PrimaryMouseButtonDown() : PlayerInput.PrimaryMouseButtonClicked();

                    if (mouseDown)
                    {
                        if (SelectTop)
                        {
                            ScrollToElement(child);
                            Select(i, autoScroll: false, takeKeyBoardFocus: true);
                        }
                        else
                        {
                            Select(i, autoScroll: false, takeKeyBoardFocus: true);
                        }
                    }

                    if (CanDragElements && PlayerInput.PrimaryMouseButtonDown() && GUI.MouseOn == child)
                    {
                        draggedElement            = child;
                        draggedReferenceRectangle = child.Rect;
                        draggedReferenceOffset    = child.RectTransform.AbsoluteOffset;
                    }
                }
                else if (selected.Contains(child))
                {
                    child.State = ComponentState.Selected;

                    if (CheckSelected != null)
                    {
                        if (CheckSelected() != child.UserData)
                        {
                            selected.Remove(child);
                        }
                    }
                }
                else
                {
                    child.State = !child.ExternalHighlight ? ComponentState.None : ComponentState.Hover;
                }
            }
        }
예제 #17
0
        partial void UpdateProjSpecific(float deltaTime, Camera cam)
        {
            serverUpdateDelay -= deltaTime;
            if (serverUpdateDelay <= 0.0f)
            {
                ApplyRemoteState();
            }

            if (networkUpdatePending)
            {
                networkUpdateTimer += deltaTime;
                if (networkUpdateTimer > 0.2f)
                {
                    if (!pendingSectionUpdates.Any() && !pendingDecalUpdates.Any())
                    {
                        GameMain.NetworkMember?.CreateEntityEvent(this);
                    }
                    foreach (Decal decal in pendingDecalUpdates)
                    {
                        GameMain.NetworkMember?.CreateEntityEvent(this, new object[] { decal });
                    }
                    foreach (int pendingSectionUpdate in pendingSectionUpdates)
                    {
                        GameMain.NetworkMember?.CreateEntityEvent(this, new object[] { pendingSectionUpdate });
                    }
                    pendingSectionUpdates.Clear();
                    networkUpdatePending = false;
                    networkUpdateTimer   = 0.0f;
                }
            }

            if (!IdFreed)
            {
                if (EditWater)
                {
                    Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
                    if (Submarine.RectContains(WorldRect, position))
                    {
                        if (PlayerInput.PrimaryMouseButtonHeld())
                        {
                            WaterVolume         += 1500.0f;
                            networkUpdatePending = true;
                            serverUpdateDelay    = 0.5f;
                        }
                        else if (PlayerInput.SecondaryMouseButtonHeld())
                        {
                            WaterVolume         -= 1500.0f;
                            networkUpdatePending = true;
                            serverUpdateDelay    = 0.5f;
                        }
                    }
                }
                else if (EditFire)
                {
                    Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
                    if (Submarine.RectContains(WorldRect, position))
                    {
                        if (PlayerInput.PrimaryMouseButtonClicked())
                        {
                            new FireSource(position, this, isNetworkMessage: true);
                            networkUpdatePending = true;
                            serverUpdateDelay    = 0.5f;
                        }
                    }
                }
            }

            if (waterVolume < 1.0f)
            {
                return;
            }
            for (int i = 1; i < waveY.Length - 1; i++)
            {
                float maxDelta = Math.Max(Math.Abs(rightDelta[i]), Math.Abs(leftDelta[i]));
                if (maxDelta > 1.0f && maxDelta > Rand.Range(1.0f, 10.0f))
                {
                    var particlePos = new Vector2(rect.X + WaveWidth * i, surface + waveY[i]);
                    if (Submarine != null)
                    {
                        particlePos += Submarine.Position;
                    }

                    GameMain.ParticleManager.CreateParticle("mist",
                                                            particlePos,
                                                            new Vector2(0.0f, -50.0f), 0.0f, this);
                }
            }
        }
예제 #18
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();
                }
            }
        }
예제 #19
0
        public void Update(float deltaTime, GUICustomComponent mapContainer)
        {
            Rectangle rect = mapContainer.Rect;

            if (CurrentDisplayLocation != null)
            {
                if (!CurrentDisplayLocation.Discovered)
                {
                    RemoveFogOfWar(CurrentDisplayLocation);
                    CurrentDisplayLocation.Discovered = true;
                    if (CurrentDisplayLocation.MapPosition.X > furthestDiscoveredLocation.MapPosition.X)
                    {
                        furthestDiscoveredLocation = CurrentDisplayLocation;
                    }
                }
            }

            currLocationIndicatorPos = Vector2.Lerp(currLocationIndicatorPos, CurrentDisplayLocation.MapPosition, deltaTime);
#if DEBUG
            if (GameMain.DebugDraw)
            {
                if (editor == null)
                {
                    CreateEditor();
                }
                editor.AddToGUIUpdateList(order: 1);
            }
#endif

            if (mapAnimQueue.Count > 0)
            {
                hudVisibility = Math.Max(hudVisibility - deltaTime, 0.0f);
                UpdateMapAnim(mapAnimQueue.Peek(), deltaTime);
                if (mapAnimQueue.Peek().Finished)
                {
                    mapAnimQueue.Dequeue();
                }
                return;
            }

            hudVisibility = Math.Min(hudVisibility + deltaTime, 0.75f + (float)Math.Sin(Timing.TotalTime * 3.0f) * 0.25f);

            Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y);
            Vector2 viewOffset = DrawOffset + drawOffsetNoise;

            float closestDist = 0.0f;
            HighlightedLocation = null;
            if (GUI.MouseOn == null || GUI.MouseOn == mapContainer)
            {
                for (int i = 0; i < Locations.Count; i++)
                {
                    Location location = Locations[i];
                    if (IsInFogOfWar(location) && !(CurrentDisplayLocation?.Connections.Any(c => c.Locations.Contains(location)) ?? false) && !GameMain.DebugDraw)
                    {
                        continue;
                    }

                    Vector2 pos = rectCenter + (location.MapPosition + viewOffset) * zoom;
                    if (!rect.Contains(pos))
                    {
                        continue;
                    }

                    float iconScale = generationParams.LocationIconSize / location.Type.Sprite.size.X;
                    if (location == CurrentDisplayLocation)
                    {
                        iconScale *= 1.2f;
                    }

                    Rectangle drawRect = location.Type.Sprite.SourceRect;
                    drawRect.Width  = (int)(drawRect.Width * iconScale * zoom * 1.4f);
                    drawRect.Height = (int)(drawRect.Height * iconScale * zoom * 1.4f);
                    drawRect.X      = (int)pos.X - drawRect.Width / 2;
                    drawRect.Y      = (int)pos.Y - drawRect.Width / 2;

                    if (!drawRect.Contains(PlayerInput.MousePosition))
                    {
                        continue;
                    }

                    float dist = Vector2.Distance(PlayerInput.MousePosition, pos);
                    if (HighlightedLocation == null || dist < closestDist)
                    {
                        closestDist         = dist;
                        HighlightedLocation = location;
                    }
                }
            }

            if (GUI.KeyboardDispatcher.Subscriber == null)
            {
                float   moveSpeed  = 1000.0f;
                Vector2 moveAmount = Vector2.Zero;
                if (PlayerInput.KeyDown(InputType.Left))
                {
                    moveAmount += Vector2.UnitX;
                }
                if (PlayerInput.KeyDown(InputType.Right))
                {
                    moveAmount -= Vector2.UnitX;
                }
                if (PlayerInput.KeyDown(InputType.Up))
                {
                    moveAmount += Vector2.UnitY;
                }
                if (PlayerInput.KeyDown(InputType.Down))
                {
                    moveAmount -= Vector2.UnitY;
                }
                DrawOffset += moveAmount * moveSpeed / zoom * deltaTime;
            }

            targetZoom = MathHelper.Clamp(targetZoom, generationParams.MinZoom, generationParams.MaxZoom);
            zoom       = MathHelper.Lerp(zoom, targetZoom, 0.1f);

            if (GUI.MouseOn == mapContainer)
            {
                foreach (LocationConnection connection in Connections)
                {
                    if (HighlightedLocation != CurrentDisplayLocation &&
                        connection.Locations.Contains(HighlightedLocation) && connection.Locations.Contains(CurrentDisplayLocation))
                    {
                        if (PlayerInput.PrimaryMouseButtonClicked() &&
                            SelectedLocation != HighlightedLocation && HighlightedLocation != null)
                        {
                            //clients aren't allowed to select the location without a permission
                            if ((GameMain.GameSession?.GameMode as CampaignMode)?.AllowedToManageCampaign() ?? false)
                            {
                                SelectedConnection = connection;
                                SelectedLocation   = HighlightedLocation;

                                OnLocationSelected?.Invoke(SelectedLocation, SelectedConnection);
                                GameMain.Client?.SendCampaignState();
                            }
                        }
                    }
                }

                targetZoom += PlayerInput.ScrollWheelSpeed / 500.0f;

                if (PlayerInput.MidButtonHeld() || (HighlightedLocation == null && PlayerInput.PrimaryMouseButtonHeld()))
                {
                    DrawOffset += PlayerInput.MouseSpeed / zoom;
                }
                if (AllowDebugTeleport)
                {
                    if (PlayerInput.DoubleClicked() && HighlightedLocation != null)
                    {
                        var passedConnection = CurrentDisplayLocation.Connections.Find(c => c.OtherLocation(CurrentDisplayLocation) == HighlightedLocation);
                        if (passedConnection != null)
                        {
                            passedConnection.Passed = true;
                        }

                        Location prevLocation = CurrentDisplayLocation;
                        CurrentLocation = HighlightedLocation;
                        Level.Loaded.DebugSetStartLocation(CurrentLocation);
                        Level.Loaded.DebugSetEndLocation(null);

                        CurrentLocation.Discovered = true;
                        CurrentLocation.CreateStore();
                        OnLocationChanged?.Invoke(prevLocation, CurrentLocation);
                        SelectLocation(-1);
                        if (GameMain.Client == null)
                        {
                            ProgressWorld();
                        }
                        else
                        {
                            GameMain.Client.SendCampaignState();
                        }
                    }

                    if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.LeftShift) && PlayerInput.PrimaryMouseButtonClicked() && HighlightedLocation != null)
                    {
                        int distance = DistanceToClosestLocationWithOutpost(HighlightedLocation, out Location foundLocation);
                        DebugConsole.NewMessage($"Distance to closest outpost from {HighlightedLocation.Name} to {foundLocation?.Name} is {distance}");
                    }

                    if (PlayerInput.PrimaryMouseButtonClicked() && HighlightedLocation == null)
                    {
                        SelectLocation(-1);
                    }
                }
            }
        }
예제 #20
0
        protected override void Update(float deltaTime)
        {
            if (!Visible)
            {
                return;
            }
            base.Update(deltaTime);
            if (Rect.Contains(PlayerInput.MousePosition) && CanBeSelected && CanBeFocused && Enabled && GUI.IsMouseOn(this))
            {
                State = Selected ?
                        ComponentState.HoverSelected :
                        ComponentState.Hover;
                if (PlayerInput.PrimaryMouseButtonDown())
                {
                    OnButtonDown?.Invoke();
                }
                if (PlayerInput.PrimaryMouseButtonHeld())
                {
                    if (OnPressed != null)
                    {
                        if (OnPressed())
                        {
                            State = ComponentState.Pressed;
                        }
                    }
                    else
                    {
                        State = ComponentState.Pressed;
                    }
                }
                else if (PlayerInput.PrimaryMouseButtonClicked())
                {
                    GUI.PlayUISound(GUISoundType.Click);
                    if (OnClicked != null)
                    {
                        if (OnClicked(this, UserData))
                        {
                            State = ComponentState.Selected;
                        }
                    }
                    else
                    {
                        Selected = !Selected;
                    }
                }
            }
            else
            {
                if (!ExternalHighlight)
                {
                    State = Selected ? ComponentState.Selected : ComponentState.None;
                }
                else
                {
                    State = ComponentState.Hover;
                }
            }

            foreach (GUIComponent child in Children)
            {
                child.State = State;
            }

            if (Pulse)
            {
                pulseTimer += deltaTime;
                if (pulseTimer > 1.0f)
                {
                    if (!flashed)
                    {
                        flashed = true;
                        Frame.Flash(Color.White * 0.2f, 0.8f, true);
                    }

                    pulseExpand += deltaTime;
                    if (pulseExpand > 1.0f)
                    {
                        pulseTimer  = 0.0f;
                        pulseExpand = 0.0f;
                        flashed     = false;
                    }
                }
            }
        }
예제 #21
0
        protected override void Update(float deltaTime)
        {
            base.Update(deltaTime);

            if (!isInitialized)
            {
                Init();
                isInitialized = true;
            }

            if (!PlayerInput.PrimaryMouseButtonHeld())
            {
                mouseHeld = false;
            }

            if (GUI.MouseOn != this)
            {
                return;
            }

            Rectangle mainArea = MainArea,
                      hueArea  = HueArea;

            hueArea.Location  += Rect.Location;
            mainArea.Location += Rect.Location;

            if (PlayerInput.PrimaryMouseButtonDown())
            {
                mouseHeld = true;
                if (hueArea.Contains(PlayerInput.MousePosition))
                {
                    selectedRect = HueArea;
                }
                else if (mainArea.Contains(PlayerInput.MousePosition))
                {
                    selectedRect = MainArea;
                }
                else
                {
                    mouseHeld = false;
                }
            }

            if (!PlayerInput.PrimaryMouseButtonHeld())
            {
                mouseHeld = false;
            }

            if (mouseHeld && (PlayerInput.MouseSpeed != Vector2.Zero || PlayerInput.PrimaryMouseButtonDown()))
            {
                if (selectedRect == HueArea)
                {
                    Vector2 pos = PlayerInput.MousePosition - hueArea.Location.ToVector2();
                    SelectedHue = Math.Clamp(pos.Y / hueArea.Height * 360f, 0, 360);
                    RefreshHue();
                }
                else if (selectedRect == MainArea)
                {
                    var(x, y)          = PlayerInput.MousePosition - mainArea.Location.ToVector2();
                    SelectedSaturation = Math.Clamp(x / mainArea.Width, 0, 1);
                    SelectedValue      = Math.Clamp(1f - (y / mainArea.Height), 0, 1);
                }

                CurrentColor = ToolBox.HSVToRGB(SelectedHue, SelectedSaturation, SelectedValue);

                OnColorSelected?.Invoke(this, CurrentColor);
            }
        }
예제 #22
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        public override void Update(double deltaTime)
        {
#if RUN_PHYSICS_IN_SEPARATE_THREAD
            physicsTime += deltaTime;
            lock (updateLock)
            {
#endif


#if DEBUG && CLIENT
            if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine != null &&
                !DebugConsole.IsOpen && GUI.KeyboardDispatcher.Subscriber == null)
            {
                var closestSub = Submarine.FindClosest(cam.WorldViewCenter);
                if (closestSub == null)
                {
                    closestSub = GameMain.GameSession.Submarine;
                }

                Vector2 targetMovement = Vector2.Zero;
                if (PlayerInput.KeyDown(Keys.I))
                {
                    targetMovement.Y += 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.K))
                {
                    targetMovement.Y -= 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.J))
                {
                    targetMovement.X -= 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.L))
                {
                    targetMovement.X += 1.0f;
                }

                if (targetMovement != Vector2.Zero)
                {
                    closestSub.ApplyForce(targetMovement * closestSub.SubBody.Body.Mass * 100.0f);
                }
            }
#endif

            GameTime += deltaTime;

            foreach (PhysicsBody body in PhysicsBody.List)
            {
                if (body.Enabled)
                {
                    body.Update();
                }
            }
            foreach (MapEntity e in MapEntity.mapEntityList)
            {
                e.IsHighlighted = false;
            }

            if (GameMain.GameSession != null)
            {
                GameMain.GameSession.Update((float)deltaTime);
            }
#if CLIENT
            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            GameMain.ParticleManager.Update((float)deltaTime);

            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("ParticleUpdate", sw.ElapsedTicks);
            sw.Restart();

            if (Level.Loaded != null)
            {
                Level.Loaded.Update((float)deltaTime, cam);
            }

            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("LevelUpdate", sw.ElapsedTicks);

            if (Character.Controlled != null)
            {
                if (Character.Controlled.SelectedConstruction != null && Character.Controlled.CanInteractWith(Character.Controlled.SelectedConstruction))
                {
                    Character.Controlled.SelectedConstruction.UpdateHUD(cam, Character.Controlled, (float)deltaTime);
                }
                if (Character.Controlled.Inventory != null)
                {
                    foreach (Item item in Character.Controlled.Inventory.Items)
                    {
                        if (item == null)
                        {
                            continue;
                        }
                        if (Character.Controlled.HasEquippedItem(item))
                        {
                            item.UpdateHUD(cam, Character.Controlled, (float)deltaTime);
                        }
                    }
                }
            }


            sw.Restart();

            Character.UpdateAll((float)deltaTime, cam);
#elif SERVER
            if (Level.Loaded != null)
            {
                Level.Loaded.Update((float)deltaTime, Camera.Instance);
            }
            Character.UpdateAll((float)deltaTime, Camera.Instance);
#endif


#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("CharacterUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif

            StatusEffect.UpdateAll((float)deltaTime);

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("StatusEffectUpdate", sw.ElapsedTicks);
            sw.Restart();

            if (Character.Controlled != null &&
                Lights.LightManager.ViewTarget != null)
            {
                Vector2 targetPos = Lights.LightManager.ViewTarget.DrawPosition;
                if (Lights.LightManager.ViewTarget == Character.Controlled &&
                    (CharacterHealth.OpenHealthWindow != null || CrewManager.IsCommandInterfaceOpen))
                {
                    Vector2 screenTargetPos = new Vector2(0.0f, GameMain.GraphicsHeight * 0.5f);
                    if (CrewManager.IsCommandInterfaceOpen)
                    {
                        screenTargetPos.X = GameMain.GraphicsWidth * 0.5f;
                    }
                    else
                    {
                        screenTargetPos = CharacterHealth.OpenHealthWindow.Alignment == Alignment.Left ?
                                          new Vector2(GameMain.GraphicsWidth * 0.75f, GameMain.GraphicsHeight * 0.5f) :
                                          new Vector2(GameMain.GraphicsWidth * 0.25f, GameMain.GraphicsHeight * 0.5f);
                    }
                    Vector2 screenOffset = screenTargetPos - new Vector2(GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight / 2);
                    screenOffset.Y = -screenOffset.Y;
                    targetPos     -= screenOffset / cam.Zoom;
                }
                cam.TargetPos = targetPos;
            }

            cam.MoveCamera((float)deltaTime);
#endif

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.SetPrevTransform(sub.Position);
            }

            foreach (PhysicsBody body in PhysicsBody.List)
            {
                if (body.Enabled)
                {
                    body.SetPrevTransform(body.SimPosition, body.Rotation);
                }
            }

#if CLIENT
            MapEntity.UpdateAll((float)deltaTime, cam);
#elif SERVER
            MapEntity.UpdateAll((float)deltaTime, Camera.Instance);
#endif

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("MapEntityUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif
            Character.UpdateAnimAll((float)deltaTime);

#if CLIENT
            Ragdoll.UpdateAll((float)deltaTime, cam);
#elif SERVER
            Ragdoll.UpdateAll((float)deltaTime, Camera.Instance);
#endif

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("AnimUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.Update((float)deltaTime);
            }

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("SubmarineUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif

#if !RUN_PHYSICS_IN_SEPARATE_THREAD
            try
            {
                GameMain.World.Step((float)Timing.Step);
            }
            catch (WorldLockedException e)
            {
                string errorMsg = "Attempted to modify the state of the physics simulation while a time step was running.";
                DebugConsole.ThrowError(errorMsg, e);
                GameAnalyticsManager.AddErrorEventOnce("GameScreen.Update:WorldLockedException" + e.Message, GameAnalyticsSDK.Net.EGAErrorSeverity.Critical, errorMsg);
            }
#endif


#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("Physics", sw.ElapsedTicks);
#endif

#if CLIENT
            if (!PlayerInput.PrimaryMouseButtonHeld())
            {
                Inventory.draggingSlot = null;
                Inventory.draggingItem = null;
            }
#endif


#if RUN_PHYSICS_IN_SEPARATE_THREAD
        }
#endif
        }
예제 #23
0
파일: Map.cs 프로젝트: yweber/Barotrauma
        public void Update(float deltaTime, GUICustomComponent mapContainer)
        {
            Rectangle rect = mapContainer.Rect;

            subReticlePosition  = Vector2.Lerp(subReticlePosition, CurrentLocation.MapPosition, deltaTime);
            subReticleAnimState = 0.8f - Vector2.Distance(subReticlePosition, CurrentLocation.MapPosition) / 50.0f;
            subReticleAnimState = MathHelper.Clamp(subReticleAnimState + (float)Math.Sin(Timing.TotalTime * 3.5f) * 0.2f, 0.0f, 1.0f);

            targetReticleAnimState = SelectedLocation == null?
                                     Math.Max(targetReticleAnimState - deltaTime, 0.0f) :
                                         Math.Min(targetReticleAnimState + deltaTime, 0.6f + (float)Math.Sin(Timing.TotalTime * 2.5f) * 0.4f);

#if DEBUG
            if (GameMain.DebugDraw)
            {
                if (editor == null)
                {
                    CreateEditor();
                }
                editor.AddToGUIUpdateList(order: 1);
            }
#endif

            if (mapAnimQueue.Count > 0)
            {
                hudOpenState = Math.Max(hudOpenState - deltaTime, 0.0f);
                UpdateMapAnim(mapAnimQueue.Peek(), deltaTime);
                if (mapAnimQueue.Peek().Finished)
                {
                    mapAnimQueue.Dequeue();
                }
                return;
            }

            hudOpenState = Math.Min(hudOpenState + deltaTime, 0.75f + (float)Math.Sin(Timing.TotalTime * 3.0f) * 0.25f);

            Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y) + CenterOffset;

            float closestDist = 0.0f;
            highlightedLocation = null;
            if (GUI.MouseOn == null || GUI.MouseOn == mapContainer)
            {
                for (int i = 0; i < Locations.Count; i++)
                {
                    Location location = Locations[i];
                    Vector2  pos      = rectCenter + (location.MapPosition + drawOffset) * zoom;

                    if (!rect.Contains(pos))
                    {
                        continue;
                    }

                    float iconScale = MapGenerationParams.Instance.LocationIconSize / location.Type.Sprite.size.X;

                    Rectangle drawRect = location.Type.Sprite.SourceRect;
                    drawRect.Width  = (int)(drawRect.Width * iconScale * zoom * 1.4f);
                    drawRect.Height = (int)(drawRect.Height * iconScale * zoom * 1.4f);
                    drawRect.X      = (int)pos.X - drawRect.Width / 2;
                    drawRect.Y      = (int)pos.Y - drawRect.Width / 2;

                    if (!drawRect.Contains(PlayerInput.MousePosition))
                    {
                        continue;
                    }

                    float dist = Vector2.Distance(PlayerInput.MousePosition, pos);
                    if (highlightedLocation == null || dist < closestDist)
                    {
                        closestDist         = dist;
                        highlightedLocation = location;
                    }
                }
            }

            if (GUI.KeyboardDispatcher.Subscriber == null)
            {
                float   moveSpeed  = 1000.0f;
                Vector2 moveAmount = Vector2.Zero;
                if (PlayerInput.KeyDown(InputType.Left))
                {
                    moveAmount += Vector2.UnitX;
                }
                if (PlayerInput.KeyDown(InputType.Right))
                {
                    moveAmount -= Vector2.UnitX;
                }
                if (PlayerInput.KeyDown(InputType.Up))
                {
                    moveAmount += Vector2.UnitY;
                }
                if (PlayerInput.KeyDown(InputType.Down))
                {
                    moveAmount -= Vector2.UnitY;
                }
                drawOffset += moveAmount * moveSpeed / zoom * deltaTime;
            }

            if (GUI.MouseOn == mapContainer)
            {
                foreach (LocationConnection connection in connections)
                {
                    if (highlightedLocation != CurrentLocation &&
                        connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(CurrentLocation))
                    {
                        if (PlayerInput.PrimaryMouseButtonClicked() &&
                            SelectedLocation != highlightedLocation && highlightedLocation != null)
                        {
                            //clients aren't allowed to select the location without a permission
                            if (GameMain.Client == null || GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign))
                            {
                                SelectedConnection     = connection;
                                SelectedLocation       = highlightedLocation;
                                targetReticleAnimState = 0.0f;

                                OnLocationSelected?.Invoke(SelectedLocation, SelectedConnection);
                                GameMain.Client?.SendCampaignState();
                            }
                        }
                    }
                }

                zoom += PlayerInput.ScrollWheelSpeed / 1000.0f;
                zoom  = MathHelper.Clamp(zoom, 1.0f, 4.0f);

                if (PlayerInput.MidButtonHeld() || (highlightedLocation == null && PlayerInput.PrimaryMouseButtonHeld()))
                {
                    drawOffset += PlayerInput.MouseSpeed / zoom;
                }
#if DEBUG
                if (PlayerInput.DoubleClicked() && highlightedLocation != null)
                {
                    var passedConnection = CurrentLocation.Connections.Find(c => c.OtherLocation(CurrentLocation) == highlightedLocation);
                    if (passedConnection != null)
                    {
                        passedConnection.Passed = true;
                    }

                    Location prevLocation = CurrentLocation;
                    CurrentLocation            = highlightedLocation;
                    CurrentLocation.Discovered = true;
                    OnLocationChanged?.Invoke(prevLocation, CurrentLocation);
                    SelectLocation(-1);
                    ProgressWorld();
                }
#endif
            }
        }
예제 #24
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();
                }
            }
        }
예제 #25
0
        private void UpdateResizing(Camera cam)
        {
            isHighlighted = true;

            int startX = ResizeHorizontal ? -1 : 0;
            int StartY = ResizeVertical ? -1 : 0;

            for (int x = startX; x < 2; x += 2)
            {
                for (int y = StartY; y < 2; y += 2)
                {
                    Vector2 handlePos = cam.WorldToScreen(Position + new Vector2(x * (rect.Width * 0.5f + 5), y * (rect.Height * 0.5f + 5)));

                    bool highlighted = Vector2.Distance(PlayerInput.MousePosition, handlePos) < 5.0f;

                    if (highlighted && PlayerInput.PrimaryMouseButtonDown())
                    {
                        selectionPos   = Vector2.Zero;
                        resizeDirX     = x;
                        resizeDirY     = y;
                        resizing       = true;
                        startMovingPos = Vector2.Zero;
                    }
                }
            }

            if (resizing)
            {
                if (rectMemento == null)
                {
                    rectMemento = new Memento <Rectangle>();
                    rectMemento.Store(Rect);
                }

                Vector2 placePosition = new Vector2(rect.X, rect.Y);
                Vector2 placeSize     = new Vector2(rect.Width, rect.Height);

                Vector2 mousePos = Submarine.MouseToWorldGrid(cam, Submarine.MainSub);

                if (PlayerInput.IsShiftDown())
                {
                    mousePos = cam.ScreenToWorld(PlayerInput.MousePosition);
                }

                if (resizeDirX > 0)
                {
                    mousePos.X  = Math.Max(mousePos.X, rect.X + Submarine.GridSize.X);
                    placeSize.X = mousePos.X - placePosition.X;
                }
                else if (resizeDirX < 0)
                {
                    mousePos.X = Math.Min(mousePos.X, rect.Right - Submarine.GridSize.X);

                    placeSize.X     = (placePosition.X + placeSize.X) - mousePos.X;
                    placePosition.X = mousePos.X;
                }
                if (resizeDirY < 0)
                {
                    mousePos.Y  = Math.Min(mousePos.Y, rect.Y - Submarine.GridSize.Y);
                    placeSize.Y = placePosition.Y - mousePos.Y;
                }
                else if (resizeDirY > 0)
                {
                    mousePos.Y = Math.Max(mousePos.Y, rect.Y - rect.Height + Submarine.GridSize.X);

                    placeSize.Y     = mousePos.Y - (rect.Y - rect.Height);
                    placePosition.Y = mousePos.Y;
                }

                if ((int)placePosition.X != rect.X || (int)placePosition.Y != rect.Y || (int)placeSize.X != rect.Width || (int)placeSize.Y != rect.Height)
                {
                    Rect = new Rectangle((int)placePosition.X, (int)placePosition.Y, (int)placeSize.X, (int)placeSize.Y);
                }

                if (!PlayerInput.PrimaryMouseButtonHeld())
                {
                    rectMemento.Store(Rect);
                    resizing = false;
                    Resized?.Invoke(rect);
                }
            }
        }
        public void DebugDrawHUD(SpriteBatch spriteBatch, int y)
        {
            foreach (ScriptedEvent scriptedEvent in activeEvents.Where(ev => !ev.IsFinished && ev is ScriptedEvent).Cast <ScriptedEvent>())
            {
                DrawEventTargetTags(spriteBatch, scriptedEvent);
            }

            GUI.DrawString(spriteBatch, new Vector2(10, y), "EventManager", Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 20), "Event cooldown: " + (int)Math.Max(eventCoolDown, 0), Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 35), "Current intensity: " + (int)Math.Round(currentIntensity * 100), Color.Lerp(Color.White, GUI.Style.Red, currentIntensity), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 50), "Target intensity: " + (int)Math.Round(targetIntensity * 100), Color.Lerp(Color.White, GUI.Style.Red, targetIntensity), Color.Black * 0.6f, 0, GUI.SmallFont);

            GUI.DrawString(spriteBatch, new Vector2(15, y + 65), "AvgHealth: " + (int)Math.Round(avgCrewHealth * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgCrewHealth), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 80), "AvgHullIntegrity: " + (int)Math.Round(avgHullIntegrity * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgHullIntegrity), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 95), "FloodingAmount: " + (int)Math.Round(floodingAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, floodingAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 110), "FireAmount: " + (int)Math.Round(fireAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, fireAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 125), "EnemyDanger: " + (int)Math.Round(enemyDanger * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, enemyDanger), Color.Black * 0.6f, 0, GUI.SmallFont);

#if DEBUG
            if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.LeftAlt) &&
                PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.T))
            {
                eventCoolDown = 1.0f;
            }
#endif

            if (intensityGraph == null)
            {
                intensityGraph       = new Graph();
                targetIntensityGraph = new Graph();
            }

            intensityGraphUpdateInterval = 5.0f;
            if (Timing.TotalTime > lastIntensityUpdate + intensityGraphUpdateInterval)
            {
                intensityGraph.Update(currentIntensity);
                targetIntensityGraph.Update(targetIntensity);
                lastIntensityUpdate = (float)Timing.TotalTime;
            }

            Rectangle graphRect = new Rectangle(15, y + 150, 150, 50);

            GUI.DrawRectangle(spriteBatch, graphRect, Color.Black * 0.5f, true);
            intensityGraph.Draw(spriteBatch, graphRect, 1.0f, 0.0f, Color.Lerp(Color.White, GUI.Style.Red, currentIntensity));
            targetIntensityGraph.Draw(spriteBatch, graphRect, 1.0f, 0.0f, Color.Lerp(Color.White, GUI.Style.Red, targetIntensity) * 0.5f);

            GUI.DrawLine(spriteBatch,
                         new Vector2(graphRect.Right, graphRect.Y + graphRect.Height * (1.0f - eventThreshold)),
                         new Vector2(graphRect.Right + 5, graphRect.Y + graphRect.Height * (1.0f - eventThreshold)), Color.Orange, 0, 1);

            y = graphRect.Bottom + 20;
            int x = graphRect.X;
            if (isCrewAway && crewAwayDuration < settings.FreezeDurationWhenCrewAway)
            {
                GUI.DrawString(spriteBatch, new Vector2(x, y), "Events frozen (crew away from sub): " + ToolBox.SecondsToReadableTime(settings.FreezeDurationWhenCrewAway - crewAwayDuration), Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
                y += 15;
            }
            else if (crewAwayResetTimer > 0.0f)
            {
                GUI.DrawString(spriteBatch, new Vector2(x, y), "Events frozen (crew just returned to the sub): " + ToolBox.SecondsToReadableTime(crewAwayResetTimer), Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
                y += 15;
            }
            else if (eventCoolDown > 0.0f)
            {
                GUI.DrawString(spriteBatch, new Vector2(x, y), "Event cooldown active: " + ToolBox.SecondsToReadableTime(eventCoolDown), Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
                y += 15;
            }
            else if (currentIntensity > eventThreshold)
            {
                GUI.DrawString(spriteBatch, new Vector2(x, y),
                               "Intensity too high for new events: " + (int)(currentIntensity * 100) + "%/" + (int)(eventThreshold * 100) + "%", Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
                y += 15;
            }

            foreach (EventSet eventSet in pendingEventSets)
            {
                if (Submarine.MainSub == null)
                {
                    break;
                }

                GUI.DrawString(spriteBatch, new Vector2(x, y), "New event (ID " + eventSet.DebugIdentifier + ") after: ", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                y += 12;

                if (eventSet.PerCave)
                {
                    GUI.DrawString(spriteBatch, new Vector2(x, y), "    submarine near cave", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                    y += 12;
                }
                if (eventSet.PerWreck)
                {
                    GUI.DrawString(spriteBatch, new Vector2(x, y), "    submarine near the wreck", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                    y += 12;
                }
                if (eventSet.PerRuin)
                {
                    GUI.DrawString(spriteBatch, new Vector2(x, y), "    submarine near the ruins", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                    y += 12;
                }
                if (roundDuration < eventSet.MinMissionTime)
                {
                    GUI.DrawString(spriteBatch, new Vector2(x, y),
                                   "    " + (int)(eventSet.MinDistanceTraveled * 100.0f) + "% travelled (current: " + (int)(distanceTraveled * 100.0f) + " %)",
                                   ((Submarine.MainSub == null || distanceTraveled < eventSet.MinDistanceTraveled) ? Color.Lerp(GUI.Style.Yellow, GUI.Style.Red, eventSet.MinDistanceTraveled - distanceTraveled) : GUI.Style.Green) * 0.8f, null, 0, GUI.SmallFont);
                    y += 12;
                }

                if (CurrentIntensity < eventSet.MinIntensity || CurrentIntensity > eventSet.MaxIntensity)
                {
                    GUI.DrawString(spriteBatch, new Vector2(x, y),
                                   "    intensity between " + ((int)eventSet.MinIntensity) + " and " + ((int)eventSet.MaxIntensity),
                                   Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                    y += 12;
                }

                if (roundDuration < eventSet.MinMissionTime)
                {
                    GUI.DrawString(spriteBatch, new Vector2(x, y),
                                   "    " + (int)(eventSet.MinMissionTime - roundDuration) + " s",
                                   Color.Lerp(GUI.Style.Yellow, GUI.Style.Red, (eventSet.MinMissionTime - roundDuration)), null, 0, GUI.SmallFont);
                }

                y += 15;

                if (y > GameMain.GraphicsHeight * 0.9f)
                {
                    y  = graphRect.Bottom + 35;
                    x += 250;
                }
            }

            GUI.DrawString(spriteBatch, new Vector2(x, y), "Current events: ", Color.White * 0.9f, null, 0, GUI.SmallFont);
            y += 15;

            foreach (Event ev in activeEvents.Where(ev => !ev.IsFinished || PlayerInput.IsShiftDown()))
            {
                GUI.DrawString(spriteBatch, new Vector2(x + 5, y), ev.ToString(), (!ev.IsFinished ? Color.White : Color.Red) * 0.8f, null, 0, GUI.SmallFont);

                Rectangle rect = new Rectangle(new Point(x + 5, y), GUI.SmallFont.MeasureString(ev.ToString()).ToPoint());

                Rectangle outlineRect = new Rectangle(rect.Location, rect.Size);
                outlineRect.Inflate(4, 4);

                if (PinnedEvent == ev)
                {
                    GUI.DrawRectangle(spriteBatch, outlineRect, Color.White);
                }

                if (rect.Contains(PlayerInput.MousePosition))
                {
                    GUI.MouseCursor = CursorState.Hand;
                    GUI.DrawRectangle(spriteBatch, outlineRect, Color.White);

                    if (ev != PinnedEvent)
                    {
                        DrawEvent(spriteBatch, ev, rect);
                    }
                    else if (PlayerInput.SecondaryMouseButtonHeld() || PlayerInput.SecondaryMouseButtonDown())
                    {
                        PinnedEvent = null;
                    }

                    if (PlayerInput.PrimaryMouseButtonHeld() || PlayerInput.PrimaryMouseButtonDown())
                    {
                        PinnedEvent = ev;
                    }
                }

                y += 18;
                if (y > GameMain.GraphicsHeight * 0.9f)
                {
                    y  = graphRect.Bottom + 35;
                    x += 250;
                }
            }
        }