// Moves the TileElement in the given direction one space // This should only be called if all spaces in the given direction are emptys public override bool Move(TileElement[,,] board, Facet direction) { // Adds the undo data for movement Moving = true; LevelManager.current.AddUndoData(new BoardMovementState(this, pos1)); // Removes the pointers to this object in the area it leaves PerformOnFacet(ref board, Constants.FlipDirection(direction), false, (int x, int y, int z) => { if (board[x, y, z] is IMonoSpacious) { IMonoSpacious carrier = (IMonoSpacious)board[x, y, z]; carrier.Expecting = true; } else { board[x, y, z] = null; } return(true); }); // Adds the pointers to this object in the area it enters PerformOnFacet(ref board, direction, true, (int x, int y, int z) => { if (board[x, y, z] is IMonoSpacious) { IMonoSpacious carrier = (IMonoSpacious)board[x, y, z]; carrier.Expecting = false; carrier.Helper.Inhabitant = this; carrier.TileEnters(this); } else { board[x, y, z] = this; } return(true); }); // Sets its new position and adds it to the animation list Vector3Int newPos1 = GetPos1() + Constants.FacetToVector(direction); Vector3Int newPos2 = GetPos2() + Constants.FacetToVector(direction); SetCoords(new int[] { newPos1.x, newPos1.y, newPos1.z }, new int[] { newPos2.x, newPos2.y, newPos2.z }); MoveToPos(false); return(true); }
public override bool Move(TileElement[,,] board, Facet direction) { Moving = true; LevelManager.current.AddUndoData(new BoardMovementState(this, pos)); Vector3Int newPos = new Vector3Int(pos.x, pos.y, pos.z); if (direction == Facet.North) { newPos.x += 1; } if (direction == Facet.South) { newPos.x -= 1; } if (direction == Facet.Up) { newPos.y += 1; } if (direction == Facet.Down) { newPos.y -= 1; } if (direction == Facet.West) { newPos.z += 1; } if (direction == Facet.East) { newPos.z -= 1; } TileElement moveSubject = (board[pos.x, pos.y, pos.z] is IMonoSpacious) ? ((IMonoSpacious)board[pos.x, pos.y, pos.z]).Helper.GetSolidOccupant() : board[pos.x, pos.y, pos.z]; if (board[pos.x, pos.y, pos.z] is IMonoSpacious) { IMonoSpacious carrier = (IMonoSpacious)board[pos.x, pos.y, pos.z]; carrier.Expecting = true; } else { board[pos.x, pos.y, pos.z] = null; } if (board[newPos.x, newPos.y, newPos.z] is IMonoSpacious) { IMonoSpacious carrier = (IMonoSpacious)board[newPos.x, newPos.y, newPos.z]; carrier.Expecting = false; carrier.Helper.Inhabitant = this; carrier.TileEnters(this); } else { board[newPos.x, newPos.y, newPos.z] = this; } pos = newPos; MoveToPos(false); return(true); }
public override bool Fall(TileElement[,,] board) { // Massless objects can't fall if (Massless) { return(false); } // Add undo data since the only condition for not falling is being massless LevelManager.current.AddUndoData(new BoardMovementState(this, pos1)); // Find the tile underneath it that is solid int yBelow; for (yBelow = pos1.y - 1; yBelow >= 0; yBelow--) { bool canLand = PerformOnFacet(ref board, Facet.Down, true, (int x, int y, int z) => { return(!(board[x, yBelow, z] == null || (board[x, yBelow, z] is IMonoSpacious && ((IMonoSpacious)board[x, yBelow, z]).Helper.GetSolidOccupant() != null))); }).Contains(true); if (canLand) { break; } } // If falling is unnecessary, stop execution if (yBelow == pos1.y - 1) { return(false); } // Save the top of the object for later int yAbove = GetPos2().y + 1; // Clear the space that the object takes up for (int x = pos1.x; x <= pos2.x; x++) { for (int y = pos1.y; y <= pos2.y; y++) { for (int z = pos1.z; z <= pos2.z; z++) { if (board[x, y, z] is IMonoSpacious) { IMonoSpacious carrier = (IMonoSpacious)board[x, y, z]; carrier.Expecting = true; } else { board[x, y, z] = null; } } } } // Delete the object entirely if there is nothing to land on if (yBelow == -1) { for (int x = pos1.x; x <= pos2.x; x++) { for (int y = pos1.y; y <= pos2.y; y++) { for (int z = pos1.z; z <= pos2.z; z++) { if (board[x, y, z] is IMonoSpacious) { IMonoSpacious carrier = (IMonoSpacious)board[x, y, z]; carrier.Helper.RemoveInhabitant(); carrier.TileLeaves(); } else { board[x, y, z] = null; } } } } RemoveModel(); } // Otherwise, place the object in its new location else { pos2.y = yBelow + 1 + (pos2.y - pos1.y); pos1.y = yBelow + 1; Debug.Log("calls MoveToPos(true);"); MoveToPos(true); for (int x = pos1.x; x <= pos2.x; x++) { for (int y = pos1.y; y <= pos2.y; y++) { for (int z = pos1.z; z <= pos2.z; z++) { if (board[x, y, z] == null) { board[x, y, z] = this; } else if (board[x, y, z] is IMonoSpacious) { IMonoSpacious carrier = (IMonoSpacious)board[x, y, z]; carrier.Helper.Inhabitant = this; carrier.TileEnters(this); } } } } } // Make objects above this object fall as well LinkedList <TileElement> evaluatedTileElements = new LinkedList <TileElement>(); for (int x = pos1.x; x <= pos2.x; x++) { for (int z = pos1.z; z <= pos2.z; z++) { if (board[x, yAbove, z] != null && !board[x, yAbove, z].Checked) { board[x, yAbove, z].Fall(board); } } } return(true); }
public override bool Fall(TileElement[,,] board) { // Massless objects can't fall if (Massless) { return(false); } TileElement fallSubject = (board[pos.x, pos.y, pos.z] is IMonoSpacious) ? ((IMonoSpacious)board[pos.x, pos.y, pos.z]).Helper.GetSolidOccupant() : board[pos.x, pos.y, pos.z]; if (fallSubject == null || fallSubject.Massless) { return(false); } LevelManager.current.AddUndoData(new BoardMovementState(this, pos)); int y; for (y = pos.y - 1; y >= 0; y--) { if (!(board[pos.x, y, pos.z] == null || (board[pos.x, y, pos.z] is IMonoSpacious && ((IMonoSpacious)board[pos.x, y, pos.z]).Helper.GetSolidOccupant() != null))) { break; } } if (y == pos.y - 1) { Debug.Log("it doesnt need to fall"); return(false); } TileElement temp = (pos.y == board.GetLength(1) - 1) ? null : board[pos.x, pos.y + 1, pos.z]; if (board[pos.x, pos.y, pos.z] is IMonoSpacious) { IMonoSpacious carrier = (IMonoSpacious)board[pos.x, pos.y, pos.z]; carrier.Expecting = true; } else { board[pos.x, pos.y, pos.z] = null; } if (y == -1) { if (board[pos.x, pos.y, pos.z] is IMonoSpacious) { RemoveModel(); IMonoSpacious carrier = (IMonoSpacious)board[pos.x, pos.y, pos.z]; carrier.Helper.RemoveInhabitant(); carrier.TileLeaves(); } else { EditorDeleteTileElement(board); } } else { if (pos.y != y + 1) { pos.y = y + 1; MoveToPos(true); if (board[pos.x, pos.y, pos.z] == null) { board[pos.x, pos.y, pos.z] = this; } else if (board[pos.x, y, pos.z] is IMonoSpacious) { IMonoSpacious carrier = (IMonoSpacious)board[pos.x, pos.y, pos.z]; carrier.Helper.Inhabitant = this; carrier.TileEnters(this); } } } temp?.Fall(board); return(true); }