[TUTORIEL] Ignorer les invocations (+ Recherche autre cible) & Exemples de challenges

    Publicités

Users Who Are Viewing This Thread (Total: 1, Members: 0, Guests: 1)

Dampen_59

Membre
Feb 3, 2019
22
37
84
Discord
Dampen59 #4187
Bonjour,

Suite à la mise à jour de FlatyBot concernant l'intelligence artificielle, il est désormais possible de boucler dans la liste des entités en combat,
ce qui permet notamment d'ignorer les invocations.

Ignorer les invocations (basique)

Code:
    local entitiesList = fight:getAllEntities()
    local entitiesCount = fight:getEntitiesCount()
    local cellIDEnnemy = fight:getNearestEnemy()

    for i = 0, entitiesCount - 1 do
        if cellIDEnnemy == entitiesList[i].CellId then
            if entitiesList[i].Stats.summoned ~= true then
                -- pas une invocation
            else
                -- invocation
            end
        end
    end

Ce code n'est pas complet, à vous de l'ajuster pour qu'il convienne à vos besoins, notamment la partie "-- invocation".

Pour cette partie (-- invocation), je vous propose de soit :

  • Faire une deuxième boucle pour lancer le sort sur un autre ennemi que "cellIDEnnemy" en veillant bien à ce que celui-ci ne soit pas une invocation​
  • Se déplacer, se booster, enfin, ce que vous voulez.​

Pour la partie où l'entité n'est pas une invocation (-- pas une invocation) :
Votre routine d'attaque habituelle, vous pouvez attaquer "cellIDEnnemy" si vous le souhaitez.

EDIT du 18/06 13h : nous allons voir ensembles comment gérer la partie "-- invocation" avec la recherche d'une autre cible quand cela est possible.

Ignorer les invocations (+ Recherche autre cible)

Le but de cette partie est d'ajouter une recherche de cible différente de "fight:getNearestEnnemy()" alias "cellIDEnnemy" dans mon code ci-dessus quand cette cellule cible une invocation.

Pour cela, il faut d'abord boucler une seconde fois la liste des Entités afin de trouver le/les ennemi(s) n'étant pas une invocation, afin de récupérer leur identifiant de cellule.
Ensuite, il va falloir appeler une fonction (qui est votre routine de combat) mais une variante de cette fonction, c'est à dire qu'il faudra y ajouter un paramètre : un identifiant de cellule.

Lors d'un combat, on appellera la fonction SANS paramètres si "fight:getNearestEnnemy()" alias "cellIDEnnemy" ne cible PAS une invocation.
Sinon, on va appeler la fonction AVEC paramètres afin de cibler une autre entité que cette invocation.

Voici un exemple de ces fonctions :

Cas où le bot veut cibler un ennemi qui n'est pas une invocation, on appelle une fonction que je vais nommer à titre d'exemple "attaquer()" :

Code:
function attaquer()
    fight:launchSpellInCell(fight:getNearestEnemy(), "Le nom de mon sort")
end

Cette fonction est appelée quand "fight:getNearestEnnemy()" alias "cellIDEnnemy" ne cible pas une invocation.

Cas où le bot veut cibler un ennemi qui EST une invocation, je peux nommer la fonction de la même manière mais je dois lui donner un paramètre :

Code:
function attaquer(prmCellID)
    fight:launchSpellInCell(prmCellID, "Le nom de mon sort")
end

Cette fonction est appelée quand "fight:getNearestEnnemy()" alias "cellIDEnnemy" cible une invocation.

Mais il manque quelque chose dans cette fonction avec paramètres, elle ne nous retourne rien : aucune idée de savoir si la cible a été touchée ou pas.
Cela est pourtant nécessaire, car les monstres peuvent être dispersés un peu partout sur la carte, il faut donc s'assurer de vérifier si le sort a bien été lancé pour savoir si on continue, ou bien si on passe à une cible suivante.

