Exemple #1
0
    void DrawAttackState(ProjectedGameState projectedState)
    {
        Sprite tileTargetedSprite = ScenarioImageManager.GetTileTargetedSprite();

        for (int i = 0; i < projectedState.attackedPositions.Count; i++)
        {
            EntityData activeEntity     = projectedState.activeEntity;
            Vector2Int attackedPosition = projectedState.attackedPositions[i];
            GenerateAndPositionCellImage(attackedPosition, 0f, tileTargetedSprite, activeEntity.IdentifyingColor);

            AttackCardData cardData      = projectedState.action.card as AttackCardData;
            Sprite         pointerSprite = cardData.cardImage;

            float rotation = GetImageRotation(projectedState.action.direction);

            GameObject abilityPointer = ScenarioImageManager.GetAbilityPointer(pointerSprite, rotation, transform);
            abilityPointer.transform.position = GetPointerImagePosition(activeEntity.Position, projectedState.action.direction);

            if (!drawingSelectedEntity)
            {
                Color pointerColor = Color.white;
                pointerColor.a = deselectedEntityActionOpacity;
                abilityPointer.GetComponent <Image>().color = pointerColor;
            }
        }
    }
Exemple #2
0
    public void DrawUpcomingStates(ScenarioState currentState, List <ProjectedGameState> upcomingStates)
    {
        Clear();
        drawingSelectedEntity = true;
        EntityData lastActiveEntity = null;

        for (int i = 0; i < upcomingStates.Count; i++)
        {
            ProjectedGameState projectedState = upcomingStates[i];

            if (projectedState.IsDummyState)
            {
                continue;
            }

            ProjectedGameState nextState = i == upcomingStates.Count - 1 ?
                                           null :
                                           upcomingStates[i + 1];

            DrawState(projectedState, nextState, lastActiveEntity);

            lastActiveEntity = projectedState.activeEntity;
        }

        DrawItemDurations(currentState.items);
        DrawEntityHealths(currentState.GetAllEntities());
    }
Exemple #3
0
    void UpdateCurrentlyResolvingState(ProjectedGameState projectedState)
    {
        ResetTurnOutlines();
        int turnIndex = currentlyDepictedTurns.FindIndex(t => t.Entity == projectedState.activeEntity);

        turnOutlines[turnIndex].effectColor = Color.yellow;
    }
Exemple #4
0
    void DrawMove(ProjectedGameState projectedState, ProjectedGameState nextState, EntityData movingEntity, EntityData lastActiveEntity)
    {
        Vector2Int positionThisState = movingEntity.Position;
        Vector2Int positionLastState = projectedState
                                       .scenarioState
                                       .lastGameState
                                       .GetEntityWhere(e => e.ID == movingEntity.ID)
                                       .Position;
        Vector2Int positionTwoStatesAgo = projectedState
                                          .scenarioState
                                          .lastGameState
                                          .lastGameState
                                          .GetEntityWhere(e => e.ID == movingEntity.ID)
                                          .Position;

        bool isEntitysFirstMove = positionLastState == positionTwoStatesAgo || movingEntity != lastActiveEntity;
        bool isEntitysLastMove  = nextState == null ||
                                  !nextState.scenarioState.HasEntityWhere(e => e == movingEntity) ||
                                  nextState.scenarioState.GetEntityWhere(e => e == movingEntity).Position == movingEntity.Position;

        if (isEntitysLastMove)
        {
            DrawPath_Ending(movingEntity, positionLastState, positionThisState);
        }
        else
        {
            if (isEntitysFirstMove)
            {
                DrawPath_Beginning(movingEntity, positionLastState, positionThisState);
            }
            DrawPath_Between(movingEntity, positionLastState, positionThisState, nextState.scenarioState.GetEntityWhere(e => e == movingEntity).Position);
        }

        int distanceCovered = BoardHelperFunctions.GetLinearDistanceBetweenPositions(positionLastState, positionThisState);

        if (distanceCovered > 1)
        {
            Direction directionToDestination = BoardHelperFunctions.GetDirectionFromPosition(positionLastState, positionThisState);
            GameBoard currentBoard           = BoardController.CurrentBoard;

            Tile lastTile              = currentBoard.GetTileAtPosition(positionLastState);
            Tile currentTile           = lastTile.GetDirectionalNeighbor(directionToDestination);
            Tile nextTile              = currentTile.GetDirectionalNeighbor(directionToDestination);
            int  intermediaryPathCount = 0;

            while (intermediaryPathCount < distanceCovered - 1)
            {
                DrawPath_Between(movingEntity, lastTile.Position, currentTile.Position, nextTile.Position);
                lastTile    = currentTile;
                currentTile = nextTile;
                nextTile    = currentTile.GetDirectionalNeighbor(directionToDestination);

                intermediaryPathCount++;
            }
        }
    }
