Ejemplo n.º 1
0
Archivo: Hand.cs Proyecto: jimu/ZunTzu
 /// <summary>Updates the mouse cursor location if it is over this view element.</summary>
 /// <param name="cursorLocation">The current mouse cursor position in screen and model coordinates.</param>
 /// <returns>False if it is not over this view element.</returns>
 public override bool ContainsCursorLocation(ref ICursorLocation cursorLocation)
 {
     if (isVisible && state != HandState.Folded && currentHeight > 0)
     {
         PointF     screenPosition = cursorLocation.ScreenPosition;
         RectangleF area           = view.HandArea;
         if (area.Contains(screenPosition) && model.CurrentGameBox.CurrentGame.GetPlayerHand(model.ThisPlayer.Guid) != null)
         {
             HandCursorLocation location = cursorLocation as HandCursorLocation;
             if (location == null)
             {
                 location       = new HandCursorLocation();
                 cursorLocation = location;
             }
             PointF anchorPosition;
             location.Piece          = getPieceAtPosition(screenPosition, out anchorPosition);
             location.AnchorPosition = anchorPosition;
             location.Index          = getIndexAtPosition(screenPosition);
             location.FocusPiece     = getFocusPieceAtPosition(screenPosition);
             location.Icon           = getIconAtPosition(screenPosition);
             if (location.Icon != HandIcon.None)
             {
                 location.Piece = null;
             }
             return(true);
         }
     }
     return(false);
 }
Ejemplo n.º 2
0
        public override void HandleMouseMove(Point previousMouseScreenPosition, Point currentMouseScreenPosition)
        {
            ICursorLocation location = model.ThisPlayer.CursorLocation;

            if (location is IStackInspectorCursorLocation)
            {
                networkClient.Send(new PieceDraggedMessage(PieceBeingSelected.Id, model.ThisPlayer.DragAndDropAnchor));
                model.ThisPlayer.PieceBeingDragged = PieceBeingSelected;
                controller.State = controller.DraggingPieceState;
                controller.DraggingPieceState.HandleMouseMove(previousMouseScreenPosition, currentMouseScreenPosition);
            }
            else if (location is IHandCursorLocation)
            {
                if (PieceBeingSelected is ITerrainClone)
                {
                    networkClient.Send(new TerrainDraggedMessage(-1, PieceBeingSelected.IndexInStackFromBottomToTop, model.ThisPlayer.DragAndDropAnchor));
                }
                else
                {
                    networkClient.Send(new PieceDraggedMessage(PieceBeingSelected.Id, model.ThisPlayer.DragAndDropAnchor));
                }
                model.ThisPlayer.PieceBeingDragged = PieceBeingSelected;
                controller.State = controller.DraggingHandPieceState;
                controller.DraggingHandPieceState.HandleMouseMove(previousMouseScreenPosition, currentMouseScreenPosition);
            }
            else
            {
                controller.State = controller.IdleState;
            }
        }
