Les bases de l'édition dans ARMA 3

Les scripts et les missions des [V]Vétérans

Vous pouvez poser vos questions et poster vos scripts, le forum est ouvert à tous.
Avatar de l’utilisateur
Tyrghen
Membre des [V]Vétérans
Messages : 4119
Inscription : 14 oct. 2012, 22:47

Les déclencheurs

Message par Tyrghen » 27 oct. 2014, 13:20

Mise à jour:27/10/2014

Les déclencheurs

Les déclencheurs (trigger en anglais) permettent de réagir sur des événements dans ArmA. Par exemple, l'arrivée des joueurs sur un point, la prise d'une zone par les BLUFOR, la mort d'une unité, etc.
C'est l'un des éléments les plus importants pour créer une mission qui répond aux actions des joueurs.

Un déclencheur va exécuter les commandes situées dans son champ d'activation lorsque les conditions requises sont vraies.
Si ce déclencheur est du type répétitif, il peut s'activer plusieurs fois. Lorsque la condition redevient fausse, les commandes situées dans son champ de désactivation sont exécutées.
Je rentrerai un peu plus dans les détails ci-dessous.


Placer un déclencheur

Pour placer un déclencheur, il suffit de sélectionner l'option "Déclencheur" dans le menu Image et ensuite de double cliquer sur carte à l'endroit voulu.
Une nouvelle fenêtre va s'ouvrir pour configurer le déclencheur.

Image

Dans les points suivants je vais parcourir les bases de la configuration des déclencheurs.


La forme du déclencheur

Comme son nom l'indique, cette zone sert à donner une forme au déclencheur pour délimiter la zone de détection.
Dans certains cas, par exemple quand on veut simplement lancer un script ou bien lier le déclencheur à un module ou un point de passage, on donnera une zone de déclencheur nulle ( Axe A et B égaux à 0), simplement pour ne pas encombrer l'éditeur avec des cercles dans tous les sens.

Image


Chrono du déclencheur

Image

Dans certains cas, on ne veut pas qu'un déclencheur s'active directement, on veut un certain délai. Pour laisser par exemple le temps aux joueurs de réagir ou bien pour avoir un enchaînement d'actions basées sur le même événements (on met un temps plus long pour chaque action).

Pour chaque déclencheur on peut choisir entre 2 types de minuterie:
  • Compte à rebours:
    Dans ce cas, lorsque l'événement se produit (une unité BLUFOR entre dans la zone par exemple) le déclencheur commence à compter, une fois le temps atteint, l'action se déclenche. Même si l'unité BLUFOR est déjà sortie de la zone, l'action se déclenchera.
  • Dépasser délai:
    A l'inverse, lorsqu'on sélectionne "Dépass. délai", il faut que l'événement reste actif pendant toute la durée du compte. Si ce n'est pas le cas, on revient à zéro. Donc, pour l'exemple ci-dessus, il faut que l'unité BLUFOR reste dans la zone pendant toute la durée du compte.
Un bon exemple de l'utilisation de "Dépasser délai", c'est lorsque vous voulez contrôler la présence d'ennemis dans une zone à conquérir. Si un ou plusieurs ennemis grenouillent à la limite de la zone, ils rentrent et sortent, Si on met un compte à rebours ou pas de compte du tout, la prise de la zone sera validée alors qu'il y a encore des ennemis.
Avec un délai à dépasser, on ne validera la zone que si les ennemis ne sont pas présents pendant un certain temps (personnellement je choisi souvent 20 ou 30 secondes).



Nom du déclencheur

Il peut être utile de donner un nom au déclencheur, simplement pour pouvoir l'utiliser, soit dans d'autres déclencheurs, soit dans sa propre condition. Il s'agit ici d'un nom de variable/objet. Il doit donc être alphanumérique, sans caractères spéciaux.
Image

Les deux commandes que j'utilise avec un déclencheur sont:
  • triggerActivated: permet de contrôler si un trigger est actif
    Par exemple, ça permet de déclencher l'arrivée d'un groupe de renforts lorsque les joueurs atteignent une certaine zone.
  • list: donne la liste de toutes les unités qui activent le trigger en question
    Je l'utlise essentiellement pour savoir si parmis les unités présentes il y a des joueurs ou des IAs.
    Ou alors pour tester la présence d'unités spéciales de la mission
Exemple:
J'ai placé un convoi d'IA OPFOR sur carte, les véhicules sont nommés: "eni1", "eni2", "eni3".
Je place sur la route un déclencheur qui ne doit s'activer que lorsque ces véhicules passent.

Je place donc un déclencheur nommé "trigger_passage" avec une activation de type "OPFOR" et je modifie la condition pour qu'il ne s'active que pour les trois véhicules précités:

Code : Tout sélectionner

(eni1 in list trigger_passage) OR (eni2 in list trigger_passage) OR (eni3 in list trigger_passage)
La commande in permet de savoir si l'objet donné est présent dans la liste.
Je teste si eni1 est dans la liste des unités du déclencheur ou (OR) si eni2 est dans la liste des unités ou (OR) etc.

Image

Remarque: Pour ce problème particulier, j'aurais simplement pu lier le déclencheur et le groupe de chaque véhicule en utilisant l'outil de groupement Image. Un exemple concret est donné plus loin dans ce tutoriel.



Types de déclencheur

Image
  • Néant: c'est le type par défaut, un déclencheur classique qui teste sa condition et éxécute les commandes du champ "Sur Act." quand la condition devient vraie.
  • Interrupteur: c'est un type spécial qui permet de désactiver un point de passage et de passer au suivant. Certains points de passage comme "Garder/Guard" n'ont pas de fin. Si vous placez ce point dans le parcours d'un groupe. Il restera là indéfiniment. Pour passer au point de passage suivant, vous devez synchroniser un déclencheur de type "Interrupteur" avec le point de passage en utilisant l'outil "Synchroniser" Image
  • Fin n°X: Active la fin de la mission pour une réussite
  • Perdre: Active l'échec de la mission
  • Gardé par X: Si vous voulez définir des zones spécifiques à garder, vous pouvez placer un déclencheur de type "Gardé par". Dans ce cas, le groupe qui a un point de passage de type "Garder" le plus proche, va se diriger vers le centre de ce déclencheur et défendre la zone.
    Si vous placez plusieurs déclencheurs de type "Gardé par", leur priorité est l'ordre de placement, le premier placé est le plus prioritaire.
    Dans ce cas, chaque groupe avec un point de passage prendre un déclencheur à garder. Et dans le cas d'une attaque ennemie, c'est le groupe avec le déclencheur de priorité la plus faible qui se déplacera en premier.
    Si c'est confus... c'est normal... je pense que je ferai un tutoriel à part complet pour ce type de déclencheur.


Activation du déclencheur

La condition d'activation d'un déclencheur est la somme de 3 éléments.
  1. La source de l'activation
    Image
  2. Le nombre d'exécutions de l'activation
    Image
  3. Le type d'activation
    Image
Ces 3 éléments forment la condition "this" du déclencheur dont on va parler juste après.
Mais d'abord, passons en détail les 3 points.

