Le script SQF/SQS

Utilisation et création de script SQF

Dans ArmA 3, vous aurez besoin de "script'. Le script est simplement un fichier text (.txt), écrit dans un language informatique. Bohémia utilise principalement le ".SQF" .

 

"Tout est dans l'éditeur, alors pourquoi utiliser des scripts ?" me direz vous ! La raison est simple, le script vous offre une liberté de création et d'optimisation nettement superieure à l'éditeur. Vous ferez ce que vous voulez, sur mesure !

 

Les outils nécessaires :

  1. ArmA 3 et sa DEBUG CONSOLE (voir les outils).
  2. Un éditeur de texte (le bloc note peut suffir). Dans tout mes tutos, j'utiliserai POSEIDON (http://www.armaholic.com/page.php?id=22139) qui permettra de donner des couleurs différentes selon le type de code. Je vous le recommande très fortement.
  3. le wiki de bohémia interactive (appelé par beaucoup le BIKI, regarder dans le menu "le wiki de boémia").

Les bases :

Pour réaliser des scripts, il faut commencer par les comprendre. Une ligne de "code", est une phrase dans laquelle nous allons utiliser des fonctionnalités propres à Arma.

 

Voici une ligne de code pour exemple:

=>

cela donne

si (la faction du joueur est BLUFOR) alors {

les domages du joueur = 0.5;

};

Dans cette ligne de code nous avons utilisé différentes choses:

Ce qui est en rouge est une "commande de script" qui ne fonctionne pas seul, elle doit obligatoirement être associée à une autre cammande. La syntaxe, c'est à dire la façon de l'écrire est if (...) then {...}; . Le if est forcément accompagné de then,exitwith,... de même pour les () et {}, ils sont obligatoirement placés de cette façon et sont indissociables de cette commande.

 

En décoder :

 

if en anglais = si

then en anglais = alors

 

ce qui nous donnes

si (une condition) alors {un code};

 

La condition est celle de votre choix et même chose pour le code. Cela veut donc dire que

 

si (vous remplissez la condition entre guillemets) alors {arma exécute le code entre crochets};

 

 

 

Ce qui est en bleu est une "commande de script" donnant une fonctionnalité et souvent retournant un résultat. Dans le code utilisé, side appel en retour la faction d'un "objet", sa syntaxe est

side + l'objet dont vous voulez connaitre la faction

 

 

 

player en sqf, c'est votre personnage "joueur". La valeur retournée par player dans un script sera celle de votre personnnage.Dans notre code, player est donc l'objet dont nous voulons connaitre la faction.

 

 

Le ==, c'est ce que l'on appelle un OPERATEUR. Un opérateur permet de comparer des valeurs et de retourner un résultat en BOOLEAN. Pour reprendre la définition, le BOOLEAN est une forme d'algèbre dans laquelle toutes les valeurs sont soit VRAIES ou FAUSSES {true,false}.

 

Je vous explique les différents types d'opérateur mais ne vous inquiètez pas c'est très simple:

 

  • == égale
  • != différent
  • > inférieur
  • < supérieur
  • >= inférieur ou égale
  • <= supérieur ou égale

 

Pour reprendre notre exemple side player == WEST , nous voulons donc savoir si la faction du joueur est égale à WEST (WEST retourne BLUFOR). le résultat sera donc TRUE ou FALSE.

 

Voici donc quelque de simple, histoire de vous donner une idée de comment cela fonctionne.

 

 

 

***********************************************************************************

 

Voyons maintenant les fonctionnalités de base.

 

LES COMMENTAIRES:

 

Nous commencerons par les commentaires. Dans un script vous pouvez ajouter des textes, afin de laisser une info (pour le dev, en pense bête, pour les autres utilisateurs) sans que ce dernier soit pris en compte par ArmA.

Dans POSEIDON, les textes prennent la couleur grise. Les développeurs l'utilisent fréquemment

au début de leur script pour vous décrire leur script. Il y a 2 méthodes:

 

  • // le double slash, qui indique que le texte de la ligne, après les slash, n'est pas pris en compte

 

  • /* */ le slash, étoile; étoile, slash qui indique que le texte derrière le /* et jusqu'au */ n'est pas pris en compte.

 

exemple:

 

 

 

 

 

 

 

 

 

 

LES VARIABLES:

 

Pour commencer, qu'est ce qu'une variable ? Une variable est un nom que l'on associe à une valeur ou un objet. Pour faire simple, vous prenez un mot et vous dites que lorsque vous utilisez ce mot, la valeur ou l'objet que vous avez indiqué doit être retourné.

Dans ArmA 3 il y a 3 types de variable différents:

 

1. les variables LOCAL

2. les variables GLOBAL

3. les PUBLIC variable

 

