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

Réapparition des joueurs

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

Mise à jour:04/03/2015

Réapparition des joueurs

Il n'existe pas de base dans ArmA 3 de scripts de réanimation qui permettent de réanimer un joueur tué/blessé sur le terrain.
A la place, les joueurs réapparaissent sur un point déterminé ou une série de points déterminés. La manière dont la réapparition est gérée est liée au configurations de la mission.

Avec ArmA 3, les options de base ont évolué, on n'est plus limité par une réapparition à la Base, on peut maintenant faire plus de manière simple.

Ce tutoriel nécessite de modifier le fichier Description.ext, ce fichier est à créer soi-même à la racine du répertoire de mission.

Dans ce tutoriel je ne vais pas parcourir tous les types de respawn possible, ce serait trop long.
Si vous voulez un aperçu de ce qui peut se faire, je vous recommande ce lien sur le Biki, googleisé en Franglais: ArmA 3 Respawn

La mission d'exemple qui illustre les points détaillés ci-dessous:
ExempleRespawn.Stratis.zip
(1.45 Kio) Téléchargé 745 fois


Type de respawn

Dans ArmA il existe 6 types de respawn:
0"NONE"Il s'agit du plus restrictif, lorsque vous mourrez, vous obtenez cet écran où vous voyez votre cadavre et celui qui vous a tué. C'est la valeur par défaut en SP.
1"BIRD"C'est le mode par défaut en MP, lorsque vous mourrez, si tous les joueurs sont morts, l'écran de fin de mission s'affiche, sinon vous continuez à existé en "mouette" et vous pouvez voir ce qui se passe.
2"INSTANT"Vous réapparaissez à l'endroit de votre mort, par défaut, un compteur s'affiche et dépend du respawnDelay.
3"BASE"C'est de loin le type le plus utilisé si une mission contient un script de revive quelconque. Par défaut, le joueur réapparaît sur la position indiquée par le marqueur "respawn_[camp du joueur]".
4"GROUP"Dans les parties où le joueur est avec des IAs, il peut utiliser l'écran de TeamSwitch pour choisir une unité de son groupe qui est jouable.
5"SIDE"Dans les parties où le joueur est avec des IAs, il peut utiliser l'écran de TeamSwitch pour choisir une unité de son camp qui est jouable.
De ces 6 types, je ne m'intéresserai ici qu'au seul type "BASE".
C'est celui qui a généralement le plus de sens pour une mission multijoueur, même en PvP/TvT.

Afin de choisir ce type de respawn, vous devez ouvrir votre répertoire de mission et éditer le fichier Description.ext, s'il n'existe pas, créez le.
Le contenu doit être au minimum:

Code : Tout sélectionner

respawn = 3; // ou bien le texte: "BASE"
respawnDelay = 5;
Respawn: otez que vous pouvez donner la valeur numérique du type de respawn ou le texte qui lui correspond.
RespawnDelay: c'est le temps que le joueur doit attendre avant de réapparaître. Même si vous utilisez un script de revive, je dirais même plus, SURTOUT si vous utilisez un script de revive, je vous recommande de ne pas mettre moins de 5 secondes.
Ceci laissera le temps aux scripts de faire leur boulot pour gérer votre décès, la sauvegarde de votre équipement, etc.




Template de respawn

Dans les dernières version d'ArmA 3, BIS a ajouté la possibilité d'utiliser des templates de respawn. Le principe est très simple, ce sont des scripts qui se lancent à la mort d'un joueur.
Vous pouvez laissez les templates par défaut (ceux qui sont liés au type de respawn) ou bien définir vous même ceux que vous souhaitez.
Vous pouvez même ajouter (par des addons) vos propres templates.

Le choix se fait en ajoutant dans le fichier Description.ext l'option "respawnTemplates", comme par exemple:

Code : Tout sélectionner

respawn = 3;
respawnDelay = 5;
respawnTemplates[] = {"MenuInventory","MenuPosition"};
Dans le cas ci-dessous, on change les valeurs par défaut du type "BASE" qui est normalement:

Code : Tout sélectionner

{"Base","Counter"}
La liste des templates préexistants (pas nécessairement exhaustive) se trouve sur la page consacrée au Respawn.
Un seul nous intéressera vraiment ici, "MenuPosition".



Respawn à la base

Rentrons un peu plus dans les détails du template par défaut du type "BASE".
Votre fichier description.ext ressemble à ceci:

Code : Tout sélectionner

respawn = 3;
respawnDelay = 5;
Lorsqu'un joueur meure, au bout de 5 secondes il réapparaît sur la position qu'il avait au moment de mourir.
ATTENTION: Il aura l'équipement qu'il avait en commençant la partie!!!!

Bon, ça peut fonctionner, mais généralement c'est pas génial... si tu es mort là... c'est que ce n'était pas une bonne position :)

Donc, on va modifier tout ça.
Le comportement par défaut du respawn sur base, c'est de faire réapparaître les joueurs sur le marqueur de leur camp.
Ce marqueur porte le nom "respawn_[camp]".
Dans le cas d'une unité BLUFOR il s'agira de "respawn_west", pour un OPFOR "respawn_east", etc.

Sur carte, on va donc placer un marqueur "respawn_west" et mourir un coup...
Image

On réapparaît là où se trouve le marqueur "respawn_west", généralement un peu plus à l'abri. Toujours avec l'équipement qu'on avait au départ.

On peut effectuer une petite variation sur le style, on peut ajouter des marqueurs: "respawn_west_1", "respawn_west_route", etc.
Du moment que le marqueur commence par "respawn_west_", il sera utilisé pour choisir aléatoirement une position de respawn, ce qui peut être intéressant.



Respawn avec sélection du point

Bon, on a vu le comportement de base... et c'est mieux que simplement mourir ou réapparaître là où on vient de mourir, mais on peut faire mieux.
Au lieu du comportement par défaut, on va choisir la possibilité de sélectionner le point de réapparition.
Il faut commencer par modifier le fichier description.ext:

Code : Tout sélectionner

respawn = 3;
respawnDelay = 5;
respawnTemplates[] = {"MenuPosition"};
On va aussi ajouter deux marqueurs sur la base:
  • "respawn_west_1", sans texte
  • "respawn_west_2", avec le texte "hangars"
Image

Maintenant on relance le jeu et lors de la connexion, on est invité à choisir un point de départ.. génial ;)
Les marqueurs qui ont un texte afficheront ce texte, les autres afficheront le nom du lieu défini dans ArmA le plus proche.
Image

Idem lorsqu'on meurre, on a la possibilité de choisir son point de réapparition!



Ajouter des points de respawn au cours de la partie

Bon, tout ça c'est bien joli, mais en début de mission, ce n'est pas top d'avoir déjà tous les points possible de réapparition.
C'est mieux que les points apparaissent au fur et à mesure de l'avancement de la mission.
A tout problème, sa solution!!

