Пример #1
0
    // The first fighter will always be the action character, and the second, the target character.
    public List <CharacterBehavior> SearchFighters(CharacterBehavior attacker, CharacterBehavior opponent)
    {
        List <CharacterBehavior>  fighters = new List <CharacterBehavior>();
        Queue <CharacterBehavior> queue    = new Queue <CharacterBehavior>();

        System.Action <CharacterBehavior> SelectFighter = (fighter) =>
        {
            if (!fighters.Contains(fighter))
            {
                fighters.Add(fighter);
                queue.Enqueue(fighter);
            }
        };

        SelectFighter(attacker);
        SelectFighter(opponent);

        while (queue.Count > 0)
        {
            CharacterBehavior currentFighter = queue.Dequeue();
            CaseBehavior      currentCell    = currentFighter.caseActuelle.GetComponent <CaseBehavior>();

            // Propagate in all directions
            for (int dir = 0; dir < 4; ++dir)
            {
                if (!currentCell.debordement(dir) && currentCell.cheminDegage(currentCell.versDirection(dir)))
                {
                    CaseBehavior nextCell = currentCell.getCaseVers(dir);

                    if (nextCell.isCaseRevealed() && nextCell.cheminDegage(nextCell.versDirection(CaseBehavior.opposee(dir))) && nextCell.enemyFighterPresent(currentFighter.gameObject))
                    {
                        if (nextCell.isNonWoundedEnemyPresent(currentFighter.gameObject))
                        {
                            foreach (CharacterBehavior character in nextCell.characters)
                            {
                                SelectFighter(character);
                            }
                        }
                    }
                }
            }
        }

        return(fighters);
    }
Пример #2
0
    // Recherche A* iterative de ligne de vue
    List <CaseBehavior> getLineOfSight(CaseBehavior fromCell)
    {
        List <CaseBehavior> charactersOnSight = new List <CaseBehavior>();

        // Propagate in all directions
        for (int dir = 0; dir < 4; ++dir)
        {
            CaseBehavior currentCell     = fromCell;
            bool         gotToSightLimit = false;
            while (!gotToSightLimit)
            {
                if (!currentCell.debordement(dir) && currentCell.cheminDegage(currentCell.versDirection(dir)))
                {
                    CaseBehavior nextCell = currentCell.getCaseVers(dir);
                    if (nextCell.isCaseRevealed() && nextCell.cheminDegage(nextCell.versDirection(CaseBehavior.opposee(dir))))
                    {
                        if (nextCell.characters.Count > 0)
                        {
                            charactersOnSight.Add(nextCell);
                            gotToSightLimit = true;
                        }
                        else
                        {
                            currentCell = nextCell;
                        }
                    }
                    else
                    {
                        gotToSightLimit = true;
                    }
                }
                else
                {
                    gotToSightLimit = true;
                }
            }
        }
        return(charactersOnSight);
    }
Пример #3
0
    // Recherche A* iterative de deplacement et saut
    void SearchPath(CaseBehavior startCell, int depth, bool jump)
    {
        Queue <CaseBehavior> queue = new Queue <CaseBehavior>();

        RegisterAction(ActionType.WALK, startCell, 0);
        if (jump)
        {
            RegisterAction(ActionType.JUMP, startCell, 0);
        }
        if (depth > 0)
        {
            queue.Enqueue(startCell);
        }

        // Proof that this iterative BFS (Broad-First-Search) has no redundancy:
        // If we can only jump through a cell, there will be only one register of this cell.
        // If we can jump and move through the same cell (therefore as first move), then the code will discard the jump.
        // Since the priority increase with depth, no cell will be registered twice for move (due to register priority check)
        // As a conclusion: we guarantee no redundant check.
        while (queue.Count > 0)
        {
            CaseBehavior currentCell = queue.Dequeue();
            int          priority    = GetActionPriority(ActionType.WALK, currentCell); // 0: init, depth: stop, MAX: JumpStart

            Debug.Assert(!currentCharacter.surLaRegletteAdverse(currentCell));

            // Propagate in all directions
            for (int dir = 0; dir < 4; ++dir)
            {
                if (!currentCell.debordement(dir) && currentCell.cheminDegage(currentCell.versDirection(dir)))
                {
                    CaseBehavior nextCell = currentCell.getCaseVers(dir);
                    if (nextCell.isCaseRevealed() && nextCell.cheminDegage(nextCell.versDirection(CaseBehavior.opposee(dir))) && (currentCharacter is CB_Magicien || !nextCell.isNonWoundedEnemyPresent(currentCharacter.gameObject)))
                    {
                        // Si la case suivante est traversable et le mouvement precedent n'est pas un saut, enregistrer un mouvement.
                        if (currentCharacter.canCrossCell(nextCell) && priority != MAX_PRIORITY)
                        {
                            if (priority + 1 == depth)
                            {
                                // Si ce n'est pas la case finale, on doit pouvoir terminer le mouvement sur cette case.
                                // WARNING: le cas d'un couloir de plusieurs cases contenant plusieur cases non finales n'est pas pris en compte.
                                //          (possibilite d'effectuer un mouvement qui devra etre annule par la suite)
                                if (currentCharacter.canStayOnCell(nextCell))
                                {
                                    RegisterAction(ActionType.WALK, nextCell, priority + 1, currentCell);
                                }
                            }
                            else
                            {
                                // propage le mouvement si besoin.
                                if (RegisterAction(ActionType.WALK, nextCell, priority + 1, currentCell) && !currentCharacter.surLaRegletteAdverse(nextCell))
                                {
                                    queue.Enqueue(nextCell);
                                }
                            }
                        }
                        // si le saut est permis et que c'est le premier mouvement, initier un saut
                        else if (priority == 0 && jump)
                        {
                            if (RegisterAction(ActionType.JUMP, nextCell, 1, currentCell))
                            {
                                queue.Enqueue(nextCell);
                            }
                        }
                        // sinon si le mouvement precedent etait un saut, enregistrer la fin du saut si possible.
                        else if (priority == MAX_PRIORITY && currentCharacter.canStayOnCell(nextCell))
                        {
                            RegisterAction(ActionType.JUMP, nextCell, 2, currentCell);
                        }
                    }
                }
            }
        }
    }