Ejemplo n.º 3
0
        public override void UpdateCursor(System.Windows.Forms.Form mainForm, IView view)
        {
            ICursorLocation cursorLocation = model.ThisPlayer.CursorLocation;

            if (cursorLocation is IBoardCursorLocation)
            {
                IBoardCursorLocation location = (IBoardCursorLocation)cursorLocation;
                mainForm.Cursor = (location.Piece == null ? (model.CurrentSelection == null || model.CurrentSelection.Empty ? view.HandCursor : System.Windows.Forms.Cursors.Cross) : view.FingerCursor);

                /*
                 * mainForm.Cursor = (location.Piece == null ?
                 *      (model.CurrentSelection == null || model.CurrentSelection.Empty ?
                 *              (model.CurrentGameBox.Reference == model.GameLibrary.DefaultGameBox ? System.Windows.Forms.Cursors.WaitCursor : view.HandCursor) :
                 *              System.Windows.Forms.Cursors.Cross) :
                 *      view.FingerCursor);
                 */
            }
            else if (cursorLocation is IStackInspectorCursorLocation)
            {
                IStackInspectorCursorLocation location = (IStackInspectorCursorLocation)cursorLocation;
                mainForm.Cursor = (location.Piece == null && location.Icon == StackInspectorIcon.None ? System.Windows.Forms.Cursors.Default : view.FingerCursor);
            }
            else if (cursorLocation is IDiceBagCursorLocation)
            {
                IDiceBagCursorLocation location = (IDiceBagCursorLocation)cursorLocation;
                mainForm.Cursor = (location.DiceCount == 0 ? System.Windows.Forms.Cursors.Default : view.FingerDoubleCursor);
            }
            else if (cursorLocation is ITabsCursorLocation)
            {
                ITabsCursorLocation location = (ITabsCursorLocation)cursorLocation;
                mainForm.Cursor = (location.Tab == null && location.Icon == TabsIcon.None ? System.Windows.Forms.Cursors.Default : view.FingerCursor);
            }
            else if (cursorLocation is IMenuCursorLocation)
            {
                IMenuCursorLocation location = (IMenuCursorLocation)cursorLocation;
                mainForm.Cursor = (location.Item == null ? System.Windows.Forms.Cursors.Default : view.FingerCursor);
            }
            else if (cursorLocation is IHandCursorLocation)
            {
                IHandCursorLocation location = (IHandCursorLocation)cursorLocation;
                mainForm.Cursor = (location.Piece == null && location.Icon == HandIcon.None ? System.Windows.Forms.Cursors.Default : (location.Icon == HandIcon.Resize ? System.Windows.Forms.Cursors.HSplit : view.FingerCursor));
            }
            else
            {
                mainForm.Cursor = System.Windows.Forms.Cursors.Default;
            }
        }