Il suffit de placer le point de départ, le marqueur "respawn_west" et ensuite d'ajouter des points de réapparition au fil de la mission.
On fait ça très simplement à l'aide d'un déclencheur et de la fonction BIS_fnc_addRespawnPosition.

On doit d'abord placer un marqueur sur le futur point de réapparition, par exemple: "respawn_road" et on lui donne un texte, "sortie base".
Image

Maintenant, on place un déclencheur. Normalement, il se déclenchera quand un événement se produit dans la mission, la destruction d'une tour, la conquête de la base, etc.. ici je vais simplement mettre un délai d'une minute.
Image

Au démarrage de la partie, le point n'est pas disponible, mais au bout de 60 secondes, si on meure:
Image



Ajouter un point de respawn mobile

Dans certaines missions, on souhaitera un point de réapparition mobile, généralement un véhicule.
Rien de plus simple, il suffit d'ajouter ceci dans la ligne d'initialisation du véhicule:

Code : Tout sélectionner

[west, this] call BIS_fnc_addRespawnPosition;
Image

Vous réapparaîtrez dans le premier poste de libre dans le véhicule.
Image



Et voilà... les bases de la réapparition des joueurs.

Si vous souhaitez quelque chose de plus avancé, avec la possibilité de soigner, vous devrez vous attaquer à un script de revive.
Personnellement je suis parti du BTC Revive et je l'ai modifié pour l'adapter à mes besoins, mais il y a d'autres choix tout aussi valides.


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 commandes d'ArmA

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

Mise à jour:28/11/2014

Création de tâches avec les commandes d'ArmA

Ce tutoriel reprend la création des tâches à l'aide de déclencheurs et de lignes de commande.
Si le scripting vous fait peur, vous pouvez utiliser les modules fournis par BIS pour gérer les tâches.
Le tutoriel Création de tâches avec les modules est là pour ça. Les modules ne font en fait que masquer ces lignes de commande.

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 de la tâche

La première chose, c'est de créer une tâche. Il y a plusieurs moyens de le faire, comme par exemple dans l'initialisation d'un objet statique sur la carte (logique de jeu ou autre), mais ce n'est pas toujours simple de retrouver la tâche en question.
Pour cela, j'essaye de regrouper la gestion des tâches à un seul endroit sur la carte, à l'intérieur de déclencheurs qui leurs sont dédiés.

On va donc commencer par placer un déclencheur qui a comme condition "true", ce qui veut dire, qu'il se déclenchera au lancement de la mission.
On ajoute aussi un petit délai, la tâche deviendra donc disponible au bout de 5 secondes.
Image

La clé ici, c'est la commande createSimpleTask.
Elle prend 2 paramètres:
  • l'unité à laquelle s'applique la tâche
  • un tableau contenant le titre de la tâche
Cette commande renvoie comme résultat la tâche qui a été créée. C'est pour cela que nous allons assigner le résultat à une variable globale (lisez le tutoriel sur les variables) pour pouvoir modifier et utilisez cette tâche dans d'autres déclencheurs et scripts.

Nous obtenons le code suivant:

Code : Tout sélectionner

TACHE1 = player createSimpleTask ["Mon titre"];
La variable TACHE1 contiendra donc la tâche qu'on vient de créer.

Comme un déclencheur est local à chaque ordinateur connecté à la mission. L'activation se lancera sur chacun des PCs indépendamment. On peut donc utiliser la variable spéciale player qui renvoie le joueur du PC sur lequel s'exécute la commande.

De nombreuses fonctions et commandes acceptent un nombre variable de paramètres, pour cela, on leur passe un tableau de valeurs.
Dans le langage SQF, un tableau est délimité par les caractères [ et ] et chaque valeur est séparée par une virgule.

Prévisualisez la mission, allez sur la carte, puis sur la carte, affichez l'option Tâches (il y a un raccourci clavier, mais il est dépendant de votre configuration, donc je ne m'aventurerai pas dans cette voie là...).

Vous voyez que votre tâche nouvellement créée est là, mais qu'elle ne contient rien d'autre qu'un titre.
Image




Ajouter une description à une tâche

Un titre c'est bien... mais une explication... c'est mieux. Pour ajouter du contenu à votre tâche, il faut appeler une deuxième commande qui va définir les textes de votre tâche.

La commande setSimpleTaskDescription permet de définir les textes liés à une tâche.
Elle attend 2 paramètres:
  • la tâche à modifier
  • un tableau contenant le titre de la tâche, la description de la tâche, le texte du marqueur de tâche (s'il y en a un).
Ce qui nous donne le code suivant:

Code : Tout sélectionner

TACHE1 setSimpleTaskDescription ["Mon titre","Ma description de tâche","texte marqueur"];
Image


Dans notre cas, il n'y a pas de marqueur de tâche, mais vous pouvez associer une tâche et un marqueur à l'aide de la commande setSimpleTaskDestination.
Cette commande attend 2 paramètres:
  • La tâche à laquelle associer la position
  • La position sur laquelle le marqueur de tâche devra être placé
Deux exemples de code possible:

Code : Tout sélectionner

TACHE1 setSimpleTaskDestination (markerPos "mon_marqueur"); // Position d'un marqueur
TACHE1 setSimpleTaskDestination (position leader_ennemi); // Position d'une unité sur carte en début de partie
Une dernière alternative est la commande setSimpleTaskTarget qui permet de désigner une cible mobile.

Code : Tout sélectionner

TACHE1 setSimpleTaskTarget [leader_ennemi, true];
Il est aussi important de noter que vous pouvez mettre dans la description d'une tâche plus que du simple texte. Pour cela, il vous suffit d'utiliser les balises (semblables à du HTML) disponibles dans ArmA. Ces balises sont décrites ici: Les balises pour structurer vos textes
Il existe en plus de cela, deux balises mal documentées:

Code : Tout sélectionner

<marker name="enemyBase">161170</marker>
 <execute expression="Code to execute">Text</execute>
Je ne rentrerai pas dans le détail de l'utilisation des balises, mais il est bon de savoir qu'elles existent.




Modifier le statut d'une tâche

Ajouter des tâches à la mission, c'est un début, mais il faut aussi pouvoir modifier le statut des tâches pour qu'elles soient réussies, échouées ou annulées.
Tout ça se fait à l'aide d'une nouvelle commande: setTaskState.
Cette commande attend 2 paramètres:
  • La tâche à modifier
  • Le nouveau statut de la tâche qui DOIT être l'une des valeurs suivantes: "Succeeded" (succès), "Failed" (échec), "Canceled" (annulé), "Created" (créé), "Assigned" (assigné)
Notez que le statut "created" est assigné par défaut lorsque la tâche est créée par la commande createSimpleTask et que le statut "Assigned" est assigné par défaut lorsqu'on clique sur le lien "Définir comme tâche actuelle" dans la description de la tâche.

Le code du déclencheur est très simple, on défini une condition d'activation (ici la présence d'unités BLUFOR dans le périmètre) et à l'activation, on change le statut de la tâche.
Image