Les variables LOCAL: ce type de variable retourne une valeur dans un script. Cette variable n'existe que dans ce script et la valeur (ou objet) qui lui est affecté, ne sera valable que dans ce script. On peut donc dire que la variable est locale dans ce script.

Une "variable local" est un nom commençant par un underscore "_" (le tiret de la touche 8 de votre clavier). Dans poseidon elle prendra la couleur verte.

exemple:

 

 

 

 

 

Voici donc 3 exemples,

le 1er où nous venons de créer la variable local _exemple, et nous lui avons donné la valeur de "1" grace au signe " = " (attention egale donne une valeur, contrairement au == qui controle une valeur, et retourne un true ou false). Chaque fois que j'utiliserai cette variable dans ce script, elle sera remplacée par ArmA par un "1".

 

Dans le 2eme exemple nous avons créé la variable _exempleDeVariable qui retournera le joueur (souvenez vous player c'est le joueur.

 

Et le 3eme,_exemple_de_variable qui retournera un texte (en jaune dans poseidon) "ceci est un exemple de variable LOCAL".

 

Vous pouvez donc écrire ce que vous voulez, tant que c est précédé d'un underscore. ATTENTION tout de même, plus le nom est court et plus le script sera rapide ! Autre chose, ArmA 3 n'aime pas qu'une variable commence par un numéro donc privilégiez des terme court du type : _obj pour un objet, _txt pour un texte, _exe pour un exemple, _exe2 pour un 2eme exemple.

Autre point, Bohémia déconseille les underscore à l'interieur d'une variable (bien que ce soit monnet courante) soi-disant que cela peut créer des erreurs dans vos scripts.

Donc privilégiez _obj2 à _obj_2, _exempledevariable à _exemple_de_variable.

 

 

Les variables GLOBAL: ce type de variable retourne une valeur dans l'ensemble des scripts.

Si vous déterminez la valeur d'une variable global dans un script, cette valeur sera la même dans tous les scripts. C'est la grosse différence entre une LOCAL et une GLOBAL.

Pour créer une variable GLOBAL, le principe est identique à la variable LOCAL sauf que

vous ne mettrez pas d'underscore devant. Une variable global sera de couleur blanche dans poseidon.

exemple:

lifecash = 100;

 

Tous les scripts où vous entrerez "lifecash", retourneront une valeur de 100.

A savoir, la valeur d'une variable GLOBAL est la même sur tous les ordinateurs où elle est définie.

 

Les publicVariable: ce type de variable retourne une valeur qui est la même partout, sur l'ensemble des PC de la mission. C'est à dire que la valeur sera la même pour tout le monde, qu'elle soit déclarée ou non !

Pour créer une publicVariable, il faut utiliser une commande de script associé à une variable GLOBAL:

leNomQueVousVoulez = 3; //ceci est une variable global

publicVariable "leNomQueVousVoulez"; // que je transforme en publicVariable

 

ATTENTION, les publicVariable sont gourmandes en ressources, elles se stockent dans la mémoire de votre PC ! Utilisé en trop grand nombre elles peuvent nuire au performance de votre mission (lags, FPS bas, ...). Si vous en utilisez dans une mission, pensez à la "supprimer" quand elle deviendra inutile. Pour se faire, donnez lui une valeur nul en utilisant nil.

Pour reprendre notre exemple précédent:

leNomQueVousVoulez = nil; //voila, nous venons de détruire notre variable GLOBAL et par la même occasion notre publicvariable.

 

Pour créer des variables GLOBAL ou PUBLICVARIABLE il existe une autre méthode qui consiste à utiliser la commande de script: setvariable , mais je vous expliquerai cette méthode lorsque vous aurez vu un peu plus de choses.

 

 

LES COMMANDES DE SCRIPT:

 

Voici la liste des commandes de script pour ArmA:

 

 

Avant de commencer, vous devez savoir une ou deux choses. Les données indiquées ou retournées peuvent être de différents types:

 

  • "ARRAY"
  • "BOOL"
  • "CODE"
  • "CONFIG"
  • "CONTROLE"
  • "DISPLAY"
  • "GROUPE"
  • "LOCATION"
  • "OBJECT"
  • "SCALAR"
  • "SCRIPT"
  • "SIDE"
  • "STRING"
  • "TEXT"
  • "TEAM_MEMBER"
  • "NAMESPACE"

 

Je vous donne une explication de chaque :

 

ARRAY (anglais = tableau), un ARRAY est donc un tableau. Il est représenté par des crochet []. Entre ces crochets vous trouverez des valeurs séparées par des virgules. Chaque virgule indique une colonne.

exemple ARRAY:

 

 

Je viens donc de créer un tableau avec 2 virgules. J'ai donc 3 colonnes:

Colonne 1- Uniform player,

Colonne 2- headgear player,

Colonne 3- damage player

 

Sans entrer dans le détail des commandes utilisées, j'obtiendrai donc un tableau me retournant:

Colonne 1- l'uniforme de mon joueur (le className de l'uniforme)