Ejemplo n.º 4
0
        public override void HandleMouseMove(Point previousMouseScreenPosition, Point currentMouseScreenPosition)
        {
            base.HandleMouseMove(previousMouseScreenPosition, currentMouseScreenPosition);

            ICursorLocation cursorLocation = model.ThisPlayer.CursorLocation;

            if (!WaitingForBoardChange && cursorLocation is ITabsCursorLocation)
            {
                ITabsCursorLocation location = (ITabsCursorLocation)cursorLocation;
                IMap tab = location.Tab as IMap;
                if (tab != null && tab != model.CurrentGameBox.CurrentGame.VisibleBoard)
                {
                    WaitingForBoardChange = true;
                    networkClient.Send(new VisibleBoardChangedMessage(model.StateChangeSequenceNumber, tab.Id));
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>Updates the mouse cursor location if it is over this view element.</summary>
        /// <param name="cursorLocation">The current mouse cursor position in screen and model coordinates.</param>
        /// <returns>False if it is not over this view element.</returns>
        public override bool ContainsCursorLocation(ref ICursorLocation cursorLocation)
        {
            // TODO: mouse location over player view

            /*
             * PointF screenPosition = cursorLocation.ScreenPosition;
             * if(Area.Contains(screenPosition)) {
             *      PlayerViewCursorLocation location = cursorLocation as PlayerViewCursorLocation;
             *      if(location == null) {
             *              location = new PlayerViewCursorLocation();
             *              cursorLocation = location;
             *      }
             *      return true;
             * } else {
             *      return false;
             * }
             */
            return(false);
        }
Ejemplo n.º 6
0
        public override void HandleGrabKeyPress()
        {
            ICursorLocation cursorLocation = model.ThisPlayer.CursorLocation;

            // over the board
            if (cursorLocation is IBoardCursorLocation)
            {
                IBoardCursorLocation location = (IBoardCursorLocation)cursorLocation;
                IPiece stackBottom            = location.Piece;
                // assumption: the stack will remain unchanged in the meantime
                if (stackBottom != null && !model.AnimationManager.IsBeingAnimated(stackBottom.Stack))
                {
                    if (stackBottom is ITerrainClone)
                    {
                        networkClient.Send(new GrabTerrainMessage(model.StateChangeSequenceNumber, stackBottom.Stack.Board.Id, stackBottom.Stack.Board.GetZOrder(stackBottom.Stack)));
                    }
                    else
                    {
                        networkClient.Send(new GrabStackMessage(model.StateChangeSequenceNumber, stackBottom.Id));
                    }
                }
                // over the stack inspector
            }
            else if (cursorLocation is IStackInspectorCursorLocation)
            {
                IStackInspectorCursorLocation location = (IStackInspectorCursorLocation)cursorLocation;
                IPiece piece = location.Piece;
                // assumption: the stack will remain unchanged in the meantime
                if (piece != null && !model.AnimationManager.IsBeingAnimated(piece.Stack))
                {
                    if (piece.Stack.Pieces.Length == 1)
                    {
                        networkClient.Send(new GrabStackMessage(model.StateChangeSequenceNumber, piece.Id));
                    }
                    else
                    {
                        networkClient.Send(new GrabPieceMessage(model.StateChangeSequenceNumber, piece.Id));
                    }
                }
            }
        }
Ejemplo n.º 7
0
Archivo: Menu.cs Proyecto: jimu/ZunTzu
        /// <summary>Updates the mouse cursor location if it is over this view element.</summary>
        /// <param name="cursorLocation">The current mouse cursor position in screen and model coordinates.</param>
        /// <returns>False if it is not over this view element.</returns>
        public override bool ContainsCursorLocation(ref ICursorLocation cursorLocation)
        {
            PointF   screenPosition   = cursorLocation.ScreenPosition;
            MenuItem menuItemSelected = getItemAtPosition(screenPosition);

            if (menuItemSelected != null)
            {
                MenuCursorLocation location = cursorLocation as MenuCursorLocation;
                if (location == null)
                {
                    location       = new MenuCursorLocation();
                    cursorLocation = location;
                }
                location.Item = menuItemSelected;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 8
0
        /// <summary>Updates the mouse cursor location if it is over this view element.</summary>
        /// <param name="cursorLocation">The current mouse cursor position in screen and model coordinates.</param>
        /// <returns>False if it is not over this view element.</returns>
        public override bool ContainsCursorLocation(ref ICursorLocation cursorLocation)
        {
            PointF screenPosition = cursorLocation.ScreenPosition;

            if (Area.Contains(screenPosition))
            {
                TabsCursorLocation location = cursorLocation as TabsCursorLocation;
                if (location == null)
                {
                    location       = new TabsCursorLocation();
                    cursorLocation = location;
                }
                location.Icon = getIconAtPosition(screenPosition);
                location.Tab  = (location.Icon != TabsIcon.None ? null : getTabAtPosition(screenPosition));
                return(true);
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 9
0
 private void onMouseDown(object o, MouseEventArgs e)
 {
     if (state != DialogState && view.GameDisplayAreaInPixels.Contains(e.X, e.Y))
     {
         if (e.Button == MouseButtons.Right)
         {
             if (State == ScrollingState)
             {
                 State                    = MeasuringState;
                 model.IsMeasuring        = true;
                 model.RulerStartPosition = model.ThisPlayer.CursorLocation.ModelPosition;
                 model.RulerEndPosition   = model.RulerStartPosition;
             }
             else
             {
                 ICursorLocation location = model.ThisPlayer.CursorLocation;
                 isZoomingInHand             = location is IHandCursorLocation;
                 zoomInvariantScreenPosition = location.ScreenPosition;
                 isZooming        = true;
                 mainForm.Cursor  = view.ZoomCursor;
                 mainForm.Capture = true;
             }
         }
         else if (e.Button == MouseButtons.Left)
         {
             if (isZooming)
             {
                 isZooming                = false;
                 State                    = MeasuringState;
                 model.IsMeasuring        = true;
                 model.RulerStartPosition = model.ThisPlayer.CursorLocation.ModelPosition;
                 model.RulerEndPosition   = model.RulerStartPosition;
             }
             else
             {
                 State.HandleLeftMouseButtonDown();
             }
         }
     }
 }
Ejemplo n.º 10
0
        public override void UpdateCursor(System.Windows.Forms.Form mainForm, IView view)
        {
            IPiece pieceBeingDragged = model.ThisPlayer.PieceBeingDragged;

            if (pieceBeingDragged == null)
            {
                controller.State = controller.IdleState;
                controller.IdleState.UpdateCursor(mainForm, view);
            }
            else
            {
                ICursorLocation cursorLocation = model.ThisPlayer.CursorLocation;
                if (cursorLocation is IHandCursorLocation)
                {
                    mainForm.Cursor = view.FingerCursor;
                }
                else if (cursorLocation is IBoardCursorLocation)
                {
                    IBoardCursorLocation location = (IBoardCursorLocation)cursorLocation;
                    mainForm.Cursor = (!model.CurrentGameBox.CurrentGame.StackingEnabled || location.Piece == null || location.Piece.Stack.AttachedToCounterSection || location.Piece.GetType() != pieceBeingDragged.GetType() || pieceBeingDragged is ITerrainClone ? view.FingerCursor : view.FingerAddCursor);
                }
                else if (cursorLocation is IStackInspectorCursorLocation)
                {
                    mainForm.Cursor = (model.CurrentSelection == null || model.CurrentSelection.Stack.Pieces[0].GetType() != pieceBeingDragged.GetType() ?
                                       System.Windows.Forms.Cursors.No : view.FingerAddCursor);
                }
                else if (cursorLocation is ITabsCursorLocation)
                {
                    ITabsCursorLocation location = (ITabsCursorLocation)cursorLocation;
                    mainForm.Cursor = (location.Tab is ICounterSheet ? view.FingerRemoveCursor : view.FingerCursor);
                }
                else
                {
                    mainForm.Cursor = System.Windows.Forms.Cursors.No;
                }
            }
        }
Ejemplo n.º 11
0
        /// <summary>Updates the mouse cursor location if it is over this view element.</summary>
        /// <param name="cursorLocation">The current mouse cursor position in screen and model coordinates.</param>
        /// <returns>False if it is not over this view element.</returns>
        public override bool ContainsCursorLocation(ref ICursorLocation cursorLocation)
        {
            PointF screenPosition = cursorLocation.ScreenPosition;

            if (model.CurrentSelection != null && Area.Contains(screenPosition))
            {
                StackInspectorCursorLocation location = cursorLocation as StackInspectorCursorLocation;
                if (location == null)
                {
                    location       = new StackInspectorCursorLocation();
                    cursorLocation = location;
                }
                PointF anchorPosition;
                location.Piece          = getPieceAtPosition(screenPosition, out anchorPosition);
                location.AnchorPosition = anchorPosition;
                location.Index          = getIndexAtPosition(screenPosition);
                location.Icon           = getIconAtPosition(screenPosition);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 12
0
        /// <summary>Updates the mouse cursor location if it is over this view element.</summary>
        /// <param name="cursorLocation">The current mouse cursor position in screen and model coordinates.</param>
        /// <returns>False if it is not over this view element.</returns>
        public override bool ContainsCursorLocation(ref ICursorLocation cursorLocation)
        {
            PointF screenPosition = cursorLocation.ScreenPosition;

            if (Area.Contains(screenPosition))
            {
                DiceBagCursorLocation location = cursorLocation as DiceBagCursorLocation;
                if (location == null)
                {
                    location       = new DiceBagCursorLocation();
                    cursorLocation = location;
                }
                int diceHandIndex;
                int diceCount;
                getDiceAtPosition(screenPosition, out diceHandIndex, out diceCount);
                location.DiceHandIndex = diceHandIndex;
                location.DiceCount     = diceCount;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 13
0
        /// <summary>Processes mouse, keyboard and network messages.</summary>
        /// <param name="currentTimeInMicroseconds">Time of this frame.</param>
        public void DoEvents(long currentTimeInMicroseconds)
        {
            // process mouse and keyboard events
            System.Windows.Forms.Application.DoEvents();

            // add a physical measure based on the mouse cursor positions to the entropy pool
            int physicalMeasure = 0;

            foreach (IPlayer player in model.Players)
            {
                Point position = player.CursorLocation.ScreenPosition;
                physicalMeasure += position.X + position.Y;
            }
            dieSimulator.AddPhysicalMeasure((uint)physicalMeasure);

            // process network messages
            foreach (Message message in networkClient.RetrieveNetworkMessages())
            {
                message.Handle(this);
            }

            // autosave every minute
            if (model.IsHosting &&
                model.CurrentGameBox.Reference != model.GameLibrary.DefaultGameBox &&
                currentTimeInMicroseconds - LastAutosaveTimeInMicroseconds > 60000000L)
            {
                model.AnimationManager.LaunchAnimationSequence(new SaveGameAnimation(AutosaveFileName));
                LastAutosaveTimeInMicroseconds = currentTimeInMicroseconds;
            }

            view.UpdateMouseLocations();

            // cursor visibility
            ICursorLocation cursorLocation = model.ThisPlayer.CursorLocation;

            if (cursorLocation is IOutOfFrameCursorLocation ||
                cursorLocation is IMenuCursorLocation ||
                cursorLocation is IHandCursorLocation ||
                state == DialogState)
            {
                if (model.ThisPlayer.IsCursorVisible)
                {
                    model.ThisPlayer.IsCursorVisible = false;
                    networkClient.Send(new HideCursorMessage());
                }
            }
            else
            {
                if (!model.ThisPlayer.IsCursorVisible)
                {
                    model.ThisPlayer.IsCursorVisible = true;
                    networkClient.Send(new ShowCursorMessage());
                }
            }

            // hand folding/unfolding
            switch (handFoldingActivationState)
            {
            case HandFoldingActivationState.OutOfActivationArea:
                if (cursorLocation is ITabsCursorLocation || cursorLocation is IHandCursorLocation)
                {
                    if (isZooming || state == ScrollingState)
                    {
                        handFoldingActivationState = HandFoldingActivationState.InActivationAreaScrolling;
                    }
                    else
                    {
                        view.Hand.Unfold();
                        handFoldingActivationState = HandFoldingActivationState.InActivationArea;
                    }
                }
                break;

            case HandFoldingActivationState.InActivationArea:
                if (state != ResizingHandState && !(cursorLocation is ITabsCursorLocation || cursorLocation is IHandCursorLocation || cursorLocation is IOutOfFrameCursorLocation))
                {
                    view.Hand.Fold();
                    handFoldingActivationState = HandFoldingActivationState.OutOfActivationArea;
                }
                break;

            case HandFoldingActivationState.InActivationAreaScrolling:
                if (!(cursorLocation is ITabsCursorLocation || cursorLocation is IHandCursorLocation || cursorLocation is IOutOfFrameCursorLocation))
                {
                    handFoldingActivationState = HandFoldingActivationState.OutOfActivationArea;
                }
                break;
            }

            if (!isZooming && !(model.ThisPlayer.CursorLocation is IOutOfFrameCursorLocation))
            {
                state.UpdateCursor(mainForm, view);
            }
        }
Ejemplo n.º 14
0
        public override void HandleDeleteKeyPress()
        {
            ICursorLocation cursorLocation = model.ThisPlayer.CursorLocation;

            // over the board
            if (cursorLocation is IBoardCursorLocation)
            {
                IBoardCursorLocation location = (IBoardCursorLocation)cursorLocation;
                IPiece stackBottom            = location.Piece;
                // over a unattached stack
                if (stackBottom != null && !stackBottom.Stack.AttachedToCounterSection)
                {
                    // assumption: the stack will remain unchanged in the meantime
                    if (!model.AnimationManager.IsBeingAnimated(stackBottom.Stack))
                    {
                        if (stackBottom is ITerrainClone)
                        {
                            networkClient.Send(new RemoveTerrainMessage(model.StateChangeSequenceNumber, stackBottom.Stack.Board.Id, stackBottom.Stack.Board.GetZOrder(stackBottom.Stack)));
                        }
                        else
                        {
                            networkClient.Send(new UnpunchStackMessage(model.StateChangeSequenceNumber, stackBottom.Id));
                        }
                    }
                }
                // over the stack inspector
            }
            else if (cursorLocation is IStackInspectorCursorLocation)
            {
                IStackInspectorCursorLocation location = (IStackInspectorCursorLocation)cursorLocation;
                IPiece piece = location.Piece;
                // over an unattached piece
                if (piece != null && !piece.Stack.AttachedToCounterSection)
                {
                    // assumption: the stack will remain unchanged in the meantime
                    if (!model.AnimationManager.IsBeingAnimated(piece.Stack))
                    {
                        networkClient.Send(new UnpunchPieceMessage(model.StateChangeSequenceNumber, piece.Id));
                    }
                }
                // over the hand
            }
            else if (cursorLocation is IHandCursorLocation)
            {
                IHandCursorLocation location = (IHandCursorLocation)cursorLocation;
                IPiece piece = location.Piece;
                // over a piece
                if (piece != null)
                {
                    // assumption: the stack will remain unchanged in the meantime
                    if (!model.AnimationManager.IsBeingAnimated(piece.Stack))
                    {
                        if (piece is ITerrainClone)
                        {
                            networkClient.Send(new RemoveTerrainMessage(model.StateChangeSequenceNumber, -1, piece.IndexInStackFromBottomToTop));
                        }
                        else
                        {
                            networkClient.Send(new UnpunchPieceMessage(model.StateChangeSequenceNumber, piece.Id));
                        }
                    }
                }
            }
        }
Ejemplo n.º 15
0
        public override void HandleLeftMouseButtonUp()
        {
            IPlayer     thisPlayer        = model.ThisPlayer;
            IPiece      pieceBeingDragged = thisPlayer.PieceBeingDragged;
            IPlayerHand playerHand        = model.CurrentGameBox.CurrentGame.GetPlayerHand(thisPlayer.Guid);

            if (pieceBeingDragged != null && playerHand.Count > 0 && playerHand.Pieces[0].Stack == pieceBeingDragged.Stack)
            {
                ICursorLocation cursorLocation = thisPlayer.CursorLocation;
                // over the hand
                if (cursorLocation is IHandCursorLocation)
                {
                    IHandCursorLocation location = (IHandCursorLocation)cursorLocation;
                    int insertionIndex           = location.Index;
                    int currentIndex             = pieceBeingDragged.IndexInStackFromBottomToTop;
                    // assumption: the stack will remain unchanged in the meantime
                    if (insertionIndex != currentIndex && insertionIndex != currentIndex + 1 &&
                        !model.AnimationManager.IsBeingAnimated(pieceBeingDragged.Stack))
                    {
                        networkClient.Send(new RearrangePlayerHandMessage(model.StateChangeSequenceNumber, currentIndex, insertionIndex));
                    }
                    else
                    {
                        networkClient.Send(new DragDropAbortedMessage());
                    }
                    // over the board
                }
                else if (cursorLocation is IBoardCursorLocation)
                {
                    IBoardCursorLocation location = (IBoardCursorLocation)cursorLocation;
                    IPiece pieceAtMousePosition   = location.Piece;
                    // over an unattached stack
                    if (model.CurrentGameBox.CurrentGame.StackingEnabled && pieceAtMousePosition != null && !pieceAtMousePosition.Stack.AttachedToCounterSection && pieceAtMousePosition.GetType() == pieceBeingDragged.GetType() && !(pieceBeingDragged is ITerrainClone))
                    {
                        // assumption: both stacks will remain unchanged in the meantime
                        if (pieceAtMousePosition.Stack != pieceBeingDragged.Stack &&
                            !model.AnimationManager.IsBeingAnimated(pieceBeingDragged.Stack) &&
                            !model.AnimationManager.IsBeingAnimated(pieceAtMousePosition.Stack))
                        {
                            networkClient.Send(new DragDropPieceOnTopOfOtherStackMessage(model.StateChangeSequenceNumber, pieceBeingDragged.Id, pieceAtMousePosition.Stack.Id));
                        }
                        else
                        {
                            networkClient.Send(new DragDropAbortedMessage());
                        }
                        // over an empty space
                    }
                    else
                    {
                        // assumption: the stack will remain unchanged in the meantime
                        if (!model.AnimationManager.IsBeingAnimated(pieceBeingDragged.Stack))
                        {
                            PointF newPiecePosition = new PointF(
                                location.ModelPosition.X - thisPlayer.DragAndDropAnchor.X,
                                location.ModelPosition.Y - thisPlayer.DragAndDropAnchor.Y);
                            if (pieceBeingDragged is ITerrainClone)
                            {
                                networkClient.Send(new DragDropTerrainMessage(model.StateChangeSequenceNumber, -1, pieceBeingDragged.IndexInStackFromBottomToTop, newPiecePosition));
                            }
                            else
                            {
                                networkClient.Send(new DragDropPieceMessage(model.StateChangeSequenceNumber, pieceBeingDragged.Id, newPiecePosition));
                            }
                        }
                        else
                        {
                            networkClient.Send(new DragDropAbortedMessage());
                        }
                    }
                    // over the stack inspector
                }
                else if (cursorLocation is IStackInspectorCursorLocation)
                {
                    IStackInspectorCursorLocation location = (IStackInspectorCursorLocation)cursorLocation;
                    // assumption: boths stacks will remain unchanged in the meantime
                    if (model.CurrentSelection != null && model.CurrentSelection.Stack != pieceBeingDragged.Stack && model.CurrentSelection.Stack.Pieces[0].GetType() == pieceBeingDragged.GetType() &&
                        !model.AnimationManager.IsBeingAnimated(model.CurrentSelection.Stack) &&
                        !model.AnimationManager.IsBeingAnimated(pieceBeingDragged.Stack))
                    {
                        networkClient.Send(new DragDropPieceIntoOtherStackMessage(model.StateChangeSequenceNumber, pieceBeingDragged.Id, location.Index));
                    }
                    else
                    {
                        networkClient.Send(new DragDropAbortedMessage());
                    }
                    // over a counter sheet tab
                    // assumption: the stack will remain unchanged in the meantime
                }
                else if (cursorLocation is ITabsCursorLocation && ((ITabsCursorLocation)cursorLocation).Tab is ICounterSheet &&
                         !model.AnimationManager.IsBeingAnimated(pieceBeingDragged.Stack))
                {
                    if (pieceBeingDragged is ITerrainClone)
                    {
                        networkClient.Send(new RemoveTerrainMessage(model.StateChangeSequenceNumber, -1, pieceBeingDragged.IndexInStackFromBottomToTop));
                    }
                    else
                    {
                        networkClient.Send(new UnpunchPieceMessage(model.StateChangeSequenceNumber, pieceBeingDragged.Id));
                    }
                }
                else
                {
                    networkClient.Send(new DragDropAbortedMessage());
                }
            }
            thisPlayer.PieceBeingDragged = null;
            controller.State             = controller.IdleState;
        }