Exemple #5
0
    static ProjectedGameState GetNextStateFromAction_Self(ScenarioState newState, EntityData entity, Action action)
    {
        SelfCardData card = action.card as SelfCardData;

        ProjectedGameState newProjectedState = new ProjectedGameState(entity, newState, action);

        entity.ChangeHealthValue_Scenario(card.healthChange, newState);

        card.modifiers.ForEach(m => entity.activeModifiers.Add(Object.Instantiate(m)));

        return(newProjectedState);
    }
    IEnumerator ProcessCurrentRoundActions()
    {
        isResolvingTurn = true;
        DeselectEverything();

        Queue <ProjectedGameState> upcomingStateQueue = new Queue <ProjectedGameState>(upcomingScenarioStates);

        while (upcomingStateQueue.Count > 0)
        {
            ProjectedGameState dequeuedProjectedState = upcomingStateQueue.Dequeue();
            GameStateDelegates.OnResolvingState?.Invoke(dequeuedProjectedState);
            ScenarioState nextScenarioState = dequeuedProjectedState.scenarioState;

            if (dequeuedProjectedState.bumps.Count > 0)
            {
                dequeuedProjectedState.bumps.ForEach(b => Debug.Log(b.bumpingEntity + " bumping " + b.bumpedEntity));
            }

            UpdateScenarioState(nextScenarioState);

            upcomingScenarioStates = new List <ProjectedGameState>(upcomingStateQueue);

            GameStateDelegates.OnCurrentScenarioStateChange(CurrentScenarioState, upcomingScenarioStates);
            dequeuedProjectedState.attackedPositions.ForEach(pos => GameStateDelegates.OnPositionAttacked(pos));

            yield return(new WaitForSeconds(0.5f));
        }

        if (CurrentScenarioState.isBossScenario && CurrentScenarioState.enemies.Count == 0)
        {
            winScreen.SetActive(true);
            yield break;
        }
        CurrentScenarioState.items = UpdateItemDurations(CurrentScenarioState);
        UpdateExitArrowVisibility();

        GameStateDelegates.OnRoundEnded?.Invoke(CurrentScenarioState);

        isResolvingTurn = false;
        upcomingScenarioStates.Clear();

        if (Player.CurrentHealth == 0)
        {
            lostScreen.SetActive(true);
            yield break;
        }

        GameStateDelegates.OnCurrentScenarioStateChange?.Invoke(CurrentScenarioState, upcomingScenarioStates);

        GenerateNextTurnStack(CurrentScenarioState);
    }
