예제 #1
0
    public static bool IsTileOccupied(this ScenarioState state, Vector2Int originPosition, Direction directionFromOrigin, int distanceFromOrigin)
    {
        Vector2Int updatedPosition = originPosition;

        switch (directionFromOrigin)
        {
        case Direction.Up:
            updatedPosition.y -= distanceFromOrigin;
            break;

        case Direction.Down:
            updatedPosition.y += distanceFromOrigin;
            break;

        case Direction.Left:
            updatedPosition.x -= distanceFromOrigin;
            break;

        case Direction.Right:
            updatedPosition.x += distanceFromOrigin;
            break;

        default:
            break;
        }

        return(state.IsTileOccupied(updatedPosition.x, updatedPosition.y));
    }
예제 #2
0
    static ProjectedGameState GetNextGameStateFromMove(ScenarioState lastState, EntityData entity, Direction move)
    {
        ScenarioState newState = lastState.DeepCopy();

        newState.lastGameState = lastState;
        EntityData entityCopy        = newState.GetAllEntities().Find(e => entity.ID == e.ID);
        Tile       currentEntityTile = BoardController.CurrentBoard.GetTileAtPosition(entityCopy.Position);

        Action stateAction = new Action(GenericMovementCard, entity, move, 1);

        // If entity can't move that direction, return state as-is.
        if (!currentEntityTile.ConnectsToNeighbor(move))
        {
            return(new ProjectedGameState(entityCopy, newState, stateAction));
        }

        Tile nextTile = currentEntityTile.GetDirectionalNeighbor(move);

        // If tile is empty, move entity there and return.
        if (!newState.IsTileOccupied(nextTile))
        {
            entityCopy.SetPosition(nextTile.Position, newState);
            return(new ProjectedGameState(entityCopy, newState, stateAction));
        }

        EntityData tileOccupant = newState.GetTileOccupant(nextTile.Position);

        ResolveBump(entity, tileOccupant, move, newState);

        Bump bump = new Bump(entityCopy, tileOccupant);

        return(new ProjectedGameState(entityCopy, newState, stateAction, bump));
    }
예제 #3
0
    // TODO: Very rudimentary AI rn, assumes all enemies rushing at player, need some
    // switch logic for different AI types.
    public void CalculateAndQueueEnemyTurns(ScenarioState gameState)
    {
        GameBoard         currentBoard = BoardController.CurrentBoard;
        List <EntityData> enemies      = gameState.enemies;

        upcomingEntityTargets.Clear();

        currentlyOccupiedTiles = enemies.Select(enemy => currentBoard.GetTileAtPosition(enemy.Position)).ToList <Tile>();

        foreach (EntityData enemy in enemies)
        {
            Tile enemyTile = currentBoard.GetTileAtPosition(enemy.Position);

            MovementCardData enemyMovementCard = enemy.movementCard;
            int enemyMoveRange = enemyMovementCard.range + enemy.GetMovementModifierValue();

            AttackCardData enemyAttackCard  = enemy.attackCard;
            int            enemyAttackRange = enemyAttackCard.range;

            List <EntityTurnTargets> possibleEntityTurns  = enemyTile.GetAllPossibleEntityTurns(enemyMoveRange, enemyAttackRange);
            List <EntityTurnTargets> sortedPotentialTurns = SortTurnTargetsByValue(enemyTile, possibleEntityTurns, gameState);
            int turnIndex = 0;
            EntityTurnTargets selectedTurnTargets       = sortedPotentialTurns[turnIndex];
            List <Direction>  movesToTargetMovementTile = BoardHelperFunctions.FindPathBetweenTiles(enemyTile, selectedTurnTargets.targetMovementTile);
            List <Tile>       tilesToTargetMovementTile = BoardHelperFunctions.GetTilesOnPath(enemyTile, movesToTargetMovementTile);

            // Enemies will not move through traps if they have any other moves available.
            while (turnIndex < sortedPotentialTurns.Count &&
                   tilesToTargetMovementTile.Any(tile => gameState.DoesPositionContainItemWhere(tile.Position, item => item.itemCategory == ItemCategory.Trap) ||
                                                 gameState.IsTileOccupied(tile)))
            {
                turnIndex++;
                selectedTurnTargets       = sortedPotentialTurns[turnIndex];
                movesToTargetMovementTile = BoardHelperFunctions.FindPathBetweenTiles(enemyTile, selectedTurnTargets.targetMovementTile);
                tilesToTargetMovementTile = BoardHelperFunctions.GetTilesOnPath(enemyTile, movesToTargetMovementTile);
            }

            if (turnIndex == sortedPotentialTurns.Count)
            {
                selectedTurnTargets = sortedPotentialTurns[0];
            }

            upcomingEntityTargets.Add(selectedTurnTargets);
            int       rangeOfProjectedAttack = BoardHelperFunctions.GetLinearDistanceBetweenTiles(selectedTurnTargets.targetMovementTile, selectedTurnTargets.targetAttackTile);
            Direction attackDirection        = BoardHelperFunctions.GetDirectionFromPosition(selectedTurnTargets.targetMovementTile.Position, selectedTurnTargets.targetAttackTile.Position);

            Action enemyAction = new Action(enemyAttackCard, enemy, attackDirection, rangeOfProjectedAttack);

            Turn enemyTurn = new Turn(enemy, movesToTargetMovementTile, enemyAction);

            turnStackController.AddNewTurn(enemyTurn);
        }
    }
