Пример #1
0
        private void AddChunksVert(GsVector offset, GsVector mousePt, int cellsNeeded, bool above)
        {
            // create a list to hold the chunk pieces
            List <GridCell> chunkPieces = new List <GridCell>();

            // get the starting chunk
            GridCellChunk startingChunk = mSelection.StartingChunk;

            // preprocess some values
            float startY     = startingChunk.Y + (above ? -CellHeight : startingChunk.Height);
            float startX     = startingChunk.X;
            float addY       = CellHeight * (above ? -1 : 1);
            float addX       = CellWidth;
            float endY       = mousePt.Y + (cellsNeeded == 1 ? 0 : addY);
            float endX       = startingChunk.Bounds.Right;
            int   comparison = (above ? 1 : -1);

            // move to the end y
            for (float y = startY; y.CompareTo(endY).Equals(comparison); y += addY)
            {
                for (float x = startX; x < endX; x += addX)
                {
                    UpdateChunkPieces(ref chunkPieces, cellsNeeded, offset, x, y);
                }
            }
        }
Пример #2
0
        private void AddChunksHorz(GsVector offset, GsVector mousePt, int cellsNeeded, bool left)
        {
            // create a list to hold the chunk pieces
            List <GridCell> chunkPieces = new List <GridCell>();

            // get the starting chunk
            GridCellChunk startingChunk = mSelection.StartingChunk;

            // preprocess some values
            float startY     = startingChunk.Y;
            float startX     = startingChunk.X + (left ? -CellWidth : startingChunk.Width);
            float addY       = CellHeight;
            float addX       = CellWidth * (left ? -1 : 1);
            float endY       = startingChunk.Bounds.Bottom;
            float endX       = mousePt.X + (cellsNeeded == 1 ? 0 : addX);
            int   comparison = (left ? 1 : -1);

            // start at the bottom of the chunk and move down until we hit the cursor y
            for (float x = startX; x.CompareTo(endX).Equals(comparison); x += addX)
            {
                for (float y = startY; y < endY; y += addY)
                {
                    UpdateChunkPieces(ref chunkPieces, cellsNeeded, offset, x, y);
                }
            }
        }
Пример #3
0
        private void UpdateChunkPieces(ref List <GridCell> chunkPieces, int cellsNeeded, GsVector offset, float x, float y)
        {
            int r = (int)((y - offset.Y) / CellHeight);
            int c = (int)((x - offset.X) / CellWidth);

            if ((-1 < r && r < NumRows) && (-1 < c && c < NumCols))
            {
                // add this cell to the current chunk
                chunkPieces.Add(Grid[c, r]);
            }

            // if we have the correct number of chunks
            if (chunkPieces.Count == (cellsNeeded * cellsNeeded))
            {
                // compute the bounds of the cell pieces
                GsRectangle bounds = ComputeBounds(chunkPieces, CellWidth, CellHeight);

                // for now, we only care if the chunk is available (in terms of it being valid)
                GridCellChunk item = new GridCellChunk
                {
                    Bounds = bounds,
                    Cells  = chunkPieces.ToArray(),
                    Valid  = chunkPieces.TrueForAll(GridCell.CellIsAvailable),
                };
                mSelection.AddChunk(item);
                chunkPieces.Clear();
            }
        }
Пример #4
0
        public Piece BuildFromChunk(GsRectangle gridBounds, GridCellChunk editedChunk)
        {
            GridCell[] cells = editedChunk.Cells.ToList().ToArray();
            Piece      piece = CreatePiece(cells);

            piece.GridBounds = gridBounds;

            for (int i = 0; i < cells.Length; ++i)
            {
                GridCell cell = cells[i];
                cell.SetPiece(piece);
            }

            piece.Cells  = cells;
            piece.Bounds = editedChunk.Bounds;
            piece.SavePriceInfo();

            if (!Player.PurchasePiece(piece))
            {
                throw new Exception("Somehow you placed this without enough money!");
            }

            return(piece);
        }
Пример #5
0
 public void AddChunk(GridCellChunk item)
 {
     chunksBeingEdited.Add(item, 0x00);
 }
Пример #6
0
        private void UpdatePiecePlacement(UpdateParams uparams)
        {
            // set the chunk to null
            mSelection.Chunk = null;

            // don't place any towers if no towers are selected
            if (lstPieces.SelectedIndex == -1)
            {
                // end any edits that are in place
                mSelection.EndPlaceEdits();
                return;
            }

            // get the mouse point
            GsVector mousePt = uparams.Input.CursorPosition - uparams.Offset;

            // get the current chunk
            Piece piece       = lstPieces.Items[lstPieces.SelectedIndex].Value as Piece;
            int   cellsNeeded = (int)piece.Grouping;
            float width       = CellWidth * cellsNeeded;
            float height      = CellHeight * cellsNeeded;

            // compute the data needed
            GsVector    offset    = GsVector.Zero;
            GsRectangle cursorBox = Calculator.CreateBoxAroundPoint(mousePt, offset, width, height);

            GridCell[] cells = GetCellsWithCenterContainedIn(Grid, cursorBox, offset);

            if (cells.Length > 0)
            {
                GsRectangle bounds = ComputeBounds(cells, CellWidth, CellHeight);
                mSelection.Chunk = new GridCellChunk
                {
                    Bounds = bounds,
                    Cells  = cells,
                    Valid  = (cells.Length == (cellsNeeded * cellsNeeded)) && Array.TrueForAll <GridCell>(cells, GridCell.CellIsAvailable),
                };
            }

            // set the bounds of the selection to be the bounds of the chunk
            mSelection.Bounds = GsRectangle.Empty;
            if (mSelection.Chunk != null)
            {
                mSelection.Bounds = mSelection.Chunk.Bounds;
            }

            // if the mouse is down and we haven't added any chunks, then make this the starting chunk
            if (uparams.Input.SelectPressed)
            {
                // if we don't have a starting chunk, then start it
                if (mSelection.StartingChunk == null)
                {
                    mSelection.StartingChunk = mSelection.Chunk;
                }

                // clear the bounds
                mSelection.Bounds = GsRectangle.Empty;

                // get the starting chunk for easy access
                GridCellChunk startingChunk = mSelection.StartingChunk;

                // if the starting chunk is null, or invalid, then don't do this
                if (startingChunk != null && startingChunk.Valid)
                {
                    // basically, we need to determine how many chunks to add to the chunks currently being
                    // edited. We can do this by first determining where the cursor box is. If it is below us
                    // (meaning the top of the cursor box is greater than the bottom of the starting chunk
                    // box), then we just need to count and see how many cells away the [0,0] cell from the cursor
                    // box is away from the starting chunk box. So, "int countNeeded = cellsAwayFromStartingBox -
                    // (cellsAwayFromStartingBox % cellsNeeded". This will tell us how many cells we should collect
                    // in each direction (horz and vert). Then, we divide that number by cellsNeeded to get the number
                    // of chunks. Then, we simply assemble the chunks and add them to a collection. The same logic is
                    // done if the cursor box is horizontally away.

                    // clear away the chunks being edited
                    mSelection.ClearEdits();

                    // figure out if the cursor is in the vert plane, or the horz plane
                    var rect   = startingChunk.Bounds;
                    var center = rect.Location;
                    center.X += rect.Width / 2;
                    center.Y += rect.Height / 2;

                    float dy  = mousePt.Y - center.Y;
                    float dx  = mousePt.X - center.X;
                    float aDy = Math.Abs(dy);
                    float aDx = Math.Abs(dx);

                    if (aDy > aDx)
                    {
                        // the difference in the y direction is greater. If dy > 0, this means that the cursor is BELOW the starting chunk.
                        // If dy < 0, this means that the cursor is ABOVE the starting chunk. If dy == 0, then we don't care
                        if (dy != 0)
                        {
                            AddChunksVert(offset, mousePt, cellsNeeded, dy < 0);
                        }
                    }
                    else
                    {
                        // the difference in the x direction is greater. If dx > 0, this means that the cursor is RIGHT of the starting chunk.
                        // If dx < 0, this means that the cursor is LEFT of the starting chunk. Again, dx == 0, we don't care
                        if (dx != 0)
                        {
                            AddChunksHorz(offset, mousePt, cellsNeeded, dx < 0);
                        }
                    }

                    // make sure that the chunk we're drawing is the starting chunk
                    mSelection.Chunk = startingChunk;
                }
            }
            else
            {
                // if we have a starting chunk
                if (mSelection.StartingChunk != null)
                {
                    // add all the towers
                    foreach (GridCellChunk editedChunk in mSelection.Edits)
                    {
                        // see if we have enough funds
                        bool enoughFunds = Player.EnoughCashFor(piece);

                        // create a default invalid message
                        string invalidMessage = enoughFunds ? "Cell(s) not available" : "Not enough funds";

                        // update the validity of the chunk
                        editedChunk.Valid &= enoughFunds;

                        // if the chunk is valid, then attempt to place it.
                        if (editedChunk.Valid)
                        {
                            // build the piece in the location
                            Piece tower = piece.BuildFromChunk(gridBounds, editedChunk);
                            mPieces.Add(tower);

                            // if we can't get through
                            if (!AssertCanGetThrough(tower))
                            {
                                // remove the piece
                                int last = mPieces.Count - 1;
                                tower.SellInstant();
                                mPieces.RemoveAt(last);

                                // re-solve the grid
                                SolveGrid();

                                // the piece is no longer valid
                                editedChunk.Valid = false;

                                // blocking
                                invalidMessage = "Blocking Invaders";
                            }
                        }

                        if (!editedChunk.Valid)
                        {
                            // add a quick message
                            //MessageComponent.AddMessage(invalidMessage,
                            //    Position + new GsVector((Width / 2f), (Height / 2f)),
                            //    800,
                            //    true);

                            // a chunk can be invalid if all the cells don't have towers.
                            // Find any cells that have towers, and flash them red
                            foreach (GridCell cell in editedChunk.Cells)
                            {
                                if (cell.IsWalkable)
                                {
                                    // we use a dictionary so we don't add the same cell twice. We also
                                    // reset the time that the cell is flashing.
                                    cellsToFlash[cell] = SecondsToFlashCell;
                                }
                            }
                        }
                    }
                }

                mSelection.EndPlaceEdits();
            }
        }