Colonne 2- le chapeau de mon joueur (le className du chapeau)

Colonne 3- la valeur de dégat de mon joueur ( un numero entre 0 et 1).

 

La 1ere colonne portera toujours le numero 0, la deuxième le 1, la 3ème le 2 et ainsi de suite. Le numéro de colonne est donc mathématiquement (sa position - 1).

 

Donc la 3ème colonne porte le numéro: 3 - 1 = 2.

 

Pourquoi vous parlez de mathématiques ? Car chaque colonne peut être "interrogée", en faisant un appel à son numéro de colonne, c'est ce qui est appelé le select.

 

Si je veux connaitre une des valeurs de mon tableau, il me suffira d'appeler son numero.

 

exemple:

Si je veux connaitre le chapeau de mon joueur, j'appelerai la 2ème colonne de mon tableau soit la colonne n° 2 - 1 = 1, donc le select 1.

 

Nous allons utiliser ce que nous avons vu précédement (les variables). Je crée une variable LOCAL que je décide d'appeler "array" et lui donne la valeur de

mon tableau de l'exemple précédent:

 

_array = [uniform player, headgear player, damage player];

 

Imaginons mon joueur porte un uniforme de RANGE MASTER (className = B_RangeMaster_F), une casquette bleu (className = H_Cap_blu) et il n'est pas blessé. Ma variable donnera donc (si nous remplaçons nos commandes par les résultats )

 

_array = [B_RangeMaster_F, H_Cap_blu, 0];

 

donc

_array select 1; est notre chapeau (H_Cap_blu)!

 

 

 

BOOL abréviation de BOOLEAN, déja expliquée plus haut, est une forme d'algèbre dans laquelle toutes les valeurs sont soit VRAIES ou FAUSSES. Seulement 2 possibilités TRUE ou FALSE.

exemple:

side player == WEST;

 

Le résultat ne peut être que vrai ou faux.

 

 

 

CODE cela indique donc une ligne de code, si vous préférez une ligne de script. Un CODE sera toujours entre 2 accolades {...} pour indiquer que c'est un CODE.Regardez l'exemple dans les bases.

exemple:

 

{damage player = 1;}

 

 

 

CONFIG vous vous doutez bien, ce terme en dit déja beaucoup. C'est bien entendu la configuration ! Tout type de commande (configFile, configName, configClasses, ...)

retournant une configuration. Laissons ça de coté, nous y reviendrons au moment voulu.

 

 

 

CONTROLE ceci est utilisé pour les DIALOG (voir à la suite). Les CONTROLE sont les objets qui donnent le contenu d'un DIALOG. Cela peut être une boite, une valeur, un texte, un objet 3D, ... Ils peuvent être interrogés grâce à leur IDC (numéro d'identification unique). Nous reparlerons des CONTROL lorsque nous attaquerons les menus.

 

 

 

DIALOG c'est un élément permettant de modifier l'Interface Graphique de l'Utilisateur (GUI), c'est a dire l'écran de jeu du joueur. Le DIALOG est donc l'élément qui vous permettra de créer des MENUS. Il existe sous 2 types:

 

- DIALOG

- DISPLAY

 

Tout comme pour les CONTROL, nous reviendrons plus en détails la dessus au moment des MENUS.

 

 

 

GROUPE dans ArmA 3, tous les personnages appartiennent à un groupe, qu'ils soient joueurs ou AI (Intelligence Artificielle plus souvent appelée BOT). Les personnages liés dans l'éditeur forment un groupe. Un personnage seul appartient à son propre groupe.

 

 

 

LOCATION c'est une sorte de MARKER. Ce sont tous les points existants sur d'origine sur la map:

 

- NameCity

- NameCityCapital

- NameMarine

- NameVillage