Notre fonction deviens donc :

Code:
function attaquer(prmCellID)
    if (fight:launchSpellInCell(prmCellID, "Le nom de mon sort") == 0) then
        return true
    else
        return false
    end
end

Maintenant que cette fonction a une valeur de retour, nous pouvons passer à la partie qui détermine la nouvelle cible si "fight:getNearestEnnemy()" alias "cellIDEnnemy" cible une invocation. Pour cela, je vais réutiliser le code "Ignorer les invocations (basique)".

Code:
    local entitiesList = fight:getAllEntities()
    local entitiesCount = fight:getEntitiesCount()
    local cellIDEnnemy = fight:getNearestEnemy()

    for i = 0, entitiesCount - 1 do -- Pour chaque entités présentes dans le combat
        if cellIDEnnemy == entitiesList[i].CellId then -- Si l'entité est celle que le bot souhaite attaquer
            if entitiesList[i].Stats.summoned ~= true then -- Si l'entité n'est pas une invocation
                -- Ce n'est pas une invocation, on peut utiliser la fonction sans paramètres
                attaquer()
            else
                -- Ici, l'entité est une invocation, il faut donc déterminer une autre cible
              
                -- La variable ci-dessous (attacked) permet d'attaquer quand même l'invocation
                -- si aucune autre cible n'est trouvée
                local attacked = false -- Valeur qui permet de savoir si on a attaqué.
              
                -- On effectue notre deuxième boucle dans la liste des entités afin de
                -- déterminer notre nouvelle cible
                for j = 0, entitiesCount - 1 do
                    if entitiesList[j].Stats.summoned ~= true then -- Si l'entité n'est pas une invocation
                        local celluleToAttack = entitiesList[j].CellId -- On récupère la cellule du monstre
                      
                        -- On appelle notre fonction avec paramètre, si celle-ci retourne true, c'est qu'on
                        -- a réussi à attaquer la nouvelle cible, on peut donc sortir de la boucle (break).
                        if (attaquer(celluleToAttack) == true) then
                            attacked = true
                            break
                        end
                    end
                end
              
                -- Ici, on vérifie si dans notre deuxième boucle on a réussi à attaquer,
                -- si on a pas réussi (attacked = false), on attaque quand même l'invocation     
                if (attacked == false) then
                    attaquer()
                end
              
            end
        end
    end

J'ai commenté le code afin que vous le compreniez dans ses moindres détails.

A vous de jouer !


Exemple de gestion de challenges

Ce bout de code permet de gérer deux challenges simples :

Code:
challengeID = challenge:getChallengeId()

    if (challengeID == 1) then -- Challenge Zombie, 1 PM
        pmsToUse = 1
    elseif (challengeID == 2) then -- Chalenge Statue, 0 PM
        pmsToUse = 0
    else
        pmsToUse = fighter:getMP() -- On utilise tout les PM's
    end

Attention : Lors d'un combat avec deux challenges (exemple : donjon), la fonction "challenge:getChallengeId()" retournera l'identifiant du deuxième challenge.



Il suffit de se déplacer uniquement de "pmsToUse" dans vos fonctions afin de réussir le challenge.
Dû à la mise à jour, il est possible de gérer des challenges complexes comme "Ordonné" ou autres.

Si vous avez des questions ou des remarques, n'hésitez-pas à répondre à ce sujet.

EDIT 17/06 18h30 : Correction suite à une erreur dans FlatyBot (au niveau de la propriété "summoned" d'une entité)


 
Last edited:
  • Like
  • Love
Reactions: Lord_Nalid, 99.99%, mamynova and 4 others

Dampen_59

Membre
Feb 3, 2019
22
37
84
Discord
Dampen59 #4187
Pas de soucis, c'est avec plaisir.
Je vous annonce l'ajout de la partie "Recherche d'autres cibles" afin que vous ayez des exemples d'utilisation, celle-ci est très complète et prête à l'emploi.