Pour vous donner une idée, voici à quoi ressemble la zone de test que j'ai créée. Avec à gauche le premier déclencheur qui crée la tâche et à droite le déclencheur qui détecte la zone.
ATTENTION Si vous entrez dans la détection de zone avant que la tâche ne soit créée, la commande setTaskState n'aura évidemment aucun effet... votre tâche ne sera JAMAIS validée.
Dans de nombreux cas (comme ici), la solution est simple, il suffit de mettre le déclencheur en mode "Répétition", mais parfois ce n'est pas aussi simple...
Image

Attendez que la tâche soit créée, entrez dans la zone et regardez vos tâches dans la liste, vous verrez qu'elle est maintenant validée.

Image




Afficher les changements de statut d'une tâche

Si vous avez déjà joué aux missions solo d'ArmA vous aurez sans doute remarqué de petites fenêtres de notification qui indiquent les événements importants. C'est fenêtre sont créées avec la fonction BIS_fnc_showNotification.

On va légérement modifier le code de nos déclencheurs pour afficher les changements de statut des tâches.
On n'utilise plus ici une commande d'ArmA, mais une fonction, la différence est expliquée plus en détails dans le tutoriel sur les notions de base du scripting.
Une fonction doit être appelée sous la forme:

Code : Tout sélectionner