- NameLocal (doit retourner le nom d'un aéroport)

- Hill (les collines)

- Mount (les montagnes)

- Airport (uniquement sur TANOA pour le moment)

 

Ils possèdent: un nom, une faction (side), une position 3D ([x,y,z]), une zone 2D ([x,y] area) et une direction (en degré).

 

 

 

OBJECT rien de compliqué à comprendre, un objet (personnage, maison, véhicule, ...).

 

 

 

SCALAR un nom "scientifique" pour nous indiquer les numéros ! N'oubliez jamais qu'ArmA est une "super calculatrice". Il vous permettra d'effectuer de très grosses opérations et d'utiliser des formules de géométrie (sinus, cosinus, tangentes, radian, ...). En rose dans poseidon.

 

 

 

SCRIPT je pense pouvoir passer les détails ...

 

 

 

SIDE simplement la FACTION, west, east, civilian, ...

 

 

 

STRING c'est une chaine de caractères entouré par des guillemets "". En jaune dans poseidon.

 

 

 

TEXT la différence avec le STRING, est qu'il peut être utilisé comme du hTML. Vous pouvez le "structurer" (modifier la police, la taille, la couleur, ...) en utilisant certaines commandes (https://community.bistudio.com/wiki/Structured_Text pour plus de détailles). Comme le STRING, il sera entouré de guillements et apparaitra en jaune dans poseidon.

 

 

 

TEAM_MEMBER je dois vous avouer que je ne l'ai jamais utilisé !

 

 

 

NAMESPACE voici une des complexités d'ArmA. Il faudra bien prendre en compte ceci. A l'intérieur d'arma, vous avez plusieurs "ESPACE" de mémoire.

 

- missionNamespace (l'espace de la mission)

- uiNamespace (l'espace de l'utilisateur)

- parsingNamespace (l'espace des scripts)

 

Vous pourrez faire appel à ses différents "espace" afin de stocker des variables.

 

 

 

 

Nous pouvons maintenant déchiffrer les commandes les plus courantes. Nous commencerons par les commandes "ROUGE", celles qui ne fonctionnent jamais seul:

 

********************

 

if (... votre condition ...) then {

... votre code ...

};

 

Nous l'avons déja vu dans notre tout 1ere exemple.

Si (une condition qui à pour résultat un BOOL) alors {exécuter ce CODE};

 

********************

 

if (...) then {

... code pour la condition remplie ...

} else {

... code pour la condition non remplie ...

};

 

La même chose que l'exemple précédent mais avec un else en plus (else = autre en anglais). le else indique que si la condition n'est pas remplie, alors exécuter cet autre CODE.

Si (une condition qui à pour résultat un BOOL) alors {exécuter ce CODE} autrement {exécuter ce CODE};

 

********************

 

if (... votre condition ...) exitwith {

... votre code ...

};

 

Très utile, cette commande vous permet de quitter un script, si la condition est validé et d'exécuter le CODE.

Si (une condition qui à pour résultat un BOOL) quitter le script et {exécuter ce CODE};

 

********************

 

switch (VARIABLE) do {

case value1 : {... CODE ...};

case value2 : {... CODE ...};

case value3 : {... CODE ...};

};

 

En Anglais switch est un changement/échange et do c'est faire. Cette commande va lancer un CODE selon la valeur retournée de votre VARIABLE. Voici un exemple simple qui vous permettra de comprendre facilement. Nous allons prendre des numeros comme valeur de VARIABLE.

Tout d'abord créons notre VARIABLE:

 

_exemple = 0;

Nous venons d'indique que _exemple a une valeur de 0.

Aux emplacements case, nous allons indiquer les valeurs possible de _exemple. Dans notre cas nous nous limiterons à 0,1,2 .

 

Voici ce que cela donne:

 

_exemple = 0;

 

switch (_exemple) do {

case 0 : {... CODE ...};

case 1 : {... CODE ...};

case 2 : {... CODE ...};

};

 

A présent notre switch va controler la valeur de notre VARIABLE et executer le CODE indiqué selon le résulat (dans notre cas le code de case 0(puisque nous avons donné 0 comme valeur à notre variable). Si nous avions donné la valeur de 2 à notre VARIABLE alors le CODE de la case 2 aurait été exécuté.

 

Dans notre exemple nous avons utilisé une valeur SCALAR mais nous aurions pu utiliser tout type de donnée énuméré plus haut, exemple avec SIDE

 

_exemple = SIDE player; (VARIABLE est donc = à la faction du joueur)

 

switch (_exemple) do {

case WEST : {... CODE ...};

case EAST : {... CODE ...};

case independant : {... CODE ...};

};

 

Dans cet exemple, si mon joueur est blufor alors on execute le CODE case WEST, si il est opfor le CODE case EAST et si il est indépendant le CODE case independant.

 

 

********************

 

while (... votre condition ...) do {

... votre code ...

};

 

Voici une commande qui permet de créer une boucle (LOOP). Ce type de commande est à utiliser avec parcimonie, mal utilisé ou en trop grand nombre, les performances du script seront mauvaises et une partie des ressources de votre machine ou du serveur, seront impactées.

while (anglais = tant que) votre condition sera vrai (true),do ArmA exécute votre CODE tout le temps ! Il aura tout de même une fin après 10 000 cycles, ce qui vous laisses du temps.

tant que (une condition true) faire {exécuter ce CODE};