Пример #4
0
    // Vérifie l'ensemble des actions spéciales qui peuvent etre exécutées depuis la case actuelle vers la direction ciblée
    public void checkAdjacentCell(CaseBehavior currentCell, int dir)
    {
        if (!currentCell.debordement(dir))
        {
            CaseBehavior nextCell = currentCell.getCaseVers(dir);

            if (!nextCell.isCaseRevealed())
            {
                // Si une salle non ouverte est adjacente et accessible, en permettre l'ouverture
                if (currentCell.cheminDegage(currentCell.versDirection(dir)))
                {
                    RegisterAction(ActionType.REVEAL, nextCell, 0);
                }
            }
            else
            {
                // Accès à la case pour vérifier que l'on peut s'y déplacer
                if (currentCell.cheminDegage(currentCell.versDirection(dir)) && nextCell.cheminDegage(nextCell.versDirection(CaseBehavior.opposee(dir))))
                {
                    // Regarder si un combat est possible
                    if (nextCell.enemyFighterPresent(currentCharacter.gameObject))
                    {
                        RegisterAction(ActionType.ATTACK, nextCell, 0);
                    }

                    if (currentCharacter is CB_Clerc)
                    {
                        // Regarder si un allie peut etre soigne
                        if (nextCell.woundedCharacterReadyForHealing())
                        {
                            RegisterAction(ActionType.HEAL, nextCell, 0);
                        }
                    }
                }

                // Si une herse non brisee relie cette case
                if (nextCell.herse != null && currentCell.herse == nextCell.herse && !nextCell.herse.GetComponent <HerseBehavior>().herseBrisee)
                {
                    if (currentCharacter is CB_Guerrier)
                    {
                        RegisterAction(ActionType.DESTROYDOOR, nextCell, 0);
                    }
                    else if (currentCharacter is CB_Voleuse)
                    {
                        if (currentCell.herse.GetComponent <HerseBehavior>().herseOuverte)
                        {
                            RegisterAction(ActionType.CLOSEDOOR, nextCell, 0);
                        }
                        else
                        {
                            RegisterAction(ActionType.OPENDOOR, nextCell, 0);
                        }
                    }
                }
            }
        }

        if (currentCharacter is CB_PasseMuraille)
        {
            if (!currentCell.debordement(dir))
            {
                // Peut franchir les murs adjacents
                CaseBehavior nextCell = currentCell.getCaseVers(dir);
                if (nextCell.isCaseRevealed())
                {
                    if (currentCell.versDirection(dir) == CaseBehavior.cheminCaseAdjacente.mur ||
                        nextCell.versDirection(CaseBehavior.opposee(dir)) == CaseBehavior.cheminCaseAdjacente.mur
                        )
                    {
                        if (currentCharacter.canStayOnCell(nextCell))
                        {
                            RegisterAction(ActionType.WALLWALK, currentCell, 0);
                            RegisterAction(ActionType.WALLWALK, nextCell, 1, currentCell);
                        }
                    }
                }
            }
        }
    }