[paramètre1, paramètre2,...] call nom_de_fonction;
Dans notre cas, la fonction attend 2 paramètres:
  • Le template à utiliser pour afficher la notification (il définit la couleur du texte et l'icône)
  • Un tableau avec la liste des textes à afficher. Dans notre cas, c'est le deuxième texte qui nous intéresse.
Vous pouvez consulter la liste des différents template disponibles pour la fonction, ce qui compte, ce sont les noms des classes ("class TaskAssigned", etc.), ce sont ces noms que vous entrerez comme premier paramètre de la fonction.
Ce qui nous intéresse pour le moment: "TaskCreated", "TaskSucceeded".

Le code pour appeler la fonction est donc:

Code : Tout sélectionner

["TaskCreated",["","Titre de ma tâche"]] call BIS_fnc_showNotification;
Ajoutez ce code à la suite du code déjà présent dans le premier déclencheur, celui qui crée la tâche avec createSimpleTask.

Image

Lancez la prévisualisation de la mission.
Attendez les 5 secondes du déclenchement et vous verrez la tâche s'afficher sur l'écran tel que ci-dessous:
Image


La deuxième étape est d'afficher le succès de la tâche.
Dans le deuxième déclencheur, celui qui utilise setTaskState, placez le même code, mais avec un autre template:

Code : Tout sélectionner

["TaskSucceeded",["","Titre de ma tâche"]] call BIS_fnc_showNotification;
Image

Lancez la prévisualisation, attendez la création de la tâche et ensuite entrez dans la zone, vous verrez apparaître la fenêtre suivante au moment de la validation de la tâche.
Image



Et voilà... on a créé et mis à jour une tâche à l'aide des commandes d'ArmA.
Ce n'est pas nécessairement la manière la plus simple de le faire, mais c'est ce que vous devrez faire, si vous souhaitez gérer ces créations dans des scripts plutôt qu'au travers de modules.


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

Sauvegarder/publier sa mission

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

Mise à jour:03/06/2015

Sauvegarder/publier sa mission



Sauvegarder sa mission

Une fois votre mission écrite, il n'est pas possible de la partager tant qu'elle n'est pas sauvegardée.
Les icônes de sauvegarde (les disquettes en haut de l'écran) vous permette d'enregistrer votre mission.
Pour l'exporter sous forme de PBO solo ou multi, sélectionnez l'option "Sauvegarder sous".
Image

La nouvelle fenêtre qui s'ouvre vous offre 5 choix, mais on va s'intéresser aux plus importants.
Image




Exporter sa mission en solo ou multi

Lorsque vous choisissez l'une des options "Exporter vers.." un fichier PBO de mission est créé dans l'arborescence d'ArmA.
Vous pouvez retrouvez ces fichiers sous:
[Répertoire d'installation]\Missions: Pour les missions en solo
[Répertoire d'installation]\MPMissions: Pour les missions en multijoueur

Il suffit de copier ce fichier PBO sur votre serveur pour qu'il soit accessible lorsqu'on utilise la commande "#missions".
Si vous hébergez la partie sur votre propre PC, il n'y a rien à faire, elle est directement accessible dans la liste.

Image




Publier sur le Steam Workshop

Si vous sélectionnez cette option, vous aurez la possibilité de publier votre mission sur le workshop. Une nouvelle fenêtre s'ouvrira et vous n'aurez qu'à remplir les informations demandées.
Pensez à remplir la liste des tags qui décrivent votre mission, c'est ce qui permettra aux joueurs de la trouver facilement.

Image


Retour vers 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

Le répertoire de mission

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

Mise à jour:14/11/2014

Le répertoire de mission

Lorsqu'on crée une mission, on peut se contenter des éléments placés dans l'éditeur, mais si on souhaite créer des missions plus complexes, il deviendra vite nécessaire pour rendre l'édition plus confortable d'utiliser des fichiers externes.


Les fichiers les plus utilisés

De base, un répertoire de mission créé avec ArmA ne contient que le fichier "mission.sqm" qui contient les éléments placés avec l'éditeur.
Mais il en existe plusieurs autres qui forment la base de la création de mission.

Les fichiers de base sont:
  • mission.sqm : contient les objets placés avec l'éditeur, NE JAMAIS l'éditer à la main!
  • description.ext : contient les informations de configuration de la mission
  • init.sqf : c'est le premier script exécuté dans une mission
  • Les scripts du créateur de mission
On va parcourir un peu dans le détails le contenu des différents fichiers.

Description.ext

Ce fichier sert à affiner la configuration de la mission. Par exemple, si on souhaite avoir un nom ou une image qui s'affiche lors du chargement de la mission, c'est ici que ça se passe.
Pour commencer, un exemple de contenu:

Code : Tout sélectionner

onLoadName = "Le nom de ma mission";
onLoadMission = "La description de la mission";
author="[V]Tyrghen";
loadScreen = "image_intro.jpg";

disabledAI=1;
debriefing=0;
showGPS=0;
respawn=3;
respawnDelay= 5;

class Header
{
	gameType = "COOP";
	minPlayers = 1;
	maxPlayers = 16;
};
Toutes les explications peuvent être retrouvées sur le Wiki de BIS:
http://community.bistudio.com/wiki/Description.ext

onLoadName : Le nom de la mission affiché au dessus de l'écran de chargement
onLoadMission : Le texte de la mission affiché au bas de l'écran de chargement
author : Le nom de l'auteur de la mission
onLoadIntro : Un message à afficher lors du chargement de la mission
onLoadIntroTime : Défini si oui ou non on affiche l'heure et le jour lors du chargement de l'intro
onLoadMissionTime : Défini si oui ou non on affiche l'heure et le jour lors du chargement de la mission
loadScreen : Le chemin vers l'image (PAA ou JPG) qui sera affichée dans l'écran de chargement, elle doit se trouver dans le répertoire de mission

disableAI : Si sur "1", les postes non pris par des joueurs ne pourront PAS être attribués à des IAs
debriefing : Défini si le débriefing est affiché ou non à la fin de la mission
showGPS : Si sur "0" la mini carte du GPS ne s'affiche plus
respawn : Sur 3 les joueurs réapparaissent sur le marqueur "respawn_west" ou "respawn_east" suivant leur camp.
respawnDelay : Le nombre de secondes avant qu'un joueur puisse réapparaître dans le jeu. Si vous utilisez un script de revive ne descendez pas sous 3 secondes... ou bien vous aurez des problèmes avec les scripts.

La classe Header défini les informations affichées dans la sélection de mission et dans le listing des serveurs.
gameType : COOP, CTF, etc. (BIS Wiki)

La plupart du temps, si une interface existe dans un script, un lien devra être ajouté dans Description.ext qui pointe vers le fichier de définition de cette interface.
Par exemple, pour le Virtual Ammobox System:

Code : Tout sélectionner

#include "VAS\menu.hpp"

Init.sqf

C'est le premier et seul script lancé par la mission sans qu'on ai besoin de l'appeler.
Donc, tous vos appels de scripts, s'ils ne sont pas appelés par un déclencheur ou dans la ligne d'initialisation d'une unité, seront appelés à partir d'ici.

Ci-dessous j'ai mis un exemple très simple qui crée du logging dans le fichier RPT (c'est comme ça que vous pourrez débugger vos missions) et qui donne directement une erreur. De cette manière vous verrez directement ce que ça donne dans le RPT et avec "-showScriptErrors".

Code : Tout sélectionner

sleep 3;

if (isServer) then {
	diag_log ["Je suis sur le serveur",isServer];
};

if (!isDedicated) then {
	diag_log ["Je suis sur le client",isDedicated];
};

sleep 5;

// Cette ligne de code va générer une erreur
getPos [];

Les scripts spécifiques à la mission

Ci-dessous vous trouverez des scripts très simples, qu'on peut appeler tant dans la mission que dans le code pour tester l'appel de scripts.
Ces scripts se contentent d'afficher un message.

Je recommande de toujours placer les scripts spécifiques à une mission dans un sous répertoire.
Moi j'ai choisi d'appeler ce répertoire "mission" parce que je trouve ça plus simple.

Pour appeler "monscript.sqf" depuis un élément de la mission (un déclencheur ou l'initialisation d'un objet) tapez:

Code : Tout sélectionner

nul = [] execVM "misson\monscript.sqf";
Pour l'appeler depuis le "init.sqf" tapez:

Code : Tout sélectionner

[] execVM "misson\monscript.sqf";
Le contenu du fichier "monscript.sqf":

Code : Tout sélectionner

hint "J'ai été exécuté!";
De la même manière le fichier "parametres.sqf" peut être appelé depuis un élément de la mission ou le fichier init.sqf, mais celui-ci accepte des paramètres.
Essayez par exemple dans le "init.sqf":

Code : Tout sélectionner

["un paramètre",isServer,local player,player] execVM "misson\parametres.sqf";
Le contenu du fichier "parametres.sqf":

Code : Tout sélectionner

hint format ["%1",_this];
La variable "_this" est ce qu'on appelle une variable magique, elle est automatiquement créée et remplie avec le(s) paramètres donné(s) au script.
Dans ce cas ci, on a donné:
  • "un paramètre": une chaîne de caractère
  • isServer: le contenu d'une variable prédéfinie
  • local player: le résultat d'une commande interne d'ArmA
  • player: le contenu d'une variable globale, ici, le joueur.
Et voilà... ce sont les éléments les plus importants du contenu d'un répertoire de mission.


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

Script: déplacer le point de réapparition

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

Mise à jour:03/06/2015

Script: déplacer le point de réapparition

Dans certaines missions, vous pouvez souhaiter déplacer le point de réapparition avec l'avancement de la mission, de manière à éviter que les joueurs n'aient à parcourir de longues distances.
C'est quelque chose de très simple à faire, donc autant ne pas s'en priver et en plus, c'est un bon exercice d'utilisation de commandes d'ArmA dans un déclencheur.
ExempleDeplacerMarqueur.Stratis.zip
Mission contenant les objets et le code décrit dans ce tutoriel
(1.08 Kio) Téléchargé 591 fois


Placer les marqueurs nécessaires

On va commencer par placer le marqueur de respawn de notre camp quelque part sur la carte.
Pour plus d'information sur les options de respawn, consulter le tutoriel prévu à cet effet.

Le joueur placé étant du camp "BLUFOR" on place le marqueur "respawn_west".
Vous remarquerez que j'ai donné une icône et un nom au marqueur, c'est pour pouvoir voir le résultat sur carte directement.
Image


Ensuite, on place un deuxième marqueur nommé "nouvelle_position" qui permet de visualiser l'endroit où se trouvera le point de réapparition après son déplacement.
Image



Placer le déclencheur

On va maintenant placer et initialiser le déclencheur qui va effectuer le déplacement.
J'ai pris une condition très simple pour illustrer, on détecte la présence d'un blufor, mais on pourrait mettre une condition plus complexe.

Le code d'activation du déclencheur est:

Code : Tout sélectionner

"respawn_west" setMarkerPos (markerPos "nouvelle_position");
La commande setMarkerPos attend 2 paramètres, d'abord, le nom du marqueur sur lequel effectuer l'action, ensuite la position à assigner à ce marqueur.
Cette position doit être une coordonnée sur carte sous forme de tableau (X,Y,Z) du style: [1234, 2345, 12]
Mais bon, ce n'est pas très facile de savoir où se trouve ces coordonnées, surtout que l'éditeur ne nous donne pas la position en [X,Y,Y].
Donc, on place un autre élément sur carte, ici le marqueur "nouvelle_position" et on appelle la commande markerPos qui nous renvoie la position [X,Y,Z] du marqueur qu'elle reçoit comme paramètre.

Image



Le résultat en image

Voici à quoi ressemble la configuration de départ.
Image


Lorsque le joueur avance dans la zone du déclencheur, le marqueur de respawn est déplacé.
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

Script: téléportation vers le leader du groupe

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

Mise à jour:04/06/2015

Script: téléportation vers le leader du groupe

Dans vos premières missions vous n'aurez sans doute pas de script de revive complexe, l'utilisation des options de base de la réapparition a alors des limitations un peu contraignantes. Le type qui meurt pendant la mission doit se taper à pied le trajet pour rejoindre... pas très drôle.
Ou alors, quelqu'un rejoint en cours de route... oui mais comment rejoindre les copains qui sont déjà loin?

C'est ce genre de problèmes qu'on va résoudre ici en une seule ligne de code.
ExempleTeleportation.Stratis.zip
Mission utilisée pour le tutoriel
(1.24 Kio) Téléchargé 694 fois


Placer les unités

Ce genre de script n'a de sens que si on joue en multijour, on va donc placer un groupe d'unités NATO, en passant par l'outil de placement de groupes. Image

Ensuite on doit modifier un des personnages pour être le joueur qui servira à tester la mission.
Image

Vous pouvez ensuite modifier les autres unités comme "Jouables" ce qui les fera apparaître dans la liste des unités disponibles sur le lobby.
Image



Placer l'objet de téléportation

On va utiliser un drapeau comme dans la domination, il suffit de le placer et d'ajouter l'initialisation suivante:

Code : Tout sélectionner

this addAction ["Téléportation", { player setPos (getPos leader player); },[],0,true,true];
Image

Passons maintenant en revue le code de l'initialisation!

"this" représente l'objet que nous sommes en train d'éditer.

Voici ce que dit le wiki à propos des paramètres de la commande addAction;

Code : Tout sélectionner

unit addAction [title, script, arguments, priority, showWindow, hideOnUse, shortcut, condition]
Remarque: la page du biki donne plus de paramètres, mais ils ne sont valables que pour TKOH donc je ne les ai pas repris.

Le premier arguement est l'objet sur lequel on souhaite ajouter l'action, dans notre cas "this" et donc la caisse de munition.
Le deuxième est la liste des paramètres de l'action:
  • title : Le titre de l'action à afficher dans le menu de la roulette
  • script : Le nom d'un script sous forme de chaîne de caractère ou bien directement du code ou une fonction.
  • arguments : (optionnel) Une liste d'arguments qui seront passés comme 4 éléments de la variable "_this" passée au script.
  • priority : (optionnel) Une valeur numérique qui indique la priorité de l'action dans la liste du menu roulette (plus haut ou plus bas)
  • showWindow : (optionnel) Une valeur booléenne (vrai/faux) qui indique si l'action doit être visible lorsqu'on approche de l'objet (sans tiliser la roulette)
  • hideOnUse : (optionnel) Une valeur booléenne (vrai/faux) qui indique si l'action doit être masquée une fois utilisée. Ca n'a de sens que si vous avez mis "vrai" à la valeur précédente.
  • shortcut : (optionnel) Si vous voulez utiliser l'action au travers d'un raccourci clavier, vous pouvez donner ici le nom du raccourci tel que défini dans ArmA, la liste complète est sur cette page.
    Dans 99,999% des cas, laissez une chaîne vide "".
  • condition : (optionnel) Une chaîne de caractère contenant du code à exécuter qui doit renvoyer vrai ou faux (true/false) pour indiquer si l'action doit être visible.
    A part dans des cas avancés, vous ne l'utiliserez pas.
Dans notre cas:
  • Titre: simplement "Téléportation"
  • Script: comme le code est très simple, on le met directement dans l'éditeur au lieu de passer par un fichier.
    Je le détaillerai ci-dessous.

    Code : Tout sélectionner

    { player setPos (getPos leader player); }
  • Paramètres: Aucun, donc je laisse un tableau vide
  • ShowWindow: Je veux que l'action soit visible dès que j'approche le drapeau, je met donc "true" (vrai).
  • HideOnUse: Je veux que l'action disparaisse une fois utilisée, je met donc "true" (vrai).
    Ce n'est pas absolument nécessaire puisqu'on sera téléporté loin du drapeau, mais c'est une bonne habitude à prendre :)
Le code exécuté est très simple..
Notez qu'il doit être contenu dans des accolades, parce qu'il s'agit ici de code, tout comme pour une fonction, on définit son contenu entre accolades.

player est une commande spéciale qui représente le joueur.

setPos est une commande qui permet de modifier la position d'un objet qui lui est donné en premier paramètre avec la position qu'elle reçoit comme deuxième paramètre.

getPos est un alias de position et renvoie la position de l'objet qu'on lui passe.

leader renvoie l'unité qui est leader du groupe dont l'unité passée en paramètre fait partie. Ici on passe player (le joueur actuel) donc on le téléporte vers son chef de groupe.




Le résultat en image

On peut maintenant lancer la prévisualisation.
Pour que ce soit un peu plus explicite, j'ai ajouté des points de passage au groupe pour qu'il se déplace.
Comme je ne suis pas le leader du groupe, les IAs s'en vont gentillement.

Vous remarquerez que sur le drapeau on voit apparaître l'option de téléportation, sans devoir passer par le menu déroulant, parce que nous avons activé l'option "ShowWindow"
Image


Si je clique sur l'option, je suis téléporté sur mon chef de groupe.
Image


A partir d'ici, on peut compliquer le script pour recevoir une position aléatoire autour du chef de groupe grâce à la commande findEmptyPosition ou on peut ajouter des tests pour le cas où on est soi-même chef de groupe et pouvoir se téléporter vers un des membres (units, group), etc.
Il y a toujours moyen de compliquer les scripts pour faire face à toutes les situations, mais ce n'est pas le but de ce tutoriel.


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

Script: actions et déclencheurs

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

Mise à jour:04/06/2015

Script: actions et déclencheurs

Prenons un exemple de mission très simple, il faut désamorcer une bombe.
Pour pouvoir réagir au désamorçage, pour par exemple, valider la tâche, il faut pouvoir lier l'action et un déclencheur.
C'est ce genre de problème que nous allons résoudre ici.
ExempleActionEtDeclencheur.Stratis.zip
Mission utilisée pour le tutoriel
(1.1 Kio) Téléchargé 628 fois


La bombe à désamorcer

Pour faire simple, je place une caisse de munition pour véhicule et j'ajoute du code à son intialisation.

Code : Tout sélectionner

this addAction ["Désamorcer",{ DEMINER = true; publicVariable "DEMINER"; },[],0,true,true];
Je détaillerai le code un peu plus bas.

Image

Passons maintenant en revue le code de l'initialisation!

"this" représente l'objet que nous sommes en train d'éditer.

Voici ce que dit le wiki à propos des paramètres de la commande addAction;

Code : Tout sélectionner

unit addAction [title, script, arguments, priority, showWindow, hideOnUse, shortcut, condition]
Remarque: la page du biki donne plus de paramètres, mais ils ne sont valables que pour TKOH donc je ne les ai pas repris.

Le premier arguement est l'objet sur lequel on souhaite ajouter l'action, dans notre cas "this" et donc la caisse de munition.
Le deuxième est la liste des paramètres de l'action:
  • title : Le titre de l'action à afficher dans le menu de la roulette
  • script : Le nom d'un script sous forme de chaîne de caractère ou bien directement du code ou une fonction.
  • arguments : (optionnel) Une liste d'arguments qui seront passés comme 4 éléments de la variable "_this" passée au script.
  • priority : (optionnel) Une valeur numérique qui indique la priorité de l'action dans la liste du menu roulette (plus haut ou plus bas)
  • showWindow : (optionnel) Une valeur booléenne (vrai/faux) qui indique si l'action doit être visible lorsqu'on approche de l'objet (sans tiliser la roulette)
  • hideOnUse : (optionnel) Une valeur booléenne (vrai/faux) qui indique si l'action doit être masquée une fois utilisée. Ca n'a de sens que si vous avez mis "vrai" à la valeur précédente.
  • shortcut : (optionnel) Si vous voulez utiliser l'action au travers d'un raccourci clavier, vous pouvez donner ici le nom du raccourci tel que défini dans ArmA, la liste complète est sur cette page.
    Dans 99,999% des cas, laissez une chaîne vide "".
  • condition : (optionnel) Une chaîne de caractère contenant du code à exécuter qui doit renvoyer vrai ou faux (true/false) pour indiquer si l'action doit être visible.
    A part dans des cas avancés, vous ne l'utiliserez pas.
Dans notre cas:
  • Titre: simplement "Désamorcer"
  • Script: comme le code est très simple, on le met directement dans l'éditeur au lieu de passer par un fichier.
    Je le détaillerai ci-dessous.

    Code : Tout sélectionner

    { DEMINER = true; publicVariable "DEMINER"; }
  • Paramètres: Aucun, donc je laisse un tableau vide
  • ShowWindow: Je veux que l'action soit visible dès que j'approche le drapeau, je met donc "true" (vrai).
  • HideOnUse: Je veux que l'action disparaisse une fois utilisée, je met donc "true" (vrai).
    C'est plus réaliste puisqu'on ne désamorce pas la bombe 15 fois.
Le code exécuté est très simple..
Notez qu'il doit être contenu dans des accolades, parce qu'il s'agit ici de code, tout comme pour une fonction, on définit son contenu entre accolades.

DEMINER n'est pas une commande, mais une variable globale, je l'ai mise en majuscule, ce n'est pas obligatoire, mais ça permet quand on relit le code de directement savoir qu'on a affaire à une variable globale. C'est simplement une convention de style. Vous pouvez écrire DeMiNeR si ça vous chante...
On aurait pu choisir n'importe quel autre nom, mais un nom explicite est toujours mieux.

DEMINER = true; On assigne à cette variable la valeur "true" (vrai) lorsque l'action est utilisée.

Mais attention, cette variable globale n'existe pour le moment que sur votre PC et l'action doit se déclencher sur tous les PCs y compris le serveur.
Pour cela, on doit publier le changement de la variable pour que tout le monde sache que cette variable est maintenant égale à "vrai".

C'est ce qu'on fait avec la commande suivante:
publicVariable "DEMINER"; cette commande va envoyer la variable et le changement à tous les PCs connectés.
Notez que le nom de la variable est passé en chaîne de caractère, si vous donnez la variable elle même, c'est son contenu qui sera passé à la commande et non pas son nom.

Et voilà, on a maintenant une action qui publie l'état d'une variable sur le réseau.
On va maintenant en faire quelque chose.



Lier un déclencheur à une variable

On place maintenant un déclencheur sur carte.
Dans notre cas on le fait très simple, on va juste afficher un message, mais on pourrait lier ce déclencheur à l'arrivée de renforts ou à la résolution d'une tâche.

La commande hint attend comme paramètre une chaîne de caractères qu'elle affichera en haut à droite de l'écran avec un petit tintement.

Image



Le résultat 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

Script: déplacer un marqueur avec un véhicule

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

Mise à jour:03/06/2015

Script: déplacer un marqueur avec un véhicule


Avant d'entamer ce tutoriel, je vous recommande de relire les tutoriels suivants:
Mission du tutoriel
ExempleMarqueurMobile.Stratis.zip
Mission contenant les objets et le code décrit dans ce tutoriel
(1.45 Kio) Téléchargé 615 fois

Déplacer un marqueur avec un véhicule au travers de l'éditeur

Dans ce point nous allons créer un petit script à placer dans l'initialisation du véhicule qui va déplacer un marqueur en même temps que le véhicule ce déplace. Je vous laisse imaginer à quoi cela peut servir.
Le marqueur de respawn d'un camp est un marqueur comme un autre... vous pouvez donc le déplacer avec un véhicule.

Commençons par placer un marqueur:
Image

Ensuite on va placer un hunter et vous pouvez lui donner l'initialisation suivante:

Code : Tout sélectionner

nul = this spawn { while { alive _this } do { "marqueur_veh" setMarkerPos (position _this); sleep 2; }; };
Une fois que c'est fait, testez que tout fonctionne comme prévu. Si ce n'est pas le cas, vérifiez que vous n'avez pas fait de fautes de frappe et que toutes les parenthèses et accolades sont là où elles doivent.
Je vais détailler le contenu de cette ligne de code dans un instant.

Image



Analysons le code pas à pas

Pour pouvoir analyser le code, je le réécris d'une manière plus lisible:

Code : Tout sélectionner

nul = this spawn {
    while { alive _this } do {
         "marqueur_veh" setMarkerPos (position _this);
         sleep 2;
    }; // Accolade de while
}; // Accolade de spawn


nul =

La commande spawn renvoie une référence au script qu'elle exécute, ce qui permet, entre autre, à l'aide de la commande scriptDone de savoir si l'exécution est finie.
Le problème, c'est que l'éditeur d'ArmA n'accepte pas que le code d'initialisation renvoie une valeur. Pour cette raison, on doit assigner la valeur renvoyée par la commande à une variable globale choisir arbitrairement.
"nul" est donc notre variable globale et reçoit la valeur renvoyée par spawn.

Si vous ne récupérez pas cette valeur, voici le message d'erreur que vous aurez:
Image

Donc, si la dernière commande que vous utilisez dans votre code renvoie une valeur, il faut toujours l'assigner à une variable.



this spawn { ... };

Le mot clé "this", qui signifie "ce/cet/cette" en anglais, représente le véhicule que vous éditez. Etant donné que nous voulons exécuter du code lié à l'objet qu'on est en train d'éditer, nous utilisons "this".

La commande spawn permet de lancer l'exécution d'un sous-script qui s'exécute dans son propre environnement.
Pourquoi utilisez cette commande ici?
Simplement parce que si vous lancez un script sans fin dans l'initialisation du véhicule, ce véhicule ne terminera jamais son initialisation et la mission ne démarrera jamais... c'est aussi simple que ça.
On doit donc quitter le contexte de l'initialisation et lancer un script secondaire.

Les accolades { } servent à délimiter le code du sous-script. Tout le code qui doit être exécuté par la commande spawn DOIT se trouver entre ses accolades.

Le point virgule ";" à la fin d'une commande sert à délimiter cette commande, si vous ne l'ajoutez pas, vous aurez des erreurs de script. Terminez TOUJOURS votre commande par un point virgule.

Maintenant, pourquoi écrire "this spawn { ... }".
Cette manière d'écrire indique à la commande spawn qu'on lui passe comme paramètre la variable "this". Celle-ci étant le véhicule en cours, la commande spawn reçoit comme seul paramètre le véhicule.



while { alive _this } do { ... };
Examinons maintenant le contenu du script exécuté par spawn.
La première commande est while, qui permet d'exécuter du code en boucle. On peut la traduire par "Tant que".

alive est une commande qui renvoie une valeur booléenne (vrai ou faux) si l'argument qui lui est passé est en vie.
Dans notre cas, vous voyez que nous lui passons "_this". Attention!!! "_this" (notez l'underscore) est différent de "this".
Quand vous démarrez un script (comme ici avec spawn, ou call, ou execVM) tous les paramètres passés à ce script sont contenus dans la variable spéciale "_this" qui est une variable locale au script (elle commence par un "underscore").

Si vous avez besoin de plus de détails sur les variables globales et locales, lisez le tutoriel qui y est consacré: ICI.

Donc, étant donné que nous avons passé à spawn la variable "this" contenant le véhicule, nous reçevons donc le véhicule dans "_this".
La commande "alive _this" renvoie donc "true" (vrai) lorsque le véhicule est en vie.

Le mot clé do (qu'on peut traduire par "faire") permet d'indiquer quel code sera exécuté par la boucle si la condition est vraie.

Notre code se traduit donc par:
Tant que le véhicule est vivant, faire ceci.



"marqueur_veh" setMarkerPos (position _this);

"marqueur_veh" est une chaîne de caractère (on le sait parce que le mot est délimité par des guillemets). Les marqueurs sont un cas particulier.
Les fonctions des marqueurs demande comme paramètre le nom du marqueur sous forme d'une chaîne de caractère.
Comme nous souhaitons changer la position du marqueur avec celle du véhicule, il suffit de l'identifier par son nom.

setMarkerPos est une commande qui permet de modifier la position d'un marqueur. Cette commande accepte deux arguments. En début de commande, le marqueur sur lequel appliquer la commande et en fin de commande, la nouvelle position.

(position _this) renvoie la position du véhicule. La commande position attend un seul argument, l'objet dont elle doit renvoyer la position. Si l'objet n'existe pas, elle renvoie [0,0,0] (le coin inférieur gauche de la carte).
On lui passe évidemment "_this" qui représente notre véhicule.

Les parenthèses sont utilisées pour grouper des éléments. Dans notre cas, "position" et "_this". Ca permet à ArmA de savoir dans quel ordre il doit exécuter les commandes. Ici, le moteur d'ArmA voit qu'ils sont en parenthèses, donc il exécutera d'abord "position _this" et ensuite seulement setMarkerPos.

Si on écrit:
"marqueur_veh" setMarkerPos position _this;
On peut avoir le risque que le moteur ne sache pas dans quel ordre exécuter les commandes.
Bon, en pratique le moteur sait généralement ce qu'il doit faire, mais parfois il se mélange les pinceaux et ça donne des erreurs bizarres...
Donc, si vous groupez des commandes, utilisez les parenthèses!!!!
En plus ça rendra votre code plus lisible et vous vous en féliciterez la prochaine fois que vous devrez relire votre code.

Et on termine évidemment par un point virgule ";" pour clôturer la commande.



sleep 2;

La commande sleep ordonne au script de faire un pause pendant X secondes (deux dans notre cas).
C'est utile pour éviter de surcharger le serveur avec des exécutions inutiles. Si le marqueur bouge toutes les 2 secondes c'est BIEN suffisant.

Si vous ne mettez pas cette commande, le code de la boucle while sera exécuté TRES souvent, ce qui aura un impact très négatif sur les performances du serveur si vous avez beaucoup de véhicules avec des marqueurs (ou d'autres scripts tout simplement).

Donc, partout où c'est possible, pensez à introduire des commandes "sleep" pour alléger le poids de vos scripts pour le serveur.





Déplacer le marqueur à l'aide d'un script dans le répertoire de mission

Nous abordons maintenant l'éternelle question... "To script or not to script".
Faut-il créer un fichier script ou appliquer le code dans l'éditeur.

Pour moi la réponse est simple, si vous répondez "Oui" à l'une de ces questions, vous créez un fichier script:
  • Vous comptez utiliser ce code pour plusieurs objets?
  • Vous avez des idées pour améliorer ce script dans le futur?
  • Vous pensez réutiliser ce script dans d'autres missions?
Pour créer un fichier de script, ouvrez le répertoire de votre mission, celui où se trouve le fichier "mission.sqm" et créez un nouveau fichier avec un éditeur de texte quelconque.

Nommez ce fichier "marqueur_mobile.sqf".
L'extension ".sqf" n'est pas obligatoire, mais si vous utilisez un outil qui fait de la coloration de syntaxe, il faudra l'utiliser. Donc je vous conseille fortement d'en prendre l'habitude.

Placez un nouveau marqueur nommé "marqueur_veh2" avec le texte qui vous convient.
Ensuite placez un nouveau véhicule dans l'éditeur et donnez lui l'initialisation suivante:

Code : Tout sélectionner

nul = [this, "marqueur_veh2"] execVM "marqueur_mobile.sqf";
Image



Analysons le code pas à pas

Il n'y a qu'une ligne de code et elle ressemble énormément à ce que nous avons déjà vu, donc je ne m'attarderai que sur les nouveautés.


[this, "marqueur_veh2"]
Lorsqu'un bloc commence par la parenthèse carrée "[" c'est le début d'un tableau de valeurs. La fin du tableau est indiquée par la parenthèse carrée de fermeture "]" et chaque élément du tableau est séparé par une virgule ",".
Un tableau de valeurs est une liste de valeurs regroupées ensemble pour former une seule variable.

Dans notre cas, notre tableau de valeur contiendra deux valeurs:
  • La variable "this" qui représente le véhicule que nous éditons
  • La chaîne de caractère "marqueur_veh2" qui est donc l'identifiant du marqueur à utiliser

execVM "marqueur_mobile.sqf";

A l'image de spawn, la commande execVM permet d'exécuter un script dans un nouvel environnement d'exécution, ce qui évitera donc de bloquer l'initialisation du véhicule.
Et, tout comme spawn, on passe peut passer un paramètre à la commande, c'est la raison pour laquelle on lui passe un tableau de valeur, pour qu'elle puisse recevoir 2 valeurs.

La commande est suivie par le nom du script, avec son chemin depuis le répertoire racine de la mission.
Dans notre cas, le fichier est dans le même répertoire que le fichier "mission.sqm", on peut donc directement lui donner son nom.

Si le fichier se trouvait dans un sous répertoire "scripts", la commande deviendrait:
nul = [this, "marqueur_veh2"] execVM "scripts\marqueur_mobile.sqf";

Donc, pour résumer, la commande execVM reçoit 1 paramètre, qui est un tableau qu'elle passera au script qu'elle reçoit comme deuxième paramètre.



Ajouter du contenu au fichier "marqueur_mobile.sqf"

Si vous lancez la mission maintenant, rien ne se passe avec le deuxième véhicule et pour cause... le fichier ne contient aucune commande.

Pour commencer nous allons ajouter du code qui nous permet de tester ce que reçoit le script.
Tapez ou copier la ligne de code suivante dans le fichier:

Code : Tout sélectionner

hint format["%1",_this];
Sauvez les modifications et relancez la mission, vous devriez voir un message s'afficher avec le contenu suivant:
Image

On voit donc que la variable spéciale "_this", contient un tableau avec les deux éléments prévus: le véhicule et le nom du marqueur.
Le charabia qui représente le véhicule n'a aucune espèce d'importance, c'est la manière dont ArmA référence les objets auquel on n'a pas donné de nom dans l'éditeur. Si vous aviez donné le nom "vec" dans l'éditeur au véhicule, vous auriez vu "vec" ici.
Faites le test...



Ecrire le script qui déplace le marqueur

Il est maintenant temps d'écrire le vrai code à exécuter:

Code : Tout sélectionner

private ["_veh","_marqueur"];
_veh = _this select 0;
_marqueur = _this select 1;

while { alive _veh } do {
	_marqueur setMarkerPos (position _veh);
	sleep 2;
};
Une fois de plus, je ne reviendrai pas sur les notions déjà vues et je vais passer directement aux nouvelles notions.

Avec une coloration de syntaxe on obtient:
Image



private ["_veh","_marqueur"];

Un script lorsqu'il est exécuté possède deux types de variables, des variables locales et des variables globales.
Je vous invite à relire le tutoriel sur les variables si ce n'est pas déjà fait.

Les variables locales sont soit déclarées dans le script, soit héritée du script qui l'appelle (on peut appeler un script, dans un script, dans un script, etc. à l'infini). Une variable qui ne doit exister que dans le script en cours doit être déclarée "privée".
C'est le but de la commande private on lui passe un tableau contenant tous les NOMS des variables que l'on souhaite garder privées.

Dans notre cas, notre script va utiliser deux variables: _veh et _marqueur.
On passe donc les deux noms (sous forme de chaînes de caractères) à la commande private avant tout autre chose.

A noter, ce n'est pas obligatoire d'utiliser "private", mais dans les scripts plus complexes, vous risquez des effets de bord très bizarre si vous ne le faites pas... donc prenez de bonnes habitudes.


_veh = _this select 0;

Au début de la grande majorité des scripts vous verrez une ou plusieurs lignes de ce type.
Elles permettent d'assigner les paramètres reçus par le script (et contenus dans "_this") à des variables locales au script, pour pouvoir facilement identifier ce qu'on manipule.

La commande select, permet de sélectionner une valeur dans un tableau de valeurs. Les tableaux de valeurs dans ArmA sont référencés par un index numérique commençant pas "0". La première case du tableau a donc l'index 0, la deuxième 1, la troisième 2, etc.

Nous avons appelé le script avec la ligne de code suivante:

Code : Tout sélectionner

[this, "marqueur_veh2"] execVM "[b]scripts\[/b]marqueur_mobile.sqf";
Nous avons donc passé un tableau avec deux valeurs, la première, le véhicule est à l'index 0.
Donc, la ligne de code suivante:

Code : Tout sélectionner

_veh = _this select 0;
Récupère la première valeur du tableau et la place dans la variable "_veh". Cette variable, à partir de maintenant, représente notre véhicule.

Le principe sera le même pour:

Code : Tout sélectionner

_marqueur = _this select 1;
Qui va assigner la deuxième valeur du tableau à la variable "_marqueur".


while { alive _veh } do { ... };

La seule différence ici par rapport à l'exemple précédent, c'est qu'on utilise maintenant la variable locale "_veh" au lieu de la variable spéciale "this" pour représenter le véhicule.


_marqueur setMarkerPos (position _veh);

Même chose que pour le point ci-dessus, on utilise les variables locales au lieu des variables spéciales.
L'avantage ici, c'est que "_marqueur" peut contenir le nom de n'importe quel marqueur passé comme paramètre pas uniquement un seul marqueur. Ce qui rend le code réutilisable.

La règle est donc que si une valeur est amenée à changer suivant l'utilisation du script, vous devez en faire une variable qui est passée comme paramètre au script.
Si on avait simplement utilisé "marqueur_veh" à la place d'une variable, TOUS les véhicules auraient déplacé le même marqueur!!!! Ce marqueur n'aurait fait que sauter d'un bout à l'autre de la carte.

Et voilà... on y est, on a un marqueur mobile et le script qui le déplace.



Le marqueur bouge, victoire, et après?

Lorsque le véhicule est détruit, vous pouvez laisser le marqueur en place ou vous pouvez choisir de l'effacer. Si c'est le cas, à la fin de votre fichier, ajoutez la ligne de code suivante:

Code : Tout sélectionner

deleteMarker _marqueur;
La commande deleteMarker efface tout simplement le marqueur que vous lui passez.
Le marqueur disparaîtra lorsqu'on quitte la boucle while. Et on ne quitte cette boucle que lorsque le véhicule est détruit.

C'est un bel exemple de l'utilité d'un script, imaginez, si vous avez placé 50 véhicules avec marqueurs... vous devriez changer l'initialisation de ces 50 véhicules sans faire de faute... ici, un seul fichier à modifier!



Conclusion

Le scripting est l'un des éléments les plus intéressants du moteur d'ArmA pour ce qui me concerne.
Ce tutoriel devrait vous ouvrir la porte pour l'écriture de vos premiers scripts.

Si vous avez des questions sur ce tutoriel, utilisez le fil dédié!


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

Mission: Détruire le camion/Assassiner le général

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

Mise à jour:27/10/2014

Mission: Détruire le camion/Assassiner le général

Titre
Image

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

Mission: Prendre le contrôle d'une ville

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

Mise à jour:27/10/2014

Mission: Prendre le contrôle d'une ville

Titre
Image

Verrouillé