예제 #4
0
    static ScenarioState RandomizeItemStartingCoordinates(ScenarioState state, List <ItemData> items, Vector2Int exit, int boardWidth)
    {
        for (int i = 0; i < items.Count; i++)
        {
            ItemData item = items[i];

            Vector2Int newPosition = GenerateRandomVector2IntInBounds(boardWidth);
            while (state.IsTileOccupied(newPosition) || state.DoesPositionContainItem(newPosition) || exit == newPosition)
            {
                newPosition = GenerateRandomVector2IntInBounds(boardWidth);
            }

            item.Position = newPosition;
        }

        return(state);
    }
예제 #5
0
    static void ResolveBump(EntityData bumper, EntityData bumpee, Direction bumpDirection, ScenarioState state)
    {
        Tile projectedBumpTile = BoardController
                                 .CurrentBoard
                                 .GetTileAtPosition(bumpee.Position);

        bool bumpCanPush = projectedBumpTile != null && !state.IsTileOccupied(projectedBumpTile);

        if (bumpCanPush)
        {
            Vector2Int projectedBumpPosition = projectedBumpTile.Position;
            bumper.SetPosition(bumpee.Position, state);
            bumpee.SetPosition(projectedBumpPosition, state);
        }

        bumpee.DealDamage(1, state);
        bumper.DealDamage(1, state);
    }
예제 #6
0
    public static Tile FindFirstOccupiedTileInDirection(this ScenarioState state, Tile originTile, Direction direction, int distance)
    {
        Tile currentTargetTile = originTile;
        Tile testTargetTile    = originTile.GetDirectionalNeighbor(direction);

        while (distance > 0 && testTargetTile != null)
        {
            currentTargetTile = testTargetTile;
            testTargetTile    = currentTargetTile.GetDirectionalNeighbor(direction);

            if (state.IsTileOccupied(currentTargetTile))
            {
                break;
            }

            distance--;
        }

        return(currentTargetTile);
    }
예제 #7
0
 public static bool IsTileOccupied(this ScenarioState state, int x, int y)
 {
     return(state.IsTileOccupied(new Vector2Int(x, y)));
 }
예제 #8
0
 public static bool IsTileOccupied(this ScenarioState state, Tile tile)
 {
     return(state.IsTileOccupied(tile.Position));
 }
예제 #9
0
 public static bool IsUnoccupied(this Tile tile, ScenarioState state)
 {
     return(!state.IsTileOccupied(tile));
 }