예제 #1
0
    // 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);
    }
예제 #2
0
    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);
    }
예제 #3
0
    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);
    }
예제 #4
0
    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);
    }