Les sources d'activation:
  • Néant: ça sonne inutile, mais si vous voulez utiliser un activation par script ou fonction, vous pouvez utiliser néant pour alléger les tests fait par le déclencheur.
    Prenons comme exemple, vous voulez envoyer un message lorsque le chef des ennemis meurt.
    La condition sera du type: !alive leader_ennemi
    On n'utilise pas la valeur "this" du déclencheur, ni les unités qui activent le déclencheur, donc inutile de remplir quelque chose ici. Ca va simplement alourdir le déclencheur.
  • Un camp (Opfor, Blufor, etc.): dans ce cas, le déclencheur deviendra actif basé sur les unités du camp spécifié
  • N'importe qui / Any: dans ce cas, toute unité (à pied ou en véhicule) qui passera dans la zone du déclencheur, va activer celui-ci
  • Radio XYZ: Le fait de sélectionner un canal radio, permet d'ajouter une option au menu radio des joueurs et donc de permettre au joueur de déclencher l'action. Par exemple, l'appel d'un hélicoptère d'extraction. Je donne un exemple plus en détail à la fin de ce tutoriel
  • Pris - Camp: Si la zone du déclencheur est occupée par le camp, le déclencheur s'active
    Une zone est considérée comme prise si le nombre d'ennemis est égal ou inférieur au nombre d'unités du camp défini.
    Pour être encore plus clair... si vous sélectionnez "Pris - Ouest". Si la zone contient 10 OPFOR, qu'il y a 4 joueurs, lorsque vous aurez tué 6 OPFOR, la zone sera prise, même si des OPFOR sont encore en vie.
Le nombre d'activations:
On a le choix entre "Une fois" et "Répétition".
Je pense que c'est assez clair lequel fait quoi :)
Parfois il est utile d'avoir un déclencheur de type "Répétition" pour laisser par exemple une zone passer de l'ennemi à l'allié et inversément.
Ou alors pour déclencher une alarme si une unité est détectée, etc.

Le type d'activation:
  • Présent: détecte si au moins une unité du camp spécifié est présente
  • Absent: détecte si il n'y a plus du tout d'unités de ce camp (si elles sont toutes parties ou toutes mortes)
  • Détection par XYZ: là c'est plus subtil. On va partir sur un exemple.
    Prenons le cas d'un déclencheur avec comme source "BLUFOR" et comme type d'activation "Détection par est".
    Le déclencheur ne s'activera que lorsqu'au moins une unité du camp est présente dans la zone du déclencheur, saura avec certitude qu'un Blufor est là. Le niveau de connaissance d'une unité est affecté par de nombreux éléments. Comme, la distance, la nuit, etc.
    Il est très difficile d'évaluer à quelle vitesse les unités auront vent de votre présence. Si vous utilisez un addon comme l'ASR AI, ça devient encore plus difficile, parce que cet addon transfère l'information vers les groupes distants pour simuler une communication radio.
    Généralement je limite mon utilisation de ce déclencheur à l'appel de renforts lorsque les combats on commencé.


La condition d'activation du déclencheur

Par défaut, le champ de condition contient la variable "this". C'est une variable spéciale qui contient le résultat des conditions que nous avons vue dans les points ci-dessus.

Image

Cette valeur n'est pas obligatoire. On peut très bien s'en passer. Dans ce cas on peut entrer des commandes qui doivent renvoyer une valeur booléenne (Vrai ou Faux).
Par exemple, on peut vouloir détecter si le leader ennemi est mort. Dans ce cas le champ "Condition" contiendra:

Code : Tout sélectionner

!alive leader_ennemi
La commande alive teste si l'unité est en vie... On peut aussi l'utiliser pour tester si un objet est détruit. Par exemple, une tour radio.
Vous pouvez retourner voir l'exemple du convoi ci-dessus, vous verrez qu'on n'utilise pas "this".

Il est cependant possible d'obtenir la liste des unités correspondant aux critères du déclencheur avec la variable spéciale "thisList".
Par exemple, vous voulez un déclencheur qui ne se déclenche que pour les BLUFOR mais seulement s'il y a un joueur parmis les unités.
La configuration du déclencheur est donc:
  • Type: Néant
  • Activation: BLUFOR, Une fois, Présent
La condition du déclencheur devient:

Code : Tout sélectionner

({ isPlayer _x} count thisList) > 0
thisList contient ici la liste des unités de type BLUFOR qui sont présentes.
count va effectuer le code entre accolade sur tous les éléments de thisList.
Le test qu'on effectue utilise la commande isPlayer sur la variable spéciale "_x" qui est celle contenant les éléments d'une itération.



Commande d'activation et de désactivation du déclencheur

Avoir une condition c'est bien... mais généralement on veut que le déclencheur fasse quelque chose...
Dans ce cas, on va entrer des commandes dans les deux zones suivants:
  • Sur Act.: Le code s'exécutera lorsque la condition devient vraie
    Image
  • Sur Désact.: Le code s'exécutera lorsque la condition devient fausse après avoir été vraie
    Image
Un rapide exemple.
On place un déclencheur qui détecte de manière répétée la présence du camp BLUFOR.
Dans l'activation et la désactivation on utilise la commande hint pour afficher un message dans le coin supérieur droit de l'écran.
Image

Lorsque le joueur entre dans la zone, le déclencheur s'active
Image

Lorsqu'il sort de la zone, le déclencheur se désactive
Image

Et ce autant de fois que vous entrez ou sortez, puisque le déclencheur est configuré sur "Répétition".



Lier un déclencheur et une unité ou un groupe

Dans certains cas, vous ne voulez pas qu'un déclencheur s'active sauf quand un groupe ou une unité d'un groupe arrive sur le déclencheur.
C'est tout à fait possible.