Exemple #7
0
    void DrawBump(EntityData bumpingEntity, ProjectedGameState projectedState, ProjectedGameState nextState, Bump bump)
    {
        Vector2Int positionTwoStatesAgo = projectedState
                                          .scenarioState
                                          .lastGameState
                                          .lastGameState
                                          .GetEntityWhere(e => e.ID == bumpingEntity.ID)
                                          .Position;
        Vector2Int positionThisState = bumpingEntity.Position;
        Vector2Int positionLastState = projectedState
                                       .scenarioState
                                       .lastGameState
                                       .GetEntityWhere(e => e.ID == bumpingEntity.ID)
                                       .Position;
        bool isEntitysFirstMove = positionLastState == positionTwoStatesAgo;

        bool bumpSucceeds = bumpingEntity.Position != positionLastState;

        if (bumpSucceeds)
        {
            DrawPath_Ending(bumpingEntity, positionLastState, positionThisState);
            DrawSuccessfulBumpEffect(positionThisState, BoardHelperFunctions.GetDirectionFromPosition(positionThisState, positionLastState));

            DrawPath_Beginning(bump.bumpedEntity, positionThisState, bump.bumpedEntity.Position);
        }
        else if (isEntitysFirstMove)
        {
            Vector2Int bumpedEntityPosition = bump.bumpedEntity.Position;
            Sprite     pathSprite           = ScenarioImageManager.GetPathSprite(PathType.Beginning);
            Direction  directionOfEntrance  = BoardHelperFunctions.GetDirectionFromPosition(bumpedEntityPosition, positionThisState);
            GenerateAndPositionCellImage(positionThisState, GetImageRotation(directionOfEntrance), pathSprite, bumpingEntity.IdentifyingColor);

            DrawFailedBumpEffect(positionThisState,
                                 BoardHelperFunctions.GetDirectionFromPosition(positionThisState, bumpedEntityPosition));
        }
        else
        {
            PathType   pathType             = GetFailedBumpPathType(positionTwoStatesAgo, positionThisState, bump.bumpedEntity.Position);
            Sprite     pathSprite           = ScenarioImageManager.GetPathSprite(pathType);
            Vector2Int bumpedEntityPosition = bump.bumpedEntity.Position;
            Direction  directionOfEntrance  = BoardHelperFunctions.GetDirectionFromPosition(positionThisState, positionTwoStatesAgo);

            GenerateAndPositionCellImage(positionThisState, GetImageRotation(directionOfEntrance), pathSprite, bumpingEntity.IdentifyingColor);
            DrawFailedBumpEffect(positionThisState,
                                 BoardHelperFunctions.GetDirectionFromPosition(positionThisState, bumpedEntityPosition));
        }
    }
Exemple #8
0
    void DrawState(ProjectedGameState projectedState, ProjectedGameState nextState, EntityData lastActiveEntity)
    {
        CardCategory actionCardCategory = projectedState.action.card.category;

        projectedState.GetMovedEntities().ForEach(e => DrawMove(projectedState, nextState, e, lastActiveEntity));

        //if (actionCardCategory == CardCategory.Movement)
        //{
        //    DrawMoveState(projectedState, nextState, lastActiveEntity);
        //}
        if (actionCardCategory == CardCategory.Attack)
        {
            DrawAttackState(projectedState);
        }

        projectedState.bumps.ForEach(b => DrawBump(b.bumpingEntity, projectedState, nextState, b));
    }
Exemple #9
0
    void DrawPath(EntityData activeEntity, ProjectedGameState projectedState, ProjectedGameState nextState)
    {
        bool isEntityAliveNextState = nextState == null || nextState
                                      .scenarioState
                                      .HasEntityWhere(e => e == activeEntity);
        bool isEntitysLastMove = projectedState.action.card.category == CardCategory.Movement &&
                                 (nextState == null ||
                                  nextState.action.card.category != CardCategory.Movement ||
                                  nextState.activeEntity.ID != activeEntity.ID);

        Vector2Int positionLastState = projectedState
                                       .scenarioState
                                       .lastGameState
                                       .GetEntityWhere(e => e.ID == activeEntity.ID)
                                       .Position;
        Vector2Int positionThisState = activeEntity.Position;

        if (isEntitysLastMove)
        {
            DrawPath_Ending(activeEntity, positionLastState, positionThisState);
            return;
        }

        bool isNextMoveFailedBump = nextState.DoesEntityBump(nextState.activeEntity) &&
                                    nextState.activeEntity.Position == activeEntity.Position;

        if (projectedState.action.card.category == CardCategory.Movement &&
            !isEntitysLastMove &&
            !isNextMoveFailedBump &&
            isEntityAliveNextState)
        {
            Vector2Int positionNextState = nextState
                                           .scenarioState
                                           .GetEntityWhere(e => e == activeEntity)
                                           .Position;

            DrawPath_Between(activeEntity, positionLastState, positionThisState, positionNextState);
        }
    }
