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); } } }
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); } } }
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(); } }
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); }
public void AddChunk(GridCellChunk item) { chunksBeingEdited.Add(item, 0x00); }
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(); } }