Example #1
0
 /// <summary>Called once when time is EndTimeInMicroseconds.</summary>
 protected override sealed void SetFinalState(IModel model)
 {
     foreach (Stack stack in stacks)
     {
         IPiece          piece          = stack.Pieces[0];
         ICounterSection counterSection = piece.CounterSection;
         if (model.CurrentSelection != null && model.CurrentSelection.Stack == stack)
         {
             if (piece is ICounter && ((int)counterSection.Type & (1 + (int)counterSection.CounterSheet.Side)) == 0 ||
                 piece is ICard && (counterSection.CounterSheet.Side == Side.Front) != counterSection.HasCardFaceOnFront)
             {
                 model.CurrentSelection = null;
             }
         }
         ((CounterSheet)counterSection.CounterSheet).MoveStackToBack(stack);
         stack.AttachedToCounterSection = true;
     }
 }
Example #2
0
        /// <summary>Returns the top-most piece (but not terrain) at a given position on this board.</summary>
        /// <param name="position">Position in local coordinates.</param>
        /// <returns>A piece or null.</returns>
        public IPiece GetPieceAtPosition(PointF position)
        {
            // for each layer (bottom layer is for unpunched pieces, next layer is for punched cards, top layer is for punched counters)
            for (int layer = 2; layer >= 0; --layer)
            {
                for (int pass = 0; pass < 2; ++pass)
                {
                    for (int i = Stacks.Count - 1; i >= 0; --i)
                    {
                        Stack    stack  = Stacks[i];
                        IPiece[] pieces = stack.Pieces;
                        if (stack.Unfolded == (pass == 0) &&
                            !(pieces[0] is ITerrain) &&
                            ((layer == 0 && stack.AttachedToCounterSection) ||
                             (layer == 1 && !stack.AttachedToCounterSection && pieces[0] is ICard) ||
                             (layer == 2 && !stack.AttachedToCounterSection && pieces[0] is ICounter)) &&
                            stack.BoundingBox.Contains(position))
                        {
                            // ignore attached pieces on the opposite side
                            ICounterSection    counterSection = pieces[0].CounterSection;
                            CounterSectionType type           = counterSection.Type;
                            if (!stack.AttachedToCounterSection ||
                                (counterSection.ContainsCounters && ((int)type & ((int)((ICounterSheet)this).Side + 1)) != 0) ||
                                (!counterSection.ContainsCounters && counterSection.HasCardFaceOnFront == (((ICounterSheet)this).Side == Side.Front)))
                            {
                                for (int j = pieces.Length - 1; j >= 0; --j)
                                {
                                    IPiece piece = pieces[j];
                                    if (piece.BoundingBox.Contains(position))
                                    {
                                        // we have to compute the model coordinates of the position
                                        // relative to the counter sheet

                                        // we have to handle rotations of the piece
                                        // apply the inverse rotation to the position
                                        PointF piecePosition       = piece.Position;
                                        PointF transformedPosition = new PointF(
                                            position.X - piecePosition.X,
                                            position.Y - piecePosition.Y);

                                        if (piece.RotationAngle != 0.0f)
                                        {
                                            // rotation:
                                            // x <- x * cos - y * sin
                                            // y <- x * sin + y * cos
                                            float sin = (float)Math.Sin(piece.RotationAngle);
                                            float cos = (float)Math.Cos(piece.RotationAngle);

                                            transformedPosition = new PointF(
                                                transformedPosition.X * cos - transformedPosition.Y * sin,
                                                transformedPosition.X * sin + transformedPosition.Y * cos);
                                        }

                                        SizeF size = piece.Size;
                                        if (new RectangleF(
                                                -size.Width * 0.5f,
                                                -size.Height * 0.5f,
                                                size.Width,
                                                size.Height).Contains(transformedPosition))
                                        {
                                            // is the piece completely transparent at that location?
                                            if (piece.Graphics != null)
                                            {
                                                uint color = piece.Graphics.GetColorAtPosition(transformedPosition);
                                                if ((color & 0xFF000000) != 0x00000000)
                                                {
                                                    // no it is not
                                                    if (!stack.Unfolded && piece is ICard)
                                                    {
                                                        return(pieces[pieces.Length - 1]);
                                                    }
                                                    else
                                                    {
                                                        return(piece);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(null);
        }