La marche à suivre est la suivante:
  • placez un déclencheur sur carte avec la zone que vous souhaitez.
  • placez aussi le groupe qui doit activer le déclencheur.
  • sélectionnez l'outil de groupement Image
  • liez le leader du groupe (ou l'unité) et le déclencheur
    • clic gauche sur l'unité
    • maintenir le bouton gauche et glisser jusqu'au déclencheur
    • relâcher le bouton gauche
    • une ligne bleue relie les deux
Vous devriez avoir dans l'éditeur un résultat qui ressemble à ceci:
Image

Vous pouvez ensuite éditer le déclencheur et ouvrir le menu déroulant "Activation".
Une nouvelle série de valeurs sont maintenant disponibles... et parlent d'elles mêmes.
Image



Déclencheur lié à la radio

Pour laisser au joueur la possibilité d'activer un déclencheur lui-même (pour lancer un renfort ou une évacuation) vous pouvez utiliser l'activation de type "Radio XYZ". La procédure est la suivante:
  • Insérez un nouveau déclencheur
  • Entrez un texte dans la zone "TEXTE", c'est ce texte qui sera affiché dans le menu radio
  • Dans le menu déroulant "Activation", sélectionnez "Radio Alpha"
  • Placez les commandes souhaitées dans la zone d'activation
  • Lancez la prévisualisation
  • Appuyez sur le bouton "0" (zéro) au haut de votre clavier PAS sur le pavé numérique
  • Vous êtes maintenant dans le menu radio, il a encore un sous menu "Radio" accessible par "0" une fois de plus (ou à la roulette)
  • Dans ce sous menu, vous avez l'option ajoutée par le déclencheur que vous pouvez activer (soit par le numéro, soit par la roulette)
En image...
Image


Retour à la table des matières
Image

Avatar de l’utilisateur
Tyrghen
Membre des [V]Vétérans
Messages : 4119
Inscription : 14 oct. 2012, 22:47

Notions de base du scripting dans ArmA 3

Message par Tyrghen » 13 nov. 2014, 09:15

Mise à jour:04/06/2015

Notions de base du scripting dans ArmA 3

Le but de ce tutoriel est de donner des notions de base de scripting dans ArmA 3 pour les non programmeurs.
Le scripting est intimidant pour les nouveaux venus, on se dit que c'est trop complexe et tout ça, mais honnêtement, le langage d'ArmA est extrêmement simple, même si pas très beau et c'est une manière très ludique et gratifiante de découvrir la programmation.
L'avantage principal du scripting dans ArmA, c'est qu'on peut très vite obtenir un résultat visible dans le jeu.

J'encourage tout le monde à se lancer et à profiter du fait que vous avez ici un forum sur lequel posez vos questions et où elles seront répondues sans préjugés... on a tous débuté un jour et il n'y a pas de bêtes questions, uniquement des bêtes réponses.

Cet article est basé sur un article du BIKI.

Cet article n'est pas fini, mais il pourrait déjà vous servir.



Qu'est-ce que le scripting?

Le coeur du scripting c'est le code, il est constitué de commandes qui disent au moteur d'ArmA ce qu'il doit faire.
Ces commandes sont exécutées séquentiellement (l'une après l'autre) dans l'ordre où elles sont données dans le script.

On peut écrire du code dans certains champs de l'éditeur de mission (l'initialisation des objets, l'activation ou la condition des déclencheurs, etc.) ou dans des fichiers qu'on appellera ensuite depuis la mission, soit dans un des champs ci-dessus ou à l'aide des scripts prédifinis dans ArmA.



La syntaxe

Tout langage de programmation suit une syntaxe, elle est la "grammaire" du langage qui définit comment former les commandes.
Cette grammaire nous permet de savoir comment formuler nos demandes pour qu'elles soient comprises par le moteur d'ArmA.

Le langage utilisé par ArmA est le SQF.

Dans certains vieux scripts vous pourriez rencontrer le langage SQS, il s'agit du langage d'OFP qui a évolué pour devenir le SQF. Il est considéré comme obsolète et il est inutile de vous y intéresser..

Il y a quelques règles de base concernant la structure d'un programme en SQF.
  • Chaque déclaration (utilisation d'une commande ou plus pour former une phrase) doit être séparée par un point virgule ";".
    Ceci permet au moteur de savoir où commence et où finit la phrase avant de la lire.
    Une déclaration est un ensemble de commandes et de variables qui interagissent avec le moteur d'ArmA.
    Exemple:

    Code : Tout sélectionner

     _pos = position player;
  • Les blocs de code (pour les fonctions, les boucles ou les conditions) doivent être entourés d'accolades "{ ... }"
    Exemple:

    Code : Tout sélectionner

     _fonction = { (position player) select 2 };
  • Les lignes de commentaires (pour expliquer ce que fait votre code) doivent commencer par deux backslashs "//"
    Exemple:

    Code : Tout sélectionner

    // Cette fonction renvoie la hauteur d'un objet par rapport à ce qui est en dessous de lui
     _fonction = { (position player) select 2 };


Agencement du code

Lorsque vous écrivez du code dans l'éditeur, vous n'avez pas le choix, toutes les déclarations se suivent sans retour à la ligne et on obtient quelque chose du genre:

Code : Tout sélectionner

nul = this spawn { while { alive _this } do { "marqueur_veh" setMarkerPos (position _this); sleep 2; }; deleteMarker "marqueur_veh"; };
Lorsque vous écrivez du code dans un fichier externe qui sera appelé par votre mission, au lieu d'avoir quelque chose d'illisible, il y a des conventions à suivre qui vous permettront de mieux lire votre code quand vous le reprendrez dans 6 mois...

En résumé:
  • Chaque déclaration doit être sur sa propre ligne
  • Lorsqu'on démarre un nouveau bloc, on décale tout son contenu d'une tabulation
  • Lorsqu'un bloc de code est contenu dans un autre bloc, on augmente la tabulation pour créer une indentation
Le code donné en exemple devient donc:

Code : Tout sélectionner

nul = this spawn {
    while { alive _this } do {
        "marqueur_veh" setMarkerPos (position _this);
        sleep 2;
    };
    deleteMarker "marqueur_veh";
};
Il est directement plus facile de voir ce qui fait partie du bloc du while et de voir ce qui fait partie du bloc du spawn.



Opérateurs

Dans un langage de programmation on a besoin d'opérateurs pour effectuer des opérations (mathématiques ou logiques par exemple) sur les variables qu'on manipule.

La liste des opérateurs sur le biki est complète et bien détaillée.
Je vous donne ici le lien en franglais, traduit par google qui est quand même de bonne qualité et devrait suffire pour que vous compreniez tout ce qu'il y a à savoir.

Ceux que vous utiliserez le plus souvent sont les suivants:
  • = : l'assignation, permet de mettre un contenu dans une variable.
    Exemple:

    Code : Tout sélectionner

     _variable = position player;
  • +, -, etc. Les opérateurs arithmétiques... je ne vous fais pas un dessin.
  • &&, AND, ||, OR, ! : les opérateurs logiques vous permettent de combiner des résultats booléens (vrai/faux) pour obtenir une combinaison de résultats.
    Exemple:

    Code : Tout sélectionner

    _vehicule_ok = (canMove _vehicule) AND (canFire _vehicule);
  • (, ) : les parenthèses vous permettent de grouper une expression de manière à pouvoir supprimer toute confusion possible sur l'ordre dans lequel on doit exécuter les commandes.
    Si j'écris:

    Code : Tout sélectionner

    _hauteur = position player select 2;
    Le moteur d'arma ne sait pas s'il doit d'abord sélectionner le troisème élément de player et ensuite prendre la position de cet élément ou s'il doit d'abord prendre la position du joueur puis en prendre le troisième élément.
    Pour éviter toute confusion au niveau du moteur on écrit:

    Code : Tout sélectionner

    _hauteur = (position player) select 2;
    On voit bien que position et player sont groupés et qu'on prend donc le troisième élément du résultat de ce groupe.
On a déjà parlé des accolades {, } donc je ne reviens pas dessus.



Les variables

En programmation, une variable est un symbole qui associe un nom à une valeur.
Lorsque j'écris:

Code : Tout sélectionner

_joueur = player;
La variable "_joueur" est le nom qui est associé (par l'opérateur d'assignation) à la valeur renvoyée par la commande player.

Dans le langage SQF on distingue 2 types de variables:
  • Les variables globales: elles commencent par une lettre, peuvent porter n'importe quel nom, sauf celui d'un mot réservé (comme les commandes d'ArmA par exemple).
    Ces variables sont accessibles n'importe où dans le jeu sur le PC sur lequel elles sont définies, si vous la définissez dans un champ d'initialisation de l'éditeur, elle sera disponible dans un script que vous lancez par après. C'est magique.
    Exemple:

    Code : Tout sélectionner

    VAR_GLOBALE = dayTime;
  • Les variables locales: elles commencent impérativement par un underscore "_" (tiret bas) et n'ont pas de limititation pour leur nom.
    Ces variables ne sont disponibles que dans l'espace de noms du segment de code où elles sont définies. Généralement, le script où vous l'utilisez.
    Attention: Les champs de l'éditeur n'acceptent pas de variables locales, sauf si celles-ci sont contenues dans un bloc de code appelé par la commande spawn.
    Exemple:

    Code : Tout sélectionner

    _locale = dayTime;
Quelques points d'attention:
  • Même les variables globales ne sont pas synchronisées entre tous les ordinateurs, si votre mission dépend d'une variable globale (utilisée dans un déclencheur par exemple) il est fortement conseillé de synchroniser cette variable globale avec la commande publicVariable à chaque fois que vous faites un changement!
  • Si vous utilisez une variable locale dans un espace global (comme par exemple un champ de l'éditeur) un message d'erreur vous en avertira.
  • Si vous appelez une fonction dans un de vos scripts, les variables locales de votre script, si elles ne sont pas protégées par la commande private, peuvent être modifiées par la fonction que vous appelez si celle-ci utilise les mêmes noms et ne les protègent pas par la commande private.
Vous pouvez lire le tutoriel dédié pour aller plus en détail.



Les variables spéciales

Il existe dans ArmA une série de variables spéciales (locales ou globales) qui sont assignées automatiquement, voici une liste non exhaustive:
  • _this: Lorsque vous entrez dans un script ou une fonction, les paramètres passés à ce script ou cette fonction sont placés automatiquement dans la variable _this.
  • _x: Lorsque vous exécutez du code avec la boucle forEach, l'élément qui est actuellement sélectionné par la commande est placé dans la variable _x.
  • this (objet): Lorsque vous éditez un objet, le code contenu dans son initialisation reçoit la variable this qui représente l'objet lui-même.
  • this (déclencheur): Lorsque vous éditez un déclencheur, le code contenu dans la zone de condition reçoit la variable this qui représente le résultat du calcul de la condition qui a été définie, par exemple "BLUFOR PRESENT".
  • this (déclencheur): Lorsque vous éditez un déclencheur, le code contenu dans la zone d'activation et de désactivation reçoit la variable this qui représente le déclencheur lui-même.
  • thisList (déclencheur): Lorsque vous éditez un déclencheur, le code contenu dans la zone d'activation et de désactivation reçoit la variable thisList qui contient un tableau avec toutes les unités qui ont activé le déclencheur.
    Par exemple, si vous placez un déclencheur "BLUFOR PRESENT", toutes les unités blufor présentent dans le déclencheur seront placées dans thisList.
Ca peut paraître un peu confus, mais à l'usage ça devrait s'éclaircir.



Les objets dans l'éditeur

Lorsque vous donnez un nom à un objet dans l'éditeur (par exemple les unités des joueurs) vous assignez en fait une variable globale à cet objet. Donc vous pouvez directement modifier l'objet depuis n'importe quel script ou champ de l'éditeur.
Ce n'est qu'un cas particulier des variables globales.

Vous pouvez lire le tutoriel dédié pour aller plus en détail.



Les tableaux de valeurs

Les tableaux de valeurs sont un type de contenu pour une variable, mais ils sont très importants et donc j'y consacre un point à part.
Je ne vais pas passer en revue toutes les commandes qu'on utilise avec les tableaux, mais uniquement les plus importantes.

Un tableau de valeur est par exemple: [ 1, 2, 3, 4 ]

Vous remarquez qu'un tableau de valeurs commence par une parenthèse carrée "[" et fini par son opposé "]".
Chaque élément du tableau est séparé par une virgule.

Lire un élément dans un tableau
On utilise la commande select avec un index qui commence à 0 pour le premier élément.
Exemple:

Code : Tout sélectionner

_element = [1,2,3,4] select 2; // renvoie la valeur "3"
Le nombre d'éléments dans un tableau
Il est souvent utile de savoir combien il y a d'éléments dans un tableau pour pouvoir passer par une boucle. On utilise la commande count.
Exemple:

Code : Tout sélectionner

_nombre = count [1,2,3,4]; // renvoie "4"
Ajouter un élément dans un tableau
Souvent vous allez ajouter des valeurs à un tableau, par exemple lorsque vous créé une liste d'objets, pour cela on utilise la commande pushback
Exemple:

Code : Tout sélectionner

_tableau = ["a","b","c"];
_index = _tableau pushback "d"; // renvoie "3" la position du nouvel élément et le tableau devient ["a","b","c","d"]
Modifier un élément dans un tableau
Parfois le contenu d'un tableau doit changer, pour modifier un élément, vous devez connaître son index (sa position) dans le tableau. On utilise ensuite la commande set pour modifier la valeur à cette position.
Exemple:

Code : Tout sélectionner

_tableau = ["a","b","c"];
_tableau set [1, "d"]; // le tableau devient  ["a","d","c"]


Les structures de contrôle

Les structures de contrôle sont des commandes qui permettent de modifier l'ordre dans lequel les déclarations d'un script sont exécutées.
Cela permet au script de s'adapter à différentes situations.

Une page du biki est consacrée aux structures de contrôle, je vous en donne aussi le lien en franglais pour que ce soit plus clair.
Par contre, la page traduit des mots qu'elle ne devrait pas, comme les noms des commandes ("if", etc.).

Mais je vais vite passer en revue les 4 structures les plus importantes.


IF THEN ELSE - La condition SI ALORS SINON

Dans la majorité des scripts, vous voudrez adapter vos scripts aux situations qui se présentent.
Typiquement, vous voulez effectuer une opération du genre:
SI le joueur est dans la zone ALORS j'affiche un message SINON je déclenche le compteur

En script ça donne:

Code : Tout sélectionner

IF ((player distance _zone) < 100) THEN {
  hint "Vous êtes dans la zone";
} ELSE {
   COMPTEUR_START = true;
};
Vous voyez que le code à exécuter est contenu dans un bloc défini par des accolades, que ce soit après le THEN (alors) ou le ELSE (sinon).
Ce qui est normal, puisqu'on peut avoir un nombre aléatoire de déclarations.

La condition est contenue dans des parenthèses parce qu'elle doit renvoyer une seule valeur booléenne qui doit être SOIT vrai, SOIT faux.
Ce n'est donc pas absolument nécessaire de les mettre, mais je vous conseille de TOUJOURS les mettre.


FOR EACH - La boucle POUR CHAQUE

Vous aurez souvent des tableaux de valeurs, que ce soit vous qui les avez créées ou une commande telle que nearObjetcs. Le plus souvent, vous voudrez exécuter une opération sur chacune de ces valeurs, comme par exemple, tester si ces objets sont détruits ou non.
Pour cela, vous devez itérer au travers des valeurs.

La commande va donc prendre chaque valeur du tableau qu'elle reçoit et la passer au bloc de code avec lequel elle est associée au travers d'une variable spéciale "_x".
Vous devez donc utiliser cette variable pour savoir de quoi on parle.

On utilise cette boucle de cette façon:

Code : Tout sélectionner

_mon_tableau = units (group player); // récupère la liste des unités du groupe du joueur
_vivants = true;
{
   _vivants = _vivants && (alive _x);
} FOREACH _mon_tableau;
La commande foreach est située à la FIN du bloc de code, c'est une décision prise par les développeurs... ne cherchez pas à comprendre pourquoi.


WHILE ... DO - La boucle TANT QUE .. FAIRE

Un autre cas de figure, c'est une script qui doit s'exécuter tant qu'une condition est remplie. Par exemple, vous voulez déplacer un marqueur avec un véhicule. Ce qui se traduit par: TANT QUE le véhicule est en vie FAIRE déplacer le marqueur.

On utilise cette condition de la manière suivante:

Code : Tout sélectionner

_vehicule = _this select 0;
_marqueur = _this select 1;
WHILE { alive _vehicule } do {
    _marqueur setMarkerPos (position _vehicule);
   sleep 2;
};
ATTENTION, si la condition de votre boucle While n'a pas de fin, cette boucle tournera jusqu'à la fin de la mission.
Parfois c'est ce que vous voulez... parfois pas du tout, vérifiez toujours la validité de la condition pendant vos tests.

IMPORTANT: Lorsque vous utilisez une boucle WHILE, posez vous toujours la question, est-ce que cette boucle doit s'exécuter tous les dixièmes de seconde ou est-ce qu'un délai plus long est bon aussi. Si un délai plus long est acceptable ajoutez TOUJOURS une commande sleep pour faire une pause à la fin de votre boucle. Ca allégera la charge de votre serveur et vous évitera de perdre tous vos FPS.


FOR ... FROM .. TO .. DO - La boucle POUR .. DE .. A .. FAIRE

Le cas de figure suivant est celui d'une boucle qui doit répéter un nombre de fois un code précis.
Par exemple, vous voulez créer 4 chars. Vous pouvez répéter 4 fois la commande et toutes les autres initialisations sur ces chars ou alors, vous écrivez une fois le code et vous utilisez la boucle FOR.

On utilise cette condition de la manière suivante:

Code : Tout sélectionner

_base = _this select 0;
FOR "_i" FROM 0 TO 3 DO {
   _vehicule = "I_MBT_03_cannon_F" createVehicle (position _base);
   createVehicleCrew _vehicule;
   (group (driver _vehicule)) setBehaviour "COMBAT";
};




Exécuter du code

Maintenant que vous avez une idée de la manière dont on écrit le code, vous pouvez commencer à faire des tests simples pour tester la syntaxe et les commandes. C'est une étape importante dans l'apprentissage du scripting qui vous permettra de vous familiariser avec le langage et les commandes.


La console de débogage

Il existe plusieurs manière d'exécuter du code dans ArmA. Une des manières les plus directes lorsque vous faites des tests dans l'éditeur, c'est la console de débogage. La plus grande partie de la console est occupée par un champ de texte qui permet de taper le code à tester.
Attention, le résultat de ce code ne sera visible que lorsque vous fermez la fenêtre de la console.


Prenons un exemple.
Placer un joueur sur la carte dans l'éditeur, ensuite lancez la prévisualisation. Une fois sur le jeu, pressez la touche Echappement (Esc / Escape), ce qui vous ramène au menu, mais aussi à la console de débogage.

Dans la fenêtre, tapez maintenant le code suivant:

Code : Tout sélectionner

hint format [ "Position: %1", position player];
Appuyez ensuite sur le bouton "Exécuter" situé en bas de l'interface.
Pressez la touche d'échappement pour revenir dans le jeu et observez le message qui s'affiche en haut à droite.

La console de débogage permet de créer de petits scripts pour tester les commandes et leur fonctionnement, c'est un outil très utile pour débuter.
Prenons un autre exemple que je ne vais pas expliquer, mais qui vous donnera un aperçu de ce qui est possible.

Code : Tout sélectionner

0 spawn {
    while { true } do {
        hintSilent parseText Format ["Position: %1<br/>Vitesse: %2<br/>Orientation: %3<br/>Pose: %4",position player, speed player, getDir player, stance player];
        sleep 0.5;
    };
};

Les champs de l'éditeur

Une autre manière d'exécuter du code, c'est dans les champs de l'éditeur.
Les champs que vous utiliserez le plus pour exécuter du code sont:

Code : Tout sélectionner

[*] Le champ d'initialisation des objets
[*] Les champs de condition et d'activation des déclencheurs
[*] Le champ d'activation des points de passage
Notez bien que ces champs sont exécutés dans un espace GLOBAL, vous ne pouvez donc PAS y utiliser de variables locales (telle que "_ma_var"), l'ensemble des variables que vous déclarez dans ces champs sont globales. Ceci signifie donc que si plusieurs champs modifient la même variable en même temps, le contenu de cette variable pourrait ne pas être ce que vous attendez.


Les fichier de script

Si vous voulez utiliser du code plusieurs fois, vous pouvez le recopier dans l'éditeur à chaque fois, mais ce n'est pas très pratique...
Premièrement, si vous voulez faire un changement dans le script, il faudra faire le changement partout où vous l'avez écrit.
Deuxièmement, les champs de l'éditeur ne sont pas très lisibles et ils seront vite très encombrés par votre code si vous tapez de nombreuses et longues commandes.

Pour remédier à ces inconvénients, on utilise un fichier de script. C'est un simple fichier texte placé dans le répertoire de la mission et qui contient les commandes à exécuter.

Si vous ne l'avez pas encore fait, placez un joueur sur carte et sauvegardez la mission en lui donnant un nom explicite.
Ensuite passez sous Windows et aller dans le répertoire mission, normalement il se trouvera sous un chemin du type:
C:\Users\[Votre Utilisateur]\Documents\ArmA 3 - Other Profiles\[Votre Pseudo]\missions\[nom de ma mission]
Vous devriez y trouver le fichier "mission.sqm" qui décrit le contenu que vous avez placé

Dans le répertoire, créez un nouveau fichier texte (clic droit de la souris et ensuite "Nouveau" > "Document texte").
Nommez le nouveau fichier: "afficher_position.sqf".
Ensuite faites un clic droit sur le fichier pour éditer son contenu.

Dans le fichier, placez le code suivant:

Code : Tout sélectionner

private ["_unite"];
_unite = _this;
while { true } do {
    hintSilent parseText Format ["Nom: %1<br/>Position: %2<br/>Vitesse: %3<br/>Orientation: %4<br/>Pose: %5",name _unite, position _unite, speed _unite, getDir _unite, stance _unite];
    sleep 0.5;
};
Allez ensuite dans l'éditeur d'ArmA et modifiez le champ d'initialisation du joueur avec le code suivant:

Code : Tout sélectionner

nul = this execVM "afficher_position.sqf";
Lancez la prévisualisation et vous verrez les informations apparaître dans le coin supérieur droit de l'écran.

Maintenant, placez une deuxième unité, dans le même groupe que le joueur avec le joueur comme leader.
Effacez le contenu du champ d'initialisation du joueur et copiez le code précédent dans le champ d'initialisation de l'IA

Lancez la prévisualisation et donnez des ordres à l'unité IA. Vous verrez que les informations changent en fonction de ses mouvements. Vous n'avez pourtant pas changé le script.
Le script s'est adapté, parce qu'il utilise un paramètre pour définir l'unité à suivre ("_this") et vous lui passez l'unité en cours dans le champ d'initialisation ("this").

C'est sans doute un peu déroutant, mais j'y reviendrai plus en détail dans le point suivant.





Appeler un script

Maintenant que vous avez une idée de ce qu'est un script, voyons comment on peut appeler un script ou du code en général.

execVM
spawn
call

Paramètres d'un script.





Les fonctions, un cas particulier de scripts
Où trouver les fonctions existantes
Comment les appeler
Comment écrire ses propres fonctions

Un tutoriel dédié parle de l'explorateur de fonctions.





Ecrire un script
Concept
Implémentation
Tester ses scripts
Le fichier RPT



Retour à la table des matières
Image

Avatar de l’utilisateur
Tyrghen
Membre des [V]Vétérans
Messages : 4119
Inscription : 14 oct. 2012, 22:47

Liste des commandes d'ArmA

Message par Tyrghen » 13 nov. 2014, 09:17

Mise à jour:03/06/2015

Liste des commandes d'ArmA

Le language d'ArmA, le SQF est un langage propriétaire créé par Bohemia.
Il a évolué avec le temps et donc on y trouve beaucoup d'incohérences, mais c'est un langage relativement simple et descriptif.

Outre les opérateurs (mathématiques, d'assignation, etc.) et les structures de contrôle (boucle, test, etc.) il existe un grand nombre de commandes qui permettent au script d'intéragir avec le moteur d'ArmA. Je ne vais pas passer en revue l'ensemble de ces commandes, je n'ai pas le temps pour ça, mais je vais simplement vous expliquer comment lire les pages du Wiki de BIS.

La liste des commandes d'ArmA est disponible sur:
Community wiki.

Ces pages sont en anglais, mais vous pouvez les visualiser en français à l'aide de google pour avoir une idée de ce qu'elles contiennent.
Le lien google en franglais du WIKI.



La liste des commandes

Sur les liens ci-dessous, vous retrouverez les commandes triées par ordre alphabétique comme sur l'image ci-dessous.
Image

Vous trouverez en haut de la page, différents liens pour visualiser les commandes par fonctionnalités ou par sous catégories (ArmA 1, ArmA 2, etc.).
Mais à priori les listes par ordre alphabétique et par fonctionnalité devraient suffire.




Comment lire une page du biki

Ci-dessous j'ai extrait une page du Biki que j'ai annotée pour décrire le contenu de la page, je reviendrai plus en détails sur chaque élément ci-dessous.

Image



Version du jeu, Argument et Effet

La première zone est composée de 3 type d'icônes (sauf pour les commandes les plus anciennes).
On retrouve donc 3 colonnes:
  • Version du jeu: ArmA 1, ArmA 2, ArmA 3, TKOH, etc.
  • Argument Local ou Global
  • Effet Local ou Global
Voici la majorité des icônes que vous rencontrerez:
Image

Version du jeu
Tant que la version du jeu est plus ancienne que celle sur laquelle vous vous trouvez, rien à craindre. Par contre, si c'est un autre jeu (TKOH par exemple) cette commande n'est pas disponible dans ArmA.

Argument Local ou Global
Cette information n'a d'importance qu'en multijoueur. Si la commande requiert un argument local, cela veut dire qu'elle ne peut être utilisée que sur une unité ou un objet qui a été créé sur le PC où cette commande s'exécute.

Par exemple, une unité ennemie est créée par le serveur. Si vous exécutez une commande avec argument local, vous ne pourrez pas l'exécuter sur cette unité ennemie, parce qu'elle n'est pas locale à votre PC, elle est distante (Remote)
Dans l'exemple ci-dessus, l'argument est Global, donc on peut l'utiliser même sur les unités gérées par un autre PC.

Effet Local ou Global
L'effet local ou global d'une commande indique si elle est automatiquement synchronisée en multijoueur sur tous les PCs ou non.
Si l'effet est local, il faut envoyer manuellement l'information à tous les PCs... mais ça c'est une aventure pour plus tard.

Dans la plupart des cas, on peut contourner les limitations en utilisant un déclencheur. Le déclencheur se lance sur tous les PCs en même temps. Donc une commande avec effet local sera exécutée sur tous les PCs, donnant l'illusion que l'effet est global.



Description

Bon, je crois que c'est assez clair.
C'est en anglais, mais google est là et vous aidera à comprendre grosso modo ce que ça veut dire:
https://translate.google.fr/



Syntaxe

C'est la manière d'utiliser la commande. La plupart du temps, les commandes d'ArmA attendent des paramètres, il faut donc leur donner cette valeur pour recevoir ce qu'on attend en retour.
Certaines commandes n'ont pas de paramètre par contre, dans ce cas, on ne doit rien leur passer.

Vu qu'ArmA a évolué au cours du temps, le langage n'a pas vraiment de cohérence, on trouvera donc beaucoup de syntaxes différentes et parfois plusieurs syntaxes pour la même commande.

Ci-dessous, j'ai repris la liste de ce qu'on retrouve le plus souvent avec des exemples.
  • _joueur = player;
    Pas d'argument, la commande renvoie l'unité que le joueur contrôle actuellement
  • _position_joueur = position player;
    Un argument après la commande, renvoie la position de l'objet passé en argument
    L'argument peut aussi être un tableau de valeurs au lieu d'une valeur unique.
  • "marqueur" setMarkerPos (position player);
    Un argument devant la commande, la commande s'exécute sur cette argument mais nécessite une deuxième information qui est alors donnée après la commande. Ici on change la position du marqueur nommé "marqueur" et on lui donne la position du joueur.
    Cette commande ne renvoie rien.
  • _maisons = (position player) nearObjects ["House", 20];
    Dans ce cas ci on a besoin de plus que deux paramètres, du coup, le deuxième paramètre est un tableau de valeurs.
    La plupart du temps, lorsqu'on a un tableau de valeurs, la commande accepte un nombre variable de valeurs ou accepte une valeur simple, sans tableau.


Exemples

Pour les commandes récentes, les exemples sont généralement de bonne qualité et suffisants pour comprendre ce que fait la commande.



Informations complémentaires

Pour certaines commandes, le comportement peut changer en multijoueur. Dans ce cas, on retrouvera ici des informations supplémentaires pour savoir ce qui se passera dans ce cas.

Vous trouvez aussi des liens vers d'autres commandes du même type qui peuvent vous intéresser.



Retour à la table des matières
Image

Avatar de l’utilisateur
Tyrghen
Membre des [V]Vétérans
Messages : 4119
Inscription : 14 oct. 2012, 22:47

L'explorateur de fonctions

Message par Tyrghen » 13 nov. 2014, 09:19

Mise à jour:24/08/2015

L'explorateur de fonctions




A quoi servent les fonctions?

Le but principal des fonctions d'ArmA c'est de pouvoir réutiliser des segments de code d'une mission à l'autre. Un exemple de fonction, c'est celle qui permet d'afficher l'écran de notification des tâches: BIS_fnc_showNotification.

Mais il existe de nombreuses autres fonctions intégrées à ArmA ou ajoutées par des addons et des scripts que vous utiliserez dans vos missions.
Le but de ce tutoriel est de vous familiariser avec l'explorateur de fonctions, celui-ci vous permet de voir ce qui existe comme fonctions et comment les appeler.





Où trouver l'explorateur de fonctions?

Tout d'abord, dans l'éditeur, parmi les boutons disponibles dans le haut de l'interface, celui intitulé "Fx" donne accès à l'explorateur de fonctions.
Image


Ensuite, lorsque vous faites des tests à l'aide de la console de débogage, vous ne voulez pas retourner dans l'éditeur pour voir le contenu de telle ou telle fonction, la console offre donc un raccourci pour l'explorateur.
Image





Contenu de l'interface

L'interface de l'explorateur de fonction est extrêmement simple et se divise en 6 éléments:
  1. Le sélecteur de "source", c'est l'endroit où les fonctions sont définies.
  2. Le sélecteur de "module", c'est le module ou l'addon auquel appartiennent les fonctions, souvent ce sera le texte trouvé au début du nom de la fonction BIS_fnc_showNotification, mais pas toujours... cela dépend de la manière dont la fonction a été définie.
  3. Le sélecteur de "groupe", qui permet de lier les fonctions par fonctionnalités. Une fois de plus, cela dépendra de la manière dont les fonctions sont définies.
  4. La liste des fonctions correspondant aux filtres sélectionnés précédemment
  5. Le nom de la fonction actuellement visualisée (c'est le nom à utiliser dans vos scripts)
  6. Le code de la fonction, celui-ci débute généralement par un commentaire qui explique le but de la fonction, mais aussi la façon de l'utiliser.
Image





La source de la fonction
Il existe plusieurs endroits où vous pouvez définir des fonctions:
  • Un addon -> configFile
  • Une campagne -> campaignConfigFile
  • Une mission -> missionConfigFile
Image

En fonction de la fonction que vous souhaitez utiliser, vous devrez choisir parmi l'une de ces sources.
Dans le cas des fonctions de BIS, l'écrasante majorité se trouve dans des addons et est donc disponible sous "configFile", c'est aussi le cas pour nombre d'addons qui ajoutent des fonctionnalités à ArmA.

Dans le cas de librairie de scripts intégrés à une mission (telle que notre Base Mission), les fonctions sont définies dans la mission même, intégrées au travers du description.ext.
Il faudra donc choisir la source "missionConfigFile" pour pouvoir explorer les différentes fonctions.

Ci-dessous j'ai repris l'exemple d'une fonction de la Base Mission intégrée à nos missions.
Le groupe EDT contient toutes les fonctions utilisables dans l'éditeur pour simplifier la création de nos missions.
Image




Retour à la table des matières
Image

Avatar de l’utilisateur
Tyrghen
Membre des [V]Vétérans
Messages : 4119
Inscription : 14 oct. 2012, 22:47

Localité dans ArmA

Message par Tyrghen » 13 nov. 2014, 17:02

Mise à jour:13/11/2014

Localité dans ArmA

Titre

Local
Global
JIP
Déclencheurs
Commandes

Retour à la table des matières
Image

Avatar de l’utilisateur
Tyrghen
Membre des [V]Vétérans
Messages : 4119
Inscription : 14 oct. 2012, 22:47

Temps d'exécution des scripts et ordre d'exécution

Message par Tyrghen » 13 nov. 2014, 17:11

Mise à jour:13/11/2014

Temps d'exécution des scripts et ordre d'exécution

Titre

Spawn, execVM, call

preInit
initialisations des unités
postInit
init.sqf


Retour à la table des matières
Image

Avatar de l’utilisateur
Tyrghen
Membre des [V]Vétérans
Messages : 4119
Inscription : 14 oct. 2012, 22:47

Objets et variables dans ArmA

Message par Tyrghen » 14 nov. 2014, 09:03

Mise à jour:14/11/2014

Objets et variables dans ArmA

Si vous voulez pouvoir faire plus que ce que l'éditeur seul permet, la plupart des commandes d'ArmA attendent des variables comme paramètres ou renvoient des résultats que vous devez stocker dans une variable. C'est l'objectif de ce tutoriel de parcourir le concept de variables dans ArmA.


Objets nommés

Dans l'éditeur, vous pouvez donner un nom aux objets, aux déclencheurs, aux logiques de jeu, etc.
Ce nom, est en fait le nom d'une variable globale, qui sera disponible dans chaque script ou zone de code de la mission. C'est la raison pour laquelle l'éditeur impose que le nom d'une variable soit unique.

Le nom d'un objet dans ARMA ne peut contenir que:
  • des lettres
  • des chiffres
  • le caractère "_" (underscore)
ATTENTION: Comme il s'agit ici d'une variable globale, elle ne peut PAS commencer par le caractère "_" (Underscore).
Par exemple: ma_voiture, ennemi1, eni123, GRP23

REMARQUE: ArmA n'est pas sensible à la casse, Eni123, ENI123, eNi123 pointent vers la même variable!


Pour illustrer, voici un test très simple:
  • Donnons le nom "p1" au joueur placé sur carte.
  • Ensuite, prévisualisez la mission.
  • Ouvrez la console de débogage avec la touche "Esc" (Escape, Echappement)
  • Dans la console, tapez le code suivant:

    Code : Tout sélectionner

    hint name p1;
  • Appuyez sur "EXEC LOCAL" pour exécuter ce code sur l'ordinateur actuel (on ne peut pas exécuter en global ou sur le serveur, si on est en mode de prévisualisation).
  • Un message s'affiche, grâce à la commande hint, avec le nom du joueur, puisque c'est ce que renvoie la commande name et "p1" dans notre cas est le joueur.
Dans l'éditeur on a donc:
Image

Dans la console de débogage:
Image

Avec le résultat:
Image



Variables globales

Une variable globale est définie dans un script ou dans une zone de code (Activation d'un déclencheur, activation d'un point de passage, initialisation d'un objet, etc.).
Une variable globale est accessible dans l'ensemble des scripts et des zones de code de l'ordinateur sur lequel elle est définie.

Le nom d'une variable globale dans ARMA ne peut contenir que:
  • des lettres
  • des chiffres
  • le caractère "_" (underscore)
ATTENTION: Comme il s'agit ici d'une variable globale, elle ne peut PAS commencer par le caractère "_" (Underscore).
Par exemple: ma_voiture, ennemi1, eni123, GRP23

REMARQUE: ArmA n'est pas sensible à la casse, Eni123, ENI123, eNi123 pointent vers la même variable!


Le plus simple pour que ce soit clair, c'est de faire un test.
Prenons par exemple le groupe du joueur. Il n'existe pas de variable permettant de référencer le groupe du joueur.
Une solution c'est de créer cette variable lorsque le joueur est créé.

Dans l'éditeur on va ajouter la ligne de code à l'initialisation du joueur.
Le nom "GRP1" est arbitraire, vous pouvez choisir le nom que vous voulez du moment qu'il respecte les conventions citées ci-dessus.
Image

A partir de maintenant, aussitôt que le joueur est créé, la variable GRP1 peut être utilisée n'importe où dans les scripts.
On va prendre un exemple simple dans la console de débogage.
Image

On peut exécuter localement pour obtenir le nom du groupe:
Image

La commande str renvoie simplement le contenu de la variable sous forme de chaîne de caractère, la commande hint n'acceptant que des chaînes de caractères comme paramètre.


Variables locales

Les variables locales sont des variables qui ne sont connues qu'à l'intérieur du script où elles sont déclarées.
Ces variables sont détruites lorsque l'exécution du script se termine.

Le nom d'une variable locale dans ARMA, DOIT COMMENCER PAR "_" (Underscore) et ne peut contenir que:
  • des lettres
  • des chiffres
  • le caractère "_" (underscore)
Par exemple: _ma_voiture, _ennemi1, _debut

REMARQUE: ArmA n'est pas sensible à la casse, _Eni123, _ENI123, _eNi123 pointent vers la même variable!


ATTENTION: Si vous appelez un script depuis un autre script, les variables locales du script appelant sont connues par le script appelé... ce qui peut entraîner des effets de bord imprévisibles. C'est pour ça qu'au début de chaque script, il faut déclarer les variables locales que vous utilisez avec la commande private.

Créez dans le répertoire de votre mission un fichier "init.sqf" avec le contenu suivant:

Code : Tout sélectionner

private ["_locale"]; // on déclare la variable _locale comme étant privée à ce script

_locale = "Une chaîne de caractères": // on assigne une valeur à la variable

hint _locale; // on affiche le contenu de la variable
Les lignes précédées par "//" (double slash) sont ignorées par le compilateur d'ArmA, ce sont des commentaires.

Lancez la mission et un message devrait s'afficher avec le texte "Une chaîne de caractères".

Vous pouvez ensuite essayer d'exécuter la commande suivante dans la console de débogage:

Code : Tout sélectionner

hint _locale;
Mais ça ne fonctionnera pas, la variable étant locale au script "init.sqf" uniquement.



Variables publiques

Une variable publique est une variable globale qui est synchronisée entre tous les ordinateurs.
Attention, certaines variables donnent l'impression d'être publiques (comme par exemple le nom d'un objet) parce qu'elles sont créées par l'éditeur et donc instanciées chez tous les joueurs, mais dans la réalité, si vous modifiez le contenu de la variable sur un ordinateur (le serveur par exemple) cette modification n'est pas reflétée sur les autres ordinateurs.

Pour qu'une variable globale soit rendue publique, il faut après chaque modification, appeler la commande publicVariable.

A partir du moment où une variable est devenue publique, elle est synchronisée entre tous les ordinateurs. Même ceux qui se connectent par après. Ce qui permet de partager des informations avec les nouveaux arrivants dans la mission.

Prenons un exemple concret avec la création d'une tâche.

Tout d'abord, placez un déclencheur qui détecte la présence des BLUFOR, dans la ligne d'activation d'un déclencheur vous pouvez placer le code suivant;

Code : Tout sélectionner

OBJECTIF1 = true; publicVariable "OBJECTIF1";
Image

Ensuite, on place un deuxième déclencheur qui réagit à l'objectif et crée une tâche.
Placez un autre déclencheur, avec la condition suivante:

Code : Tout sélectionner

OBJECTIF1
Et le code d'activation:

Code : Tout sélectionner

TACHE1 = player createSimpleTask ["Tâche à accomplir"];
Image

Lancez la mission, prévisualisez, la tâche sera ajoutée lorsque vous entrez dans la zone du premier déclencheur.
Image

Si vous lancez cette mission sur un serveur, dédié ou non, et qu'un joueur se connecte en cours de partie. Même s'il n'y a plus personne dans la zone, la tâche sera créée pour lui aussi, parce que la variable OBJECTIF1 sera synchronisée avec son PC et passera donc à "true".



Localité des variables

Le graphique suivant résume la localité des différents types de variables
Seules les variables publiées par la commande publicVariable sont disponibles dans l'espace public qui est partagé par l'ensemble des ordinateurs. Mais attention, à chaque changement de la variable, peu importe sur quel ordinateur, il faut à nouveau publier le changement.

Les variables globales comme on le voit sont globales à chaque ordinateur séparément, donc accessibles dans les différents scripts de cet ordinateur là uniquement!
Il en résulte que sur l'ordinateur 2, il se peut que la variable VEC1 pointe vers le Hunter numéro 1, tandis que sur l'ordinateur 1, VEC1 pointe vers un autre Hunter, parce qu'il a été créé en cours de mission avant que l'ordinateur 2 ne se connecte.

Image


Retour à la table des matières
Image

Avatar de l’utilisateur
Tyrghen
Membre des [V]Vétérans
Messages : 4119
Inscription : 14 oct. 2012, 22:47

Création de tâches avec les modules

Message par Tyrghen » 21 nov. 2014, 11:36

Mise à jour:28/11/2014

Création de tâches avec les modules

Ce tutoriel reprend la création des tâches à l'aide de déclencheurs et des modules inclus dans ArmA 3.

Le tutoriel Création de tâches avec les commandes d'ArmA vous permettra de mieux comprendre ce qui se passe derrière ces modules.
Même si vous êtes allergique au scripting, je ne peux que vous recommander de quand même lire ce tutoriel. Simplement parce qu'il est utile de savoir ce qui se cache derrière les modules pour comprendre ce que font ces modules et quelles sont les limitations.



Création d'une tâche

La première chose à faire, c'est de sélectionner l'outil de placement des modules Image. Ensuite, double cliquez sur la carte près du déclencheur qui activera la création de la tâche. Vous ouvrirez l'écran d'édition des modules.

Le module qui nous intéresse se trouve dans la catégorie "Infos" et se nomme "Créer tâche".
Lorsque vous faites votre sélection, vous remarquez que le contenu sur la droite change en fonction du module sélectionnez.
Ci-dessous, vous pouvez voir le module de création de tâche.

Image

Ce qui nous intéresse ici, ces sont tous les champs à partir de "Propriétaire". Ci-dessous je les reprends un par un.

Propriétaire
C'est une liste déroulante qui permet de choisir qui recevra la nouvelle tâche.
Les différents possibilités sont:
  • Objets synchronisés uniquement: Ce sont les unités liées au module à l'aide de l'outil de synchronisation Image
  • Groupes d'objets synchonisés: Ce sont toutes les unités dont le leader est synchronisé à l'aide de l'outil de synchronisation Image
  • Camps des unités synchronisées: Si vous synchronisez (Image) des unités blufor avec le module, TOUTES les unités du camp BLUFOR recevront cette tâche, qu'elles soient synchronisées ou non.
  • Toutes les unités jouables: C'est ce que vous utiliserez le plus, toutes les unités qui sont contrôlées par un joueur recevront la tâche. Aucune synchronisation n'est nécessaire.
  • BLUFOR, OPFOR, Indépendant, Civil: Toutes les unités du camp sélectionné recevront la tâche. Aucune synchronisation n'est nécessaire.
ID Tâche
C'est l'identifiant unique qui permet de retrouver la tâche, donnez le nom que vous voulez, du moment qu'il est unique.

Titre
Le titre de la tâche qui sera affiché dans la liste des tâches, mais aussi dans les notifications qui s'affichent automatiquement à l'écran.

Description
C'est le texte qui peut être lu dans la description de la tâche.
Tout comme pour la fonction setSimpleTaskDescription, vous pouvez utiliser du texte structuré pour ajouter des images, des liens, des titres, etc.

Marqueur
C'est le texte qui s'affichera sur le marqueur de destination du module.

Destination
Vous pouvez placer le module là où se trouve la destination de la tâche. Dans ce cas, à la place de sélectionner "Désactivé", vous pourrez mettre "Position du module".
Si le module ne se trouve pas là où vous voulez positionner la tâche (pour une raison ou une autre), vous pouvez placer un module du type "Définir destination de la tâche", mais c'est du boulot supplémentaire pour rien, SAUF si vous voulez lier une tâche avec un objet mobile. Dans ce cas là, vous n'avez pas le choix.

Etat
C'est le statut de la tâche au moment de l'activation du module.
Vous vous demandez probablement, pourquoi s'emmerder à avoir plusieurs statuts différents. En fait, vous pouvez placer plusieurs modules de création de tâche sur carte et tous les lier entre eux en utilisant le même ID Tâche.
Vous pouvez de cette manière, faire évoluer la description, le statut, la destination, etc.
C'est une alternative à l'utilisation du module qui sert à définir le statut d'une tâche.


Pour le moment, cliquez simplement sur OK et allez voir sur la carte, vous verrez que la tâche est créée.
Image




Lier une tâche et un déclencheur

Souvent dans une mission, les tâches seront créées et mises à jour au fur et à mesure de la progression de la mission. Pour permettre de retarder la création d'une tâche, vous devez synchroniser Image le module de création avec le déclencheur.

On va commencer par placer un déclencheur qui s'active après 5 secondes.

Image

Ensuite on lie le module de tâche et le déclencheur avec l'outil de synchronisation Image.

Image

Lancez la prévisualisation et après 5 secondes, une notification va apparaître automatiquement.
En effet, le fait de placer un module de création de tâche ou de changement de statut de la tâche, fera appel automatiquement aux notifications.

Image




Modifier le statut d'une tâche

Maintenant que nous avons une tâche, nous voulons modifier son statut lorsque l'action est réussie (ou échouée, ou abandonnée, etc.).
Deux méthodes s'offrent à nous:
  1. Lier un module de création de tâche au déclencheur et utiliser le même ID Tâche (dans notre exemple TACHE1). Pour cela, suivez la procédure ci-dessus.
  2. Lier un module de changement de statut au déclencheur ET à la tâche à modifier
Dans ce point, c'est la deuxième méthode que nous allons utiliser.

Commencez par placer un déclencheur qui s'active lorsque des BLUFOR entre dans la zone du hangar.
Ensuite placez un nouveau module du type: "Définir état de la tâche".
Sélectionnez le nouveau statut de la tâche: Réussie.

Image

Une fois le module placé, faite attention à deux choses:
  1. Il faut supprimer le lien de groupe entre les deux modules, utilisez l'outil de groupement pour ça Image
  2. Il faut lier le nouveau module avec le module de création de tâche et le déclencheur en utilisant l'outil de synchronisation Image
Vous devriez obtenir quelque chose qui ressemble à l'image ci-dessous:

Image

La flèche rouge indique le lien entre les deux modules, il doit s'agir d'une ligne de synchronisation (bleu foncée) et pas de groupement (bleu clair)

Lancer la prévisualisation, entrez dans le hangar...
En plus de la validation de la tâche, une belle fenêtre de notification vous indique le changement de statut de la tâche.

Image




Conclusion

Même si cela représente plus de travail, je recommande nettement d'utiliser plusieurs modules de création de tâche liées à la même tâche (par le même ID Tâche) pour mettre à jour une tâche.
Simplement parce que ça évite les lignes de synchronisation à tout va.

Mais bon, tous les goûts sont dans la nature....



Retour à la table des matières
Image

Verrouillé