Exemple #10
0
    void DrawMoveState(ProjectedGameState projectedState, ProjectedGameState nextState, EntityData lastActiveEntity)
    {
        EntityData activeEntity      = projectedState.activeEntity;
        Vector2Int positionThisState = activeEntity.Position;
        Vector2Int positionLastState = projectedState
                                       .scenarioState
                                       .lastGameState
                                       .GetEntityWhere(e => e.ID == activeEntity.ID)
                                       .Position;
        EntityData activeEntityTwoStatesAgo = projectedState
                                              .scenarioState
                                              .lastGameState
                                              .lastGameState
                                              .GetEntityWhere(e => e.ID == activeEntity.ID);

        bool isEntitysFirstMove = lastActiveEntity == null ||
                                  activeEntity.ID != lastActiveEntity.ID ||
                                  (activeEntity.ID == activeEntityTwoStatesAgo.ID &&
                                   activeEntity.Position == activeEntityTwoStatesAgo.Position);

        bool isFailedBump = projectedState.DoesEntityBump(activeEntity) &&
                            positionLastState == positionThisState;

        if (isEntitysFirstMove && !isFailedBump)
        {
            DrawPath_Beginning(activeEntity, positionLastState, positionThisState);
        }

        if (!projectedState.DoesEntityBump(activeEntity))
        {
            DrawPath(activeEntity, projectedState, nextState);
        }
        else
        {
            projectedState.bumps.ForEach(b => DrawBump(activeEntity, projectedState, nextState, b));
        }
    }
Exemple #11
0
    void HighlightSelectedEntityStates(EntityData selectedEntity, ScenarioState currentGameState, List <ProjectedGameState> upcomingStates)
    {
        Clear();
        EntityData lastActiveEntity = null;

        for (int i = 0; i < upcomingStates.Count; i++)
        {
            ProjectedGameState projectedState = upcomingStates[i];

            if (projectedState.IsDummyState)
            {
                continue;
            }

            ProjectedGameState nextState = i == upcomingStates.Count - 1 ?
                                           null :
                                           upcomingStates[i + 1];

            bool isEntityDeadThisState = !projectedState.scenarioState.HasEntityWhere(e => e == selectedEntity);
            bool didEntityDieThisState = projectedState.scenarioState.lastGameState.HasEntityWhere(e => selectedEntity == e);

            if (isEntityDeadThisState)
            {
                if (!didEntityDieThisState)
                {
                    drawingSelectedEntity = false;
                    DrawState(projectedState, nextState, lastActiveEntity);
                    lastActiveEntity = projectedState.activeEntity;
                    continue;
                }
                else
                {
                    drawingSelectedEntity = true;
                    DrawState(projectedState, nextState, lastActiveEntity);
                    lastActiveEntity = projectedState.activeEntity;
                    Vector2Int entityPositionLastState = projectedState.scenarioState
                                                         .lastGameState
                                                         .GetEntityWhere(e => e == selectedEntity)
                                                         .Position;
                    if (!projectedState.scenarioState.HasEntityWhere(e => e.Position == selectedEntity.Position) && selectedEntity.Position != entityPositionLastState)
                    {
                        GenerateAndPositionCellImage(entityPositionLastState, 0f, selectedEntity.entitySprite, translucent);
                    }
                    GenerateAndPositionCellImage(entityPositionLastState, 0f, deadEntitySprite, Color.white);
                    continue;
                }
            }

            Vector2Int selectedEntityPositionThisState = projectedState
                                                         .scenarioState
                                                         .GetEntityWhere(e => e == selectedEntity)
                                                         .Position;

            bool isSelectedEntityState    = projectedState.activeEntity == selectedEntity;
            bool isSelectedEntityBumped   = projectedState.IsEntityBumped(selectedEntity);
            bool isSelectedEntityAttacked = projectedState.attackedPositions.Contains(selectedEntityPositionThisState);

            if (isSelectedEntityState || isSelectedEntityBumped || isSelectedEntityAttacked)
            {
                drawingSelectedEntity = true;

                // Draw entity under attack targeting reticule if
                // (A) selected entity is hit OR
                // (B) selected entity is attacking & hits someone.
                projectedState
                .attackedPositions
                .Select(position => projectedState
                        .scenarioState
                        .GetTileOccupant(position))
                .Where(attackTarget => attackTarget != null && isSelectedEntityState || attackTarget == selectedEntity)
                .ToList()
                .ForEach(entity => boardController.DrawEntityAtPosition(entity, translucent));

                // Draw entities killed this turn.
                projectedState
                .scenarioState
                .lastGameState
                .GetAllEntities()
                .ForEach(e =>
                {
                    if (!projectedState.scenarioState.HasEntityWhere(projectedEntity => e == projectedEntity))
                    {
                        if (!currentGameState.HasEntityWhere(currentEntity => currentEntity.Position == e.Position))
                        {
                            GenerateAndPositionCellImage(e.Position, 0f, e.entitySprite, translucent);
                        }
                        GenerateAndPositionCellImage(e.Position, 0f, deadEntitySprite, Color.white);
                    }
                });
            }
            else
            {
                drawingSelectedEntity = false;
            }
            DrawState(projectedState, nextState, lastActiveEntity);
            lastActiveEntity = projectedState.activeEntity;
        }

        DrawEntityHealth(selectedEntity);
        DrawItemDurations(currentGameState.items);
    }
Exemple #12
0
 void ResolvingStateHandler(ProjectedGameState projectedState)
 {
     endRoundButton.interactable = false;
 }
Exemple #13
0
    static ProjectedGameState GetNextStateFromAction_Attack(ScenarioState newState, EntityData entity, Action action)
    {
        GameBoard      testBoard        = BoardController.CurrentBoard;
        AttackCardData card             = action.card as AttackCardData;
        TargetType     attackTargetType = card.targetType;

        Tile attackOriginTile = BoardController.CurrentBoard.GetTileAtPosition(entity.Position);

        List <Tile> targetTiles = new List <Tile>();

        switch (attackTargetType)
        {
        case TargetType.Single:
            targetTiles.Add(newState.FindFirstOccupiedTileInDirection(attackOriginTile, action.direction, action.distance));
            break;

        case TargetType.AreaOfEffect:
            Tile impactTile = newState.FindFirstOccupiedTileInDirection(attackOriginTile, action.direction, action.distance);
            targetTiles.Add(impactTile);
            targetTiles.AddRange(impactTile.Neighbors);
            break;

        case TargetType.Line:
            targetTiles.AddRange(attackOriginTile.GetAllTilesInDirection(action.direction, action.card.range));
            break;

        default:
            break;
        }

        ProjectedGameState newProjectedState = new ProjectedGameState(entity, newState, action);

        newProjectedState.AddAttackedPositions(targetTiles.Select(t => t.Position));

        List <EntityData> affectedEntities = targetTiles
                                             .Select(t => newState.GetTileOccupant(t))
                                             .Where(o => o != null)
                                             .ToList();

        if (affectedEntities.Count == 0)
        {
            List <ModifierData> modifiersToResolve = action.card.modifiers
                                                     .Where(m =>
                                                            m.modifierCategory == ModifierCategory.Blowback ||
                                                            m.modifierCategory == ModifierCategory.FollowUp)
                                                     .ToList();

            for (int i = 0; i < modifiersToResolve.Count; i++)
            {
                ModifierData modifier = modifiersToResolve[i];
                ApplyModifierToAttack_BlowbackFollowUp(modifier, entity, newState, action.direction, modifier.modifierCategory);
            }

            return(newProjectedState);
        }

        for (int i = 0; i < affectedEntities.Count; i++)
        {
            EntityData affectedEntity = affectedEntities[i];

            int cardDamage = card.damage + entity.GetAttackModifierValue();
            affectedEntity.DealDamage(cardDamage, newState);

            List <ModifierData> attackModifiers = action.card.modifiers;
            if (attackModifiers != null && attackModifiers.Count > 0)
            {
                for (int j = 0; i < attackModifiers.Count; i++)
                {
                    ApplyModifierToAttack(affectedEntity, attackModifiers[j], entity, newState, action.direction);
                }
            }
        }

        return(newProjectedState);
    }
Exemple #14
0
    public static List <ProjectedGameState> CalculateUpcomingStates(ScenarioState currentState, GameBoard board)
    {
        List <ProjectedGameState> projectedGameStates = new List <ProjectedGameState>();

        ScenarioState mostRecentState = currentState.DeepCopy();

        mostRecentState.lastGameState = currentState;

        Vector2Int lastPlayerPosition = currentState.player.Position;

        while (mostRecentState.turnStack.Count > 0)
        {
            Turn       turn   = mostRecentState.turnStack.Pop();
            EntityData entity = turn.Entity;

            foreach (Direction move in turn.moves)
            {
                bool entityIsAliveToMove = mostRecentState.HasEntityWhere(e => e == entity);

                if (!entityIsAliveToMove)
                {
                    break;
                }

                ProjectedGameState updatedState = GetNextGameStateFromMove(mostRecentState, entity, move);
                entity = updatedState.activeEntity;

                projectedGameStates.Add(updatedState);

                mostRecentState = updatedState.scenarioState;

                if (updatedState.bumps.Count > 0)
                {
                    break;
                }
            }

            if (projectedGameStates.Count > 0)
            {
                projectedGameStates.Last().scenarioState.CollectFinishMoveItems();
            }

            bool entityIsStillAlive = mostRecentState.HasEntityWhere(e => e == entity);

            if (!entityIsStillAlive)
            {
                continue;
            }

            if (turn.action.card != null)
            {
                ProjectedGameState updatedState = GetNextGameStateFromAction(mostRecentState, entity, turn.action);
                entity = updatedState.activeEntity;
                projectedGameStates.Add(updatedState);

                mostRecentState = updatedState.scenarioState;
            }

            UpdateEntityModifiers(entity, mostRecentState);
        }

        // TODO: As-is, this was causing a bunch of problems with state calculation. Gotta bugfix it.
        // If enemies dead, duplicate current gamestate, just for stagnation projection purposes.
        //if (projectedGameStates.Count == 0)
        //{
        //    ProjectedGameState fillerGameState = new ProjectedGameState(currentState.DeepCopy());
        //    projectedGameStates.Add(fillerGameState);
        //}

        //ScenarioState lastCalculatedState = projectedGameStates.Last().scenarioState;

        //lastCalculatedState.UpdateStagnation(board);
        //lastCalculatedState.stagnatedPositions.ForEach(p =>
        //{
        //    EntityData stagnatedEntity = lastCalculatedState.GetTileOccupant(p);
        //    if (stagnatedEntity != null)
        //    {
        //        stagnatedEntity.DealDamage(1, lastCalculatedState);
        //    }
        //});

        return(projectedGameStates);
    }