BaseMission - 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

BaseMission - ArmA 3

Message par Tyrghen » 02 mai 2013, 10:49

Version:2.09b
Mise à jour:29/09/2015

Base Mission ARMA 3

Fichier ZIP:
basemission.stratis.zip
Version 2.09b
(1.9 Mio) Téléchargé 886 fois
Ce fichier contient le répertoire de la BaseMission.

La Base Mission sert de fondement à la création de missions pour les Vétérans. Elle a pour but d'offrir de manière simple des fonctionnalités avancées comme des scripts de patrouille, des objectifs à accomplir, etc. Elle nécessite des connaissances de base de l'édition dans ArmA.
Voyez la comme une librairie de scripts prêts à l'emploi.

Si vous chercher un tutoriel sur l'édition, ça se passe dans le fil: Les bases de l'édition dans ARMA 3


Version intermédiaire, en cours de développement, bugs possibles:
basemission.stratis.zip
Version 2.09c intermédiaire
(1.89 Mio) Téléchargé 671 fois

Mission sur Altis
mission.altis.zip
Mission de démonstration très basique pour la prise en main. Mise à jour pour la Version 2.09b
(1.87 Mio) Téléchargé 738 fois
Une mission très simple pour se lancer dans l'utilisation de la Base Mission.


Pack de templates
bases.zip
Version 2.09b
(14.95 Mio) Téléchargé 773 fois
Ce fichier zip contient des répertoires de mission pour toute une série d'îles. Vous pouvez vous en servir pour créer une mission sur ces îles, sans devoir placer vous même les objets de base.
Chaque template contient:
  • 16 postes pour des joueurs
  • 1 poste pour tester la mission (unité à effacer avant de jouer la mission)
  • 1 MHQ avec ses fonctionnalités
  • 1 Drapeau de téléportation
  • 1 Caisse VAS
Les îles contiennent entre autres, les îles d'ArmA 3, mais aussi celles d'ArmA 2 avec le All In ArmA.

Documentation

  1. Les fichiers SQF dans la racine de la Base Mission sont commentés (enfin.. la plupart), avec des exemples pour détailler leur utilisation
  2. Dans ArmA, avec le visualiseur de Fonctions, vous pouvez regarder les fonctions du groupe "EDT", ce sont les fonctions à utiliser dans l'éditeur quand vous créez vos missions. Une bonne partie de ces fonctions sont maintenant commentées.
  3. La Base Mission est en elle même une démonstration des fonctionnalités. Il suffit d'inspecter le contenu des éléments pour s'en faire une idée.
  4. Des tutoriels complets pour réaliser telle ou telle tâche sont listés ci-dessous.

La documentation de la base mission ArmA 2 donne l'idée du principe qui reste le même ici.

Le secret d'une mission réussie... la simplicité... ne l'oubliez pas :)
Commencez avec quelque chose de simple!

Liste des tutoriels
Anciennes versions
Pièces jointes
basemission.stratis.zip
Version 2.08
(1.87 Mio) Téléchargé 599 fois
basemission.stratis.zip
Version 2.09
(1.87 Mio) Téléchargé 601 fois
basemission.stratis.zip
Version 2.09a
(1.88 Mio) Téléchargé 600 fois

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

BaseMission - ArmA 3 - Fonctionnalités

Message par Tyrghen » 02 mai 2013, 10:59

Mise à jour: 13/10/2014

Fonctionnalités
  • Les objectifs principaux
  • Les tâches
  • Le BTC Revive - Nouvelle version, complètement revue et corrigée
  • Des caisses de munitions VAS disponibles sur les MHQ du BTC Revive
  • Le Virtual Ammobox
  • La synchronisation en JIP des objectifs et des tâches
  • Les interfaces d'administration
  • Les modules de base du MSO (CAS, SatView, JIP Marker/Task, par exemple)
  • La gestion de marqueurs de mission dynamiques (et synchronisés en JIP)
  • Helmet Cam - Caméra de casque pour les membres d'un groupe (touche étoile "*")
  • Script jump pour pouvoir sauter au dessus des obstacles
  • CAS Drones - interface simple pour demander un drone sur site
  • HeliLift script pour l'hélitreuillage
  • Traduction automatique de tout ce qui peut/doit être traduit dans la langue du joueur en utilisant les strings magiques "STR_"
  • Les fonctions de création de véhicules et de groupes d'IA
  • Les fonctions de combat des IA (attack, defend, patrol)
  • Outlawled Mag Repack
  • R3F Logistic
  • F.S.F. Sac Ventral
  • Tao Foldmap
  • Système de menu unifié pour toutes les fonctionnalités, inutile de fouiller les menus radio désormais et fini les menus roulette à rallonge!
  • IndeedPete Conversation script pour rendre les interactions avec les IAs plus visuelles
  • Script d'appui d'artillerie
  • Script de réparation pour les joueurs mais aussi de zone de réparation pour les véhicules
  • Script de largage de véhicules/munitions
  • Compatibilité avec un client Headless pour les unités créées à l'aide de la fonction edt_fnc_spawn du framework
  • Compatibilité avec un client Headless pour les scripts appelés à l'aide de la fonction "execHC" du framework
  • Vie civile simplifiée

A ajouter
  • Interface de gestion des groupes (rejoindre / quitter)
  • Vie civile dynamique performante

Mettre à jour vos missions

Avec la version 2.06a de la Base Mission, la mise à jour de vos missions s'est grandement simplifiée.
Du moment que vous ne touchez pas aux scripts inclus à la racine de la Base Mission, ça se limite simplement à copier/coller l'ensemble des fichiers présents dans le ZIP de la Base Mission et à écraser ceux présents dans votre mission SAUF:
  1. Le répertoire "mission\"
  2. Le fichier "mission.sqm"
mettre_a_jour_05.jpg

Résumé des fonctions de tâches et d'objectifs

Pour un tutoriel plus complet, il faut voir la liste des tutoriels dans le message d'introduction du fil.

1) Objectifs et tâches

On peut dans un déclencheur appeler les fonctions suivantes pour créer un objectif et une tâche associée

Code : Tout sélectionner

nul = ["Land_PowLines_Transformer_F","marker0_1","jip_activated1"] execVM "activer.sqf";

["STR_AP_TASK_TITLE","created","STR_AP_TASK_DESC","marker0_1","jip_activated1"] call edt_fnc_taskSilent;
execVM "activer.sqf"
Dans le répertoire de base de la BaseMission on trouve une série de scripts (activer.sqf, detruire.sqf, ramasser.sqf, etc..) qui sont autant d'objectifs qu'on peut accomplir. Tous ces objectifs sont utilisés en démonstration dans la mission test de la BaseMission.
Dans l'exemple ci-dessus, on crée avec une ligne de code, un transformateur qu'on pourra activer et désactiver, sur la position du marqueur "marker0_1", et qui poste son statut dans la variable "jip_activated1" qui est une variable synchronisée entre tous les joueurs, ainsi que ceux qui se connectent en cours de partie (join in progress).
Le nom de la variable, ici "jip_activated1" est totalement libre, il n'est utile que si on teste le contenu de cette variable à l'aide de la fonction "edt_fnc_getVar" (voir point suivant).
Cette variable peut aussi être utilisée pour contrôler le statut d'un objectif (accompli ou non).

edt_fnc_taskSilent
Avec cette ligne de code, on crée une tâche (visible lorsqu'on va sur la carte dans la partie "tasks"). Il existe deux fonctions pour créer une tâche.
edt_fnc_task : Crée ou met à jour une tâche en affichant une notification à l'utilisateur.
edt_fnc_taskSilent : Crée ou met à jour une tâche sans afficher de notification à l'utilisateur.
En début de mission, s'il y a beaucoup d'objectifs (comme dans la mission de test par exemple) pour éviter de spammer l'utilisateur avec des notifications, il est préférable d'utiliser "edt_fnc_TaskSilent". Dans tous les autres cas, on privilégiera la fonction "edt_fnc_task" qui informe l'utilisateur du changement de statut de la tâche.

Remarque importante: Si les textes ont le format "STR_..." et qu'ils existent dans le fichier "mission\stringtable.csv", ils seront traduit automatiquement par le système dans la langue de l'utilisateur qui les voit. C'est valable pour toutes les fonctions faisant partie de la Base Mission.

Dans l'exemple ci-dessus:
Le premier paramètre est le titre de la tâche utilisé dans la liste, attention!!!!!!, ce titre doit être unique, il sert de clé pour identifier la tâche. Deux titres identiques vont simplement s'écraser l'un l'autre.
Le second paramètre est le statut de la tâche. Pour mettre le statut à jour, il suffit d'appeler la méthode avec le même titre, mais un autre statut,
Le troisième paramètre est le contenu de la tâche. Il peut changer d'un appel à l'autre. Si on ne souhaite pas changer le texte, mais juste le statut. Il faut laisser ce champ vide.
exemple:

Code : Tout sélectionner

["STR_AP_TASK_TITLE","succeeded"] call edt_fnc_taskSilent;
Le quatrième paramètre (optionel) est le marqueur de tâche (pour qu'un marqueur soit affiché sur carte). Si ce marqueur a un texte, le texte sera utilisé comme information sur le marqueur de tâche.
Le cinquième paramètre (optionel) est le nom de la variable avec laquelle le marqueur est lié pour la réussite. Si cette variable passe à "true", la tâche passe automatiquement au statut "Réussie".
Dans notre cas, lorsque le transformateur est activé, la tâche est automatiquement réussie.

Avec deux lignes de code, on a crée un couple objectif/tâche, on ne doit plus rien toucher, ça se fait tout seul. Les joueurs qui se connectent en cours de partie sont automatiquement synchronisés.
Tout le monde est heureux et on peut dézinguer dans la joie et la bonne humeur...


2) Déclencheurs et tâches

Pour passer à l'étape suivante d'une mission, on voudra savoir le statut des objectifs. La plupart du temps on les utilisera dans un déclencheur, pour envoyer des renforts, déclencher la fin de la mission, etc.
On doit donc connaître le statut des objectifs. Pour cela on a deux fonctions qui permettent de tester le statut des variables synchronisées en JIP.
Dans la condition des déclencheurs on peut appeler les fonctions suivantes:

Code : Tout sélectionner

1 call edt_fnc_status

["jip_activated1",false] call edt_fnc_getVar
edt_fnc_status
La première fonction permet de tester qu'un script ou un autre déclencheur s'est activé. Ce script ou cet autre déclencheur a utilisé l'une des deux fonctions suivantes:

Code : Tout sélectionner

1 call edt_fnc_completed

1 call edt_fnc_canceled
Pour mettre respectivement l'objectif à "true" ou "false".
La variable qui lie ces fonctions est "tmf_edt_X" (où X est le numéro utilisé dans l'appel de la fonction).
Ces informations sont synchronisées en MP et avec les joueurs se connectant en cours de partie, ce qui assure que chaque PC aura le même statut.
Pourquoi est-ce important? Simplement pour garantir que lorsqu'un joueur arrive en milieu de partie, les objectifs sont dans le même statut pour lui que pour les autres joueurs.

En effet, les déclencheurs (triggers) sont locaux à chaque PC (et au serveur), ils ne se déclenchent donc pas nécessairement en même temps.
Prenons un exemple simple.
Placez un déclencheur de zone, qui crée un tâche lorsque des joueurs arrivent dans la zone. Lancez le serveur, passez dans la zone, la tâche s'ajoute à votre liste des tâches.
Maintenant sortez de la zone, il n'y a donc aucun joueur dans la zone de déclenchement.
Un autre joueur se connecte maintenant à la partie, pour lui, comme pour les autres, le déclencheur est créé localement. Lorsqu'il se connecte, la tâche n'est pas là, parce qu'il n'y a personne dans la zone du déclencheur. Tous les joueurs n'ont donc pas les mêmes objectifs, rien n'est synchronisé... c'est la caca... c'est la cata... c'est la catastrophe.

Important, la variable qui se cache derrière ces fonctions, peut être liée à une tâche!
Par exemple, vous souhaitez qu'une tâche soit accomplie lorsque les joueurs arrivent dans l'usine désaffectée (comme ci-dessus).
Vous créé une tâche avec le code suivant:

Code : Tout sélectionner

["Arrivée à l'usine","created","Vous devez rejoindre l'usine au plus vite!","",1] call edt_fnc_taskSilent;

// Si vous voulez utiliser une chaîne de caractère plutôt qu'un chiffre, vous devez utiliser le nom complet de la variable.
["Arrivée à l'usine","created","Vous devez rejoindre l'usine au plus vite!","","tmf_edt_1"] call edt_fnc_taskSilent;
Cette tâche s'accomplira si la variable "tmf_edt_1" passe à "true".
Dans le déclencheur de zone de l'usine, la partie activation contiendra le code suivant:

Code : Tout sélectionner

1 call edt_fnc_completed
Résultat, lorsqu'un joueur atteint l'usine, la tâche est accomplie. Si un joueur se connecte plus tard, la tâche sera aussi accomplie pour lui.
On a résolu le problème précédent...

edt_fnc_getVar
La deuxième fonction permet de tester qu'un objet de mission (une tour radio a détruire, un objet à ramasser, etc.) a changé de statut.
Lors de la création de l'objet de mission, on peut donner un nom de variable globale (synchronisée entre les tous les clients) qu'on peut ensuite tester dans des déclencheurs pour activer des unités ou des tâches.
Par exemple, on crée l'objectif de mission suivant:

Code : Tout sélectionner

nul = ["Land_PowLines_Transformer_F","marker0_1","jip_activated1"] execVM "activer.sqf";
Et on veut envoyer des renforts aussitôt que l'engin est activé.
Pour cela on crée un déclencheur qu'on va lié au premier waypoint des renforts.
Dans la condition du déclencheur on mettra:

Code : Tout sélectionner

["jip_activated1",false] call edt_fnc_getVar
On pourrait accomplir la même chose avec un objectif numérique en utilisant le code de création suivant:

Code : Tout sélectionner

nul = ["Land_PowLines_Transformer_F","marker0_1","jip_activated1"] execVM "activer.sqf";
Et dans le code d'activation du déclencheur:

Code : Tout sélectionner

1 call edt_fnc_status

3) Fichier mso_uids.sqf
Le tutoriel complet est ici: Configurer les accès aux fonctionnalités
C'est un fichier texte qui permet de donner des droits particuliers à des joueurs pour limiter l'accès à certaines fonctionnalités.
Ce fichier doit se trouver dans un répertoire "mso\" situé:
- Soit dans le répertoire de mission si les droits à appliquer ne sont valables que pour cette mission.
- Soit dans le répertoire de ArmA3 (là où se trouve l'exécutable) si ces droits sont globaux à toutes les missions.
La structure du fichier est la suivante:

Code : Tout sélectionner

[
     ["ID_ARMA3", "GRADE",	["role1","role2",...],"NomDuJoueur"] 	/* Nom du joueur optionnel, utilisé pour des scripts de bannissement pour usurpation d'identité */
    ,["123456789", "SERGEANT",	["admin","pilot","crew"]] 	/* SevenOfNine */
]
On peut ensuite dans différents scripts tester l'accès à des fonctionnalités avec la fonction:

Code : Tout sélectionner

_hasAccess = [(getPlayerUID _unit),["member","admin"]] call mp_rights_fnc_hasRoles;

Mission d'exemple

Attention, l'image ci-dessous ne reflète plus complètement la réalité.
De manière à tester l'ensemble des fonctionnalités, j'ai réparti les objectifs dans 2 vallées adjacentes.

Dans la première vallée (où démarrent les joueurs) j'ai placé les objectifs créés à la volée. C'est à dire par du code.
Typiquement on utilisera cette méthode au cours de la mission pour créer des objectifs au fur et à mesure de l'avancement des joueurs et en fonction de ce qu'ils réussissent ou non.

Dans la deuxième vallée (située au nord nord-ouest) j'ai placé des objets sur carte et j'y ai associé des objectifs par leur code d'initialisation. Ca permet dans la plupart des cas, de simplifier la création de la mission si on place à l'avance tous les éléments.

Pour les scripts, ça ne change rien.
basemission_A3_exemples.jpg

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

Re: BaseMission - ArmA 3

Message par Tyrghen » 02 mai 2013, 22:33

Version 2.09c - en préparation:
  • Nettoyage parmis les modules inclus, suppression de plusieurs d'entre eux devenus obsolètes ou redondants
  • Correction du script d'artillerie qui ne tenait pas en compte le rayon de dispersion
  • ...
Version 2.09b:
  • Correction d'un bug lorsqu'on assigne une tâche à un groupe qui n'existe pas
  • Corrections dans la VAS suite aux mises à jour d'ArmA 3
  • Corrections dans le Mag Repack suite aux mises à jour d'ArmA 3
  • Correction de plusieurs petits bugs dans notre version du BTC Revive
  • Changements dans l'exécution de certains fonctions du framework de mission
  • Changements dans les configurations
  • Modification du script de respawn des véhicules, si un temps n'est pas donné, le véhicule ne respawnera que s'il est détruit
  • Grosse mise à jour du script de kamikaze
  • Plusieurs petites corrections ici et là dans les scripts d'objectifs
Version 2.09a:
  • Correction d'un bug dans la configuration de la VAS
  • Mise à jour de la VAS à la version 2.9
  • Paramètre pour désactiver le thermique et la vision de nuit des véhicules
  • Paramètre pour changer l'heure de début de la mission
  • Correction dans les calculs du placement des unités et des objets dans les bâtiments
  • Ajout d'une fonction edt_fnc_ammobox qui initialise un objet placé dans l'éditeur en tant que caisse de munition, peu importe le système choisi en interne par la mission
  • Correction dans la fonction edt_fnc_destroy qui ne permettait pas de choisir le nombre de charges à utiliser dans le script détruire
  • Ajout de paramètres pour modifier l'équipement des unités présentes sur carte. Placée par l'éditeur ou par les fonctions de la mission
  • Correction d'un bug dans la sauvegarde des munitions lorsqu'on meurre
  • Correction du bug qui faisait qu'on avait le bruit de chute libre de la réapparition
  • Correction d'un bug pour les soins à l'aide d'un medikit
Version 2.09:
  • Correction du script de renforts par véhicules, le conducteur ne voulait plus démarrer
  • Correction de quelques scripts dans les modules externes suite aux changements dans ArmA (entre autre, la VAS)
  • Corrections liées à la v1.40 d'ArmA
  • Ajout d'une fonction pour "protéger les véhicules IA" des dégâts non voulus. Dans l'initialisation: [this] call edt_fnc_protectVehicle
  • Correction dans le script patrouille pour gérer les véhicules placés sur des montagnes
Version 2.08:
  • Correction d'un bug dans le placement des snipers
  • Ajout du script "civils.sqf", pour créer une vie civile de base. Il suffit de placer un groupe de civils et d'appliquer le script au leader comme pour tout autre groupe. Le script fonctionne sur les véhicules aussi. Il est particulièrement léger parce qu'il ne fait appel qu'à des waypoints scriptés et à des événements de base (firedNear/hit).
  • Ajout par défaut du fichier mso_uids.sqf et activation de celui-ci par défaut. Ca ne change rien aux droits d'accès dans l'éditeur, mais une fois la mission lancée, seuls les admins ont accès aux fonctions avancées. Mais toutes les fonctions de base comme l'artillerie sont ouvertes à tous.
  • Compatibilité avec un headless pour les fonctions de type "spawn". Donc toutes unités créées dynamiquement à l'aide de la Base Mission, seront créées sur le Headless, c'est aussi valable pour les fonctions de renfort.
  • Ajout d'une fonction "execHC" qui exécutera le script donné avec ses paramètres, soit sur le serveur, soit sur un HC s'il y en a un de disponible.
  • Plusieurs HC sont supportés, s'il en existe plusieurs, à chaque appel de création d'unité ou d'exécution de script HC, l'un d'eux sera choisi au hasard, ce qui en moyenne devrait répartir la charge. Je ne pense pas ajouter plus de contrôle que ça... simplement parce que c'est vraiment un edge case. Si quelqu'un souhaite plus de contrôle, il n'aura qu'à utiliser les fonctions de plus bas niveau du framework.
  • ATTENTION: la fonction edt_fnc_spawn a changé de signature. Elle ne renvoie plus la liste des unités mais le groupe. De plus, ce groupe ne contiendra des unités que plusieurs secondes après l'exécution si un client Headless est actif.
  • Correction d'un bug dans le script homed.sqf et ajout d'un test dans le placement des unités pour voir si le spot est libre.
  • Correction d'un bug dans la fonction edt_fnc_defend lorsqu'elle utilise les positions définies dans ArmA.
  • Correction du bug dans le menu de modération empêchant de détacher un joueur
  • Ajout de la possibilité de téléporter un joueur vers soi depuis le menu de modération
  • Correction d'un bug dans le VAS qui empêchait de limiter correctement les armes, munitions et objets
  • On peut maintenant utiliser les objectifs numériques à la place des variables JIP dans la plupart des fonctions et scripts
Version 2.07:
  • Ajout de l'affichage des noms par le script de Xeno
  • Ajout du script de la Dom pour accrocher une chemlight sur son épaule
  • Ajout du script de la Dom pour construire des tranchées
  • Quelques changements supplémentaires dans la structure des fichiers de la Base Mission pour pouvoir facilement mettre à jour les missions
  • Ajout de nouveaux scripts comme edt_fnc_stuckGroup, edt_fnc_landChopper, edt_fnc_sniper, edt_fnc_homed, etc.
  • De nombreux correctifs suite aux tests dans les missions
  • Ajout de l'insigne de Team sur les uniformes
  • Ajout de scripts au répertoire de base (pour l'éditeur):
    • sniper.sqf
    • homed.sqf
    • safeVehicle.sqf
  • Ajout d'un système centralisé d'exécution de fonctions, pour éviter des spawns et des whiles à tout va
  • Ajout d'un container IOC qui permet d'enregistrer des événements locaux et des handlers ainsi que des événements distants, pour éviter de définir à la main partout des variables PVEH et le code associé. Le meilleur exemple est le nouveau menu unifié. Lorsqu'on l'ouvre, on exécute en fait tous les handlers enregistrés par les différents modules. Le menu ne sait donc pas lui même ce qu'il va contenir, il sait uniquement comment gérer les réponses des handlers.
  • Pas mal de choses dont je ne me souviens plus :) dont de nombreux petits correctifs ici et là pour des usages spécifiques
Version 2.06a:
  • Ajout des scripts de renforts à pied et par véhicules
  • Quelques retouches dans l'initialisation du Framework pour que ce soit plus cohérent
  • Quelques changements dans la structure des fichiers de la Base Mission
  • Nettoyage du fichier setup.sqf et déplacement de celui-ci dans le répertoire "mission" puisqu'il est spécifique à la mission
  • Ajout d'un fichier description.hpp dans le répertoire mission pour ajouter des éléments au description .ext. Pour faire les mises à jour on ne doit donc plus que garder le fichier mission.sqm et le répertoire mission, tous les autres peuvent être écrasés.
  • Support pour les objectifs numériques dans toutes les fonctions. Inutile désormais de nommer ses objectifs "tmf_edt_1", etc. un simple 1 numérique suffit, mais attention, pas une chaîne de caractère, la valeur numérique. Comme dans la fonction edt_fnc_status
Version 2.06:
  • Ajout du système de menus unifié pour avoir une place centralisée pour tous les scripts
  • Ajout des scripts IndeedPete Conversations. Les interactions avec les IAs peuvent se faire au travers d'une fenêtre de dialogues avec des choix, des conditions scriptées, des paramètres, etc.
  • Intégration et correction du F.S.F. Sac Ventral, pour pouvoir faire ses sauts en parachute avec son sac à dos et tout son barda.
  • Ajout d'une caisse sur les MHQ du BTC Revive
  • Ajout d'un script d'artillerie issu de la Domination pour une bonne partie
  • Ajout d'un script de réparation qui permet à tous les joueurs de réparer à l'aide de toolkit et aussi de placer des zones de réparation sur carte
  • Ajout du script de convoi de Norrin, largement revu et modifié. Mais bon, ça reste ArmA... faut pas trop rêver quand même :)
  • Ajout du Tao Foldmap
  • Ajout d'un script de largage de véhicules/munitions inspiré de celui de la Domination, utilisant le Mando Chute pour guider l'objet vers le sol
Version 2.04b:
  • Correction de plusieurs bugs dans les interfaces depuis la mise à jour de BIS
  • Correction du lancement du Mag Repack qui bloquait l'exécution des scripts côté serveur
Version 2.04a:
  • R3F Logistique
  • Outlawled Mag Repack
  • Upgrade VAS
  • Script de parachutage de renforts
  • Amélioration de plusieurs scripts suite aux différentes missions

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

BaseMission - ArmA 3 - Créer le répertoire de mission

Message par Tyrghen » 05 mai 2013, 20:36

Mise à jour: 14/09/2014

Tutoriel - Créer le répertoire de mission

Le but de ce tutoriel est de créer une mission, vide, mais qui permet d'utiliser toutes les fonctionnalités de la Base Mission (satellite, artillerie, etc.).
Au fur et à mesure des tutoriels, nous rajouterons différentes fonctionnalités pas à pas. A la fin de chaque tutoriel, le répertoire de mission sera disponible au téléchargement.



1) Choisir une île et placer le premier joueur

Ouvrez l'éditeur, sélectionnez votre île (ici je prendrai Stratis) et placez votre joueur.
Vous remarquerez que je donne un nom de variable à mon joueur, c'est une bonne habitude à prendre, ça aide énormément durant la mission pour gérer les joueurs.
mission_start_05.jpg


2) Placer la logique de jeu "Server"

Vous devez ensuite placer une logique de jeu nommée "server". C'est une étape essentielle de la mise en place de la mission. La majorité des scripts sont dépendants de l'existence de cette logique de jeu. C'est grâce à elle qu'une série de fonctionnalités sont synchronisées entre les joueurs.

Placez simplement une nouvelle unité, comme camp sélectionnez "Logique de jeu" à la place de "Blufor".
Ensuite vérifiez que catégorie et unités sont bien "Objets" et "Logique de jeu".

NOMMEZ la logique de jeu: "server"
mission_start_10.jpg


3) Placer l'héliport invisible "JIPH"

Vous devez ensuite placer un héliport invisible nommé "JIPH". C'est une étape essentielle de la mise en place de la mission. La majorité des scripts sont dépendants de l'existence de cet objet pour synchroniser des valeurs entre tous les ordinateurs et pour assurer la persistance des variables. C'est grâce à elle que les données sont synchronisées entre les joueurs.

Placez simplement une nouvelle unité, comme camp sélectionnez "Vide" à la place de "Blufor".
Ensuite vérifiez que catégorie et unités sont bien "Objets (panneaux)" et "Héliport (invisible)".

NOMMEZ l'objet: "JIPH"

Vous pouvez ajouter la ligne de code suivante dans l'initialisation de l'objet:

Code : Tout sélectionner

nul = [] execVM "mission\start.sqf";
Ce n'est pas obligatoire, mais ça vous permet de prendre une bonne habitude :)
Pour initialiser les joueurs et le serveur, plutôt que de tout mettre dans l'initialisation (qui, il faut être honnête, n'est pas très lisible), j'ai pris l'habitude d'avoir un script "start.sqf" qui contient mes initialisations. Un script pré-rempli est donné avec la Base Mission comme on le verra plus tard.
La différence entre "start.sqf" et "init.sqf" c'est que le fichier "start.sqf" n'est exécuté que lorsque les objets de la mission sont instanciés. On peut donc leur ajouter des attributs, etc. ET si vous gardez la structure de base du fichier fourni, vous êtes CERTAIN que le framework est initialisé.
mission_start_15.jpg


4) Sauvegarder la mission

Vous pouvez maintenant simplement contrôler que tout est en place. Vous devriez avoir 3 objets comme ci-dessous.
mission_start_20.jpg
Vous pouvez ensuite sauver la mission et lui donner un nom. Ici j'ai choisi "[V]Exemple".
mission_start_25.jpg
REMARQUE:
Si vous avez oublié un élément dans la mission, pas de problème!
Vous recevrez un message vous signalant qu'il manque quelque chose.
mission_start_27.jpg


5) Copier les fichiers de la Base Mission

ATTENTION! Copiez tous les fichiers SAUF le mission.sqm, c'est le seul fichier que vous ne pouvez JAMAIS écraser!
mission_start_30.jpg


6) Lancer la mission

Tout d'abord, il faut recharger la mission, dans l'éditeur, sélectionnez "Charger" et chargez à nouveau la mission que vous êtes en train d'éditer. La raison pour laquelle vous devez recharger la mission c'est qu'une série d'éléments ne sont mis à jour que lorsque vous chargez la mission.
Une liste nos exhaustive:
  • Les traductions
  • Les interfaces des menus
  • Les fonctions disponibles (CfgFunctions)
Une fois la mission lancée, vous devriez voir le message de lancement de la mission à droite et après quelques secondes (le temps que la Base Mission s'initialise) vous devriez pouvoir ouvrir le menu du joueur (touche "U").
mission_start_35.jpg


7) Remarque importante

Notez qu'à partir d'ici, la plupart des fonctions de la Base Mission sont maintenant disponibles au travers de l'éditeur et il n'est pas nécessaire d'utiliser les scripts et les fichiers qui sont détaillés plus loin.
Il n'y a donc pas besoin de compétences en programmation pour utiliser la Base Mission!

Evidemment, toutes les fonctionnalités (comme les conversations) ne peuvent pas être utilisées simplement dans l'éditeur.
Ici je ne vais couvrir que les fichiers inclus dans la Base Mission que vous pouvez éditer pour ajouter votre propre code.



8) Les fichiers spécifiques à la mission

Lorsque vous éditerez votre mission, je vous encourage VRAIMENT à placer tous vos fichiers spécifiques à cette mission dans le répertoire "Mission" de la Base Mission.
Pourquoi?
Simplement parce que ça vous simplifiera la vie pour les mises à jour. Pour mettre à jour votre mission à la dernière version de la Base Mission, il faudra simplement copier tous les fichiers de la Base Mission sauf: le répertoire mission, le mission.sqm et le description.ext (si vous l'avez modifié, ce qui à priori ne devrait que rarement être nécessaire).

Contenu de base
Le contenu du répertoire "Mission" lorsque vous le copiez depuis le Base Mission contient les fichiers suivants:
  • functions: Ce répertoire n'est pas indispensable si vous n'utilisez pas de fonctions spécifiques à la mission, mais je le garderais, simplement par facilité. Il contient des bases de fonctions qui vous permettront d'ajouter très simplement des fonctionnalités à votre mission.
  • cfgFunctions.hpp: Ce fichier EST indispensable! Il est référencé dans le description.ext et permet d'intégrer des fonctions de vos missions au fichier description.ext sans devoir y toucher. Ce qui simplifie les mises à jour plus tard.
  • conversations.hpp: Ce fichier n'est pas indispensable, mais je le garderais simplement pour pouvoir créer des conversations. Laissez le tel quel si vous ne l'utilisez pas. Si vous voulez le supprimer, il faudra retirer le lien vers ce fichier qui se trouve dans "description.hpp" (celui ci-dessous)
  • description.hpp: Ce fichier EST indispensable! Il sert à ajouter une image, des fenêtres, des conversations ou d'autres choses propres à votre missions sans devoir éditer le "description.ext".
  • init.sqf: Ce fichier EST indispensable! Placez dans ce script les initialisations des scripts que vous ajoutez dans votre mission, n'éditez pas le "init.sqf" qui se trouve à la racine du répertoire de mission.
  • setup.sqf: Ce fichier EST indispensable! Ce fichier contient des variables pour configurer le fonctionnement de la mission. Son contenu va évoluer dans les prochaines versions de la Base Mission pour reprendre plus de variables possibles avec plus d'explications.
  • start.sqf: C'est le fichier que vous avez peut-être ajouté à l'initialisation du JIPH. Dans ce fichier je met les initialisations du joueur et du serveur. Par exemple, si dans ma mission j'ai besoin d'une série de fonctions sur le serveur uniquement, je les placerai ici.
    Pourquoi utiliser ce fichier à la place du init.sqf? Simplement parce que ce fichier ne sera appelé que lorsque les objets de la mission sont instanciés. Dans le cas du init.sqf, il est possible que la mission ne soit pas encore entièrement initialisée.
  • stringtable.csv: Ce fichier EST indispensable! Le fichier qui contient toutes les traductions de la mission. Pour que tout fonctionne correctement, préfixez TOUJOURS vos traductions par "STR_", de cette manière le framework fera les traductions pour vous sans avoir à le spécifier.
  • tmf_constants.h: Un fichier contenant les constantes définies pour le framework. Ne pas y toucher...
  • tmf_macros.h: Un fichier contenant les macros utilisées par le framework. Il ne faut pas l'éditer, mais vous êtes encouragés à les utiliser.
mission_start_40.jpg
version 2.07


9) Contenu des scripts de base

Nous allons maintenant parcourir les fichiers SQF de base que vous pouvez utiliser pour démarrer votre mission.


init.sqf
Ici vous placerez tout le code et les scripts à lancer à l'initialisation de la mission.
Ce code est exécuté en parallèle de l'initialisation normale de la mission.
J'ai choisi de le mettre en parallèle, pour qu'une erreur dans cette initialisation spécifique à la mission ne bloque pas l'initialisation du Framework de mission.
mission_start_45.jpg

start.sqf
Tout le code contenu dans ce fichier pourrait être inclus dans init.sqf, mais, je trouve qu'il est beaucoup plus clair de séparer les deux, pourquoi?
Parce que le fichier start.sqf ne se lancera qu'une fois l'ensemble du Framework de mission initialisé. Du coup on peut être sûr que toutes les fonctionnalités sont disponibles pour le code inclus ici.
Et on est aussi certain que le joueur a fini d'être initialisé. On pourra dès lors lui assigner un nouvel équipement, etc.
mission_start_50.jpg

setup.sqf
Ce fichier contient quelques unes des variables qu'on peut modifier pour modifier le comportement de la mission, mais il y en a beaucoup d'autres.
Par exemple, la plupart des fonctionnalités du BTC Revive peuvent être configurées par variables.
C'est ici qu'on fera les modifications nécessaires.
mission_start_55.jpg


Conclusion

Vous avez maintenant créé en quelques étapes très simple une mission qui possède les fonctionnalités de notre Base Mission. Pour pouvoir ajouter des fonctionnalités comme les points de respawn, les MHQs, etc. vous pouvez suivre les autres tutoriels qui viendront.

Bonne édition et bon jeu!
Pièces jointes
[V]Exemple.Stratis.zip
Version 2.07
(1.79 Mio) Téléchargé 535 fois

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

BaseMission - ArmA 3 - Utiliser le BTC Revive

Message par Tyrghen » 08 mai 2013, 11:10

Mise à jour: 14/09/2014

Tutoriel - Utiliser le BTC Revive

Dans ce tutoriel nous allons voir comment ajouter les objets nécessaires à l'utilisation du BTC Revive dans la mission.
Notre version du BTC Revive possède une série de changements par rapport à la version de base.
D'un point de vue édition, notre revive est composé de fonctions et non plus de grands fichiers plats.
D'un point de vue fonctionnel, de nombreux ajouts et retouches ont été faits au travers du code pour avoir un fonctionnement plus stable et plus cohérent avec ce que nous avons sur la Domination.


1) Ajouter le point de réapparition de base

Pour que les joueurs réapparaissent à un endroit précis s'ils choisissent de réapparaître (par exemple parce que tout le monde est mort), il faut placer un marqueur nommé "Respawn_[camp]". Si vous ne le faites pas, les joueurs réapparaissent en position [0,0,0] sur la carte.

Un autre avantage d'avoir ce marqueur, c'est que vous pouvez le déplacer au fur et à mesure de la partie pour changer l'endroit où réapparaissent les joueurs. Pour cela il suffit d'appeler dans un déclencheur une ligne de code du type:

Code : Tout sélectionner

"respawn_west" setMarkerPos (getPos outpost);
Les noms pour chaque camp:
respawn_west
respawn_east
respawn_guerrila
respawn_civilian
btc_revive_05.jpg


2) Ajouter des points de réapparition alternatifs

Vous pouvez souhaiter plusieurs points de réapparition différents pour votre partie, chacun apparaîtra dans l'interface de réapparition. Vous pouvez les placer en début de partie ou les créer à la volée.
Pour que ces points de réapparition fonctionne, il faut donner un nom précis aux marqueurs.
Ce nom doit être sous la forme:
  • respawn_[index] dans le cas où le point est disponible pour TOUS les camps
  • respawn_[camp]_[index] dans le cas où le point ne doit être disponible que pour un camp
Index est un nombre compris entre 0 et 49 inclus.
Camp est une des quatre possibilités suivantes: west, east, guer, civ

Par exemple:
Respawn_0, Respawn_1..
Respawn_west_0, Respawn_east_2,...

Points importants:
  • Le texte du marqueur donne le nom qu'aura le point de réapparition dans l'interface de Respawn.
    Ce nom sera traduit si une traduction existe.
  • La numérotation ne doit pas se suivre, vous pouvez avoir des trous dans la numérotation :)
  • La numérotation est indépendante dans chaque type de marqueur (respawn_, respawn_west_, respawn_east_, ..)
  • Ces points de réapparition ne sont visibles dans la liste qu'en cas de décès!!! Si vous voulez ajouter des points de téléportations... ça se passe plus bas.
btc_revive_10.jpg


3) Ajouter un respawn mobile

Dans certains missions on souhaitera pouvoir déplacer le point de réapparition. Pour ça, rien de plus simple, il suffit d'identifier un véhicule comme étant un respawn mobile.
Vous avez pour ça deux solutions possibles.

En donnant un nom spécifique au véhicule:
Vous placez le véhicule dans l'éditeur et lui donnez un nom de la forme:
BTC_Mobile_[camp]_[index]

Index est un nombre compris entre 0 et 49 inclus.
Camp est une des quatre possibilités suivantes: west, east, guer, civ

Par exemple:
BTC_Mobile_west_0, BTC_Mobile_west_1
BTC_Mobile_east_0,...
btc_revive_20.jpg

Via une variable définie dans le Setup.SQF:
Cette autre solution consiste à assigner à une variable définie dans le fichier setup.sqf un tableau contenant les noms des variables des véhicules dans l'éditeur.
Admettons que le véhicule doit avoir un nom précis pour qu'il fonctionne avec un autre script que vous avez ajouté, vous pouvez simplement signaler ce véhicule comme étant un respawn mobile en assignant la variable correspondante à votre camp.
BTC_vehs_mobile_west
BTC_vehs_mobile_east
BTC_vehs_mobile_guer
BTC_vehs_mobile_civ

Par exemple:

Code : Tout sélectionner

BTC_vehs_mobile_west = [mon_vec_1,mon_vec_2];


4) Ajouter un point de téléportation
Avoir des points de réapparition c'est bien, mais que se passe-t-il lorsqu'un joueur se connecte en cours de partie?
Pour qu'il puisse rejoindre facilement le groupe, vous pouvez placer un objet sur la carte à proximité du point d'apparition des joueurs qui permet de se téléporter vers les cibles possibles, à savoir:
  • Le leader de son groupe
  • Les respawn mobiles
Pour que l'objet placé dans l'éditeur devienne un point de téléportation, il faut lui donner un nom particulier.
Ce nom sera sous la forme:
BTC_objects_actions_[camp]_[index]

Par exemple:
BTC_objects_actions_west_0, BTC_objects_actions_west_1,...
btc_revive_15.jpg


5) Le résultat dans le jeu

On place sur carte un respawn_west, un respawn_0 qui a comme texte "Les hangars", un respawn mobile et un point de téléportation.
btc_revive_25.jpg
Lorsqu'on approche du Drapeau qui est notre point de téléportation, on a une invite qui nous permet de choisir une destination.
btc_revive_30.jpg
Dans notre cas, on peut se téléporter vers le leader du groupe, le point "respawn_west" qui est toujours considéré comme le point de téléportation et respawn de base et enfin, les respawn mobiles. Ici nous n'en avons qu'un seul.
Notez qu'ici le respawn mobile s'appelle "MHQ 1" parce que dans le fichier stringtable.csv on a défini une entrée pour le nom de variable du véhicule.
btc_revive_35.jpg
Par contre, lorsqu'on meurt, les points de respawn alternatifs sont ajoutés à la liste et sont utilisables comme destination pour le respawn.
Vous remarquerez en même temps que le texte du marqueur sert à le nommer dans la liste.
btc_revive_40.jpg
btc_revive_40.jpg (78.58 Kio) Consulté 50754 fois


Conclusion
Pour une mission classique vous n'aurez besoin que de 2 éléments:
  • Le marqueur de respawn de base ("respawn_west" pour les blufor)
  • Un objet pour permettre à ceux qui rejoignent en route de se téléporter (nommé "BTC_objects_actions_west_0" pour les blufor)
Pièces jointes
[V]Exemple.Stratis.zip
Version 2.07
(1.79 Mio) Téléchargé 549 fois

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

BaseMission - ArmA 3 - Ajouter des objets et des caisses

Message par Tyrghen » 17 mai 2013, 15:49

Mise à jour: 14/09/2014

Tutoriel - Ajouter un objet ou une caisse d'équipement

Dans ce tutoriel nous allons voir comment ajouter des objets statiques non disponibles dans l'éditeur, comme par exemple, les bunkers en métal.
Nous allons aussi ajouter des caisses d'équipement sur la carte.



1) Ajouter un objet statique
Tous les objets ne peuvent pas se placer par l'éditeur.
Prenons par exemple le grand radar de Mike-26 sur Stratis ou tout simplement un de ces petits bunker métallique.
De manière à contourner cette limitation et ne pas devoir toujours éditer le fichier mission.sqm pour modifier le type de l'objet, vous pouvez simplement placer des marqueurs nommés:
building_[index]

ATTENTION, le code a changé, j'ai mis un séparateur entre le "building" et l'index.
Pourquoi?
Parce que ça simplifie le placement des marqueurs, il suffit de créer un marqueur nommé "building" quelque part sur carte et en faisant du copier/coller (CTRL+C / CTRL + V) ArmA va automatiquement créer la numérotation building_1, building_2, etc.

Le texte du marqueur sera le type de l'objet à créer. La direction du marqueur sera la direction de l'objet.
A noter que ça ne fonctionne pas à la volée, mais uniquement lors de l'initialisation de la carte par le serveur.

En pratique

Placez un premier marqueur "building".
statique_05.jpg
Ensuite faites du copier/coller pour créer un premier marqueur "building_1" le "_1" s'ajoute automatiquement dans l'éditeur. Profitez-en..
Tapez le nom de la classe du bâtiment dans le texte du marqueur.
Vous pouvez utiliser le Six Config Browser pour rechercher ces classes. Ou alors le navigateur de configuration intégré à ArmA.
statique_10.jpg
Allez, hop, un deuxième pour le plaisir :)
statique_15.jpg
Et le résultat en image!
statique_20.jpg


2) Ajouter des caisses d'équipement
Pour placer une caisse d'équipement sur carte, rien de plus simple, il suffit de placer un marqueur avec un nom spécifique.
Le nom doit avoir la forme:
box_[index]

On peut placer le marqueur à la volée, une caisse sera créée à cet endroit.
En peut aussi effacer le marqueur et la caisse sera supprimée.

Pour ajouter un marqueur de caisse sans se casser la tête, vous pouvez utiliser la fonction edt_fnc_boxMarker.
Quelques exemples de code à appeler dans un déclencheur par exemple:

Code : Tout sélectionner

BOX_Usine = [getPos hangar] call edt_fnc_boxMarker;
BOX_Camp = [getPos HQ] call edt_fnc_boxMarker;
Attention! Ce code ne s'exécute QUE sur le serveur, si vous voulez récupérer le contenu de la variable BOX_Usine, vous devrez faire un "publicVariable" pour le poster vers les clients.
Ou... si vous voulez quelque chose de complet et de synchronisé automatiquement, la condition de votre déclencheur sera:

Code : Tout sélectionner

if (isServer) then {
   box = [getPos hangar] call edt_fnc_boxMarker;
   ["box_usine",box] call edt_fnc_setVar;
};
Ce qui vous permet de récupérer le nom de la box chez les clients sous la forme:

Code : Tout sélectionner

box = ["box_usine",""] call edt_fnc_getVar;
Une dernière note, vous pouvez donner comme paramètre à la fonction edt_fnc_boxMarker un autre marqueur. La caisse sera créé sur ce marqueur. Si vous souhaitez placer la caisse sur une position en hauteur, donnez comme texte au marqueur une position ATL précise en plus des autres paramètres. Le format est celui d'un tableau en SQF:
["camp", "type", [], [positionATL]]

Par exemple:

Code : Tout sélectionner

["west", "B_supplyCrate_F", [], [1234, 3245, 12]]
En pratique

Placez un marqueur nommé "box_1" sur la carte.
statique_25.jpg
Ou bien utilisez une ligne de script dans un déclencheur ou autre en utilisant la fonction edt_fnc_boxMarker qui va ajouter un marqueur de caisse automatiquement et qui renvoie son nom si vous voulez l'effacer par après.
Vous pouvez utiliser cette fonction de 3 façons:
  • En donnant un autre marqueur comme paramètre: ["other_marker"] call edt_fnc_boxMarker;
  • En donnant un objet ou trigger comme paramètre: [trigger_blufor] call edt_fnc_boxMarker;
  • En donnant des coordonnées comme paramètre: [12345,25369,0] call edt_fnc_boxMarker;
statique_30.jpg
Sur la carte on a donc:
statique_35.jpg
Ce qui nous donnera en jeu une caisse qui est là dès le début de la partie et une caisse qui apparaît lorsque les joueurs entrent dans la zone du déclencheur.
statique_40.jpg
Pièces jointes
[V]Exemple.Stratis.zip
Version 2.07
(1.79 Mio) Téléchargé 591 fois

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

BaseMission - ArmA 3 - Gestion des tâches et leurs variables

Message par Tyrghen » 20 mai 2013, 20:58

Mise à jour: 17/04/2014

Tutoriel - Gestion des tâches et leurs variables

Le but de ce tutoriel est de créer des tâches et de les mettre à jour, sans devoir appeler toutes les fonctions que les tâches demandent généralement.
Pourquoi utiliser la Base Mission pour ça?:
  • Les fonctions de gestion des tâches de la Base Mission permettent d'afficher un message lorsqu'elles changent de statut.
  • Le statut des tâches est synchronisé automatiquement entre tous les joueurs, même ceux qui se connectent plus tard.
  • Les tâches peuvent être assignées à tous, à un camp ou à un groupe de joueurs.
Exemple concret
Pour ne pas gonfler ce message qui est déjà assez gros...
J'ai créé un message à part avec un exemple concret de A à Z de la création et mise à jour d'une tâche par les variables synchronisées.
L'exemple se trouve ici: Création et mise à jour d'une tâche



1) Création d'une tâche
Deux fonctions sont disponibles pour créer ou mettre à jour une tâche:
  • edt_fnc_task
  • edt_fnc_taskSilent
La seule différence étant que la deuxième fonction n'affiche pas de message à l'écran lorsque la tâche est mise à jour.

Lorsque vous créez une tâche, vous pouvez la créer en utilisant des textes qui peuvent être traduits ou pas.
Vous pouvez pour le titre utiliser un texte en français ou passer par une chaîne magique qui est définie dans le "stringtable.csv" de votre répertoire \mission.
Si la chaîne commence par STR_ elle sera automagiquement traduite dans la langue de l'utilisateur. Même s'il se connecte plus tard.

Les deux façons de faire sont illustrées ci-dessous:

Code : Tout sélectionner

// Un tâche créée en français, qui ne sera disponible qu'en français.
["Le titre de ma tâche","created","Le contenu de la description de ma tâche"] call edt_fnc_task;
// Une tâche multilingue, pour peu qu'on la traduise :)
["STR_TITRE_TACHE","created","STR_DESC_TACHE"] call edt_fnc_taskSilent;
Dans votre fichier "mission\stringtable.csv" il faut ajouter:

Code : Tout sélectionner

// Code, English, Deutsch, Français, Italiano
STR_TITRE_TACHE,"My task title","My task title","Le titre de ma tâche","Le titre de ma tâche"
STR_DESC_TACHE,"The content of my task description","The content of my task description","Le contenu de la description de ma tâche","Le contenu de la description de ma tâche"
Exemple d'une tâche créée dans un déclencheur:
taches_05.jpg


2) Mise à jour d'une tâche
Pour mettre à jour une tâche rien de plus simple, vous appelez exactement la même fonction!
Seuls les deux premiers paramètre, le titre de la tâche et le statut de la tâche, sont nécessaires pour faire une mise à jour. Les paramètres qui ne sont pas donnés sont simplement ignorés.

Code : Tout sélectionner

// Tâche réussie
["Le titre de ma tâche","succeeded"] call edt_fnc_task;
// Tâche échouée
["STR_TITRE_TACHE","failed"] call edt_fnc_taskSilent;

3) Marqueur de tâche
Pour simplifier le déroulement de la mission, il peut être intéressant de pointer l'endroit concerné par la tâche. Pour cela vous pouvez fournir un marqueur de tâche qui sera visualisé sur carte avec le statut de la tâche à laquelle il est lié.
Pour cela, rien de plus simple, ajoutez le paramètre additionnel dans l'appel à la fonction edt_fnc_task/edt_fnc_taskSilent.

Code : Tout sélectionner

["Le titre de ma tâche","created","Le contenu de la description de ma tâche","marqueur_tache"] call edt_fnc_task;
["STR_TITRE_TACHE","created","STR_DESC_TACHE","marqueur_tache"] call edt_fnc_taskSilent;

4) Variables de statut
Personnellement, je n'aime pas me soucier de la mise à jour des tâches. J'aime bien pouvoir créer une tâche et savoir qu'elle se mettra à jour au bon statut lorsqu'un événement se produira.
Pour cela, on peut associer une ou plusieurs variables à une tâche:
  • Une variable de succès: lorsqu'elle passe à "true", la tâche est marquée comme réussie
  • Une variable d'échec: lorsqu'elle variable passe à "true", la tâche est marquée comme échouée
  • Une variable d'échec inversée: lorsqu'elle variable passe à "false" la tâche est marquée comme échouée
Personnellement je n'ai jamais eu besoin de plus. Et si le cas devait se présenter, je ferais la mise à jour moi-même.

ATTENTION: Quand je parle de variable ici, je ne parle PAS d'une variable d'ArmA, mais bien d'une variable synchronisée en JIP. Ces variables sont gérées par les fonctions: edt_fnc_setVar et edt_fnc_getVar.

Exemple d'utilisation:

Code : Tout sélectionner

["Le titre de ma tâche","created","Le contenu de la description de ma tâche","marqueur_tache","jip_var_success"] call edt_fnc_task;
["STR_TITRE_TACHE","created","STR_DESC_TACHE","marqueur_tache","jip_var_success","jip_var_fail"] call edt_fnc_taskSilent;

Pourquoi s'emmerder avec tout ça?
Si vous ne vous êtes pas encore posé la question... eh bien c'est le moment :)
Pourquoi s'embêter avec ces fonctions, à créer tout ça dans la Base Mission, à synchroniser des variables et tout le bazar??

Prenons un exemple simple avec deux tâches:
- atteindre la zone de largage pour récupérer le matériel de destruction.
- se rendre sur la zone des hangars pour faire sauter le chargement de munitions

Torix et Julien se connectent sur la mission, Tyrghen est à la bourre comme toujours...
Les deux compères commencent donc la mission, Tyrghen n'aura qu'à rejoindre plus tard.

1) Ajout de la tâche "récupération"
Ils arrivent sur la base, Un déclencheur qui détecte la présence des joueurs s'active, la tâche "récupération du matériel" est ajoutée. Jusque là, pas de souci.

2) Mise à jour de la tâche "récuparation"
Arrivés sur le point de largage, ils attendent la caisse, qui est larguée par un avion allié. Parfait!
Un déclencheur détecte la présence des joueurs sur place et la disparition de la caisse. La tâche est mise à jour.

3) Ajout de la tâche "destruction"
Maintenant que les joueurs ont la caisse, ils peuvent détruire le hangar cible. On ajoute donc cette tâche aux joueurs dans le même déclencheur que celui où ils récupèrent la caisse. Sinon comment savoir qu'ils ont la caisse?

4) Et Tyrghen débarque
Les deux compères sont en route et c'est le moment choisi par Tyrghen pour débarquer... il était temps.. la moitié de la mission est déjà passée ;)
Il arrive sur base, passe dans le premier déclencheur, la tâche "Récupération" est ajoutée.... mais... elle est déjà exécutée, mais il ne le sait pas.
Pourquoi? parce qu'il n'y a plus personne dans l'autre zone et donc le déclencheur (qui est local au PC de Tyrghen) ne sait pas que la caisse est récupérée. En fait il serait impossible d'accomplir cette tâche pour Tyrghen, puisque le largage a déjà eu lieu et la caisse est déjà récupérée.
Autre problème... vu que le déclencheur de la récupération ne s'exécutera JAMAIS sur le PC de Tyrghen, il n'aura jamais la tâche "Destruction du Hangar".

Avec le code de la Base Mission, qu'il passe par la première ou la deuxième zone de détection n'a aucune importance, Tyrghen recevra automatiquement toutes les tâches en cours avec leur statut actuel. Qu'il y en ait 2, 5 ou 10...

ATTENTION! Je ne dis pas que le problème décrit ci-dessus ne peut pas être solutionné autrement. Je dis simplement que l'utilisation des fonctions rend tout ça plus simple. Le créateur de mission n'a plus à se soucier de savoir si sa tâche est bien ajoutée à un joueur qui se connecte par après, il ne doit pas non plus se soucier du statut que cette tâche aura.

Pensez aussi au fait que ce que j'ai décrit ci-dessus est un scénario très simple. Dans des cas plus compliqués, ça devient encore plus difficile de garder ses tâches à jour et de s'assurer que chaque joueur aura bien la bonne info.

Certains penseront, "ahhh moi ça ne me concerne pas, tous mes joueurs sont connectés dès le début de la mission, personne ne rejoint en cours de route". Ah bon? Et si un joueur perd sa connexion? Il se reconnectera, en cours de route, mais tous les déclencheurs sont donc réinitialisés pour lui.

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

BaseMission - ArmA 3 - Déclencheurs et variables synchronisé

Message par Tyrghen » 09 juil. 2013, 22:25

Mise à jour: 15/04/2014

Tutoriel - Déclencheurs et variables synchronisées

Le but de ce tutoriel est de créer des déclencheurs pour les scripts, les tâches et les événements de vos missions qui soient fiables et synchronisés entre TOUS les joueurs, qu'ils se connectent en début de mission ou pas.

Exemple concret
Pour ne pas gonfler ce message qui est déjà assez gros...
J'ai créé un message à part avec un exemple concret de A à Z de la création et mise à jour d'une tâche par les variables synchronisées.
L'exemple se trouve ici: Création et mise à jour d'une tâche



1) Cas pratique

Une fois n'est pas coutume, commençons par un exemple de mission.
Je reviendrai sur le contenu des nouvelles fonctions par après, mais je voudrais simplement illustrer la différence de code.
  1. Les joueurs reçoivent une tâche en arrivant sur le jeu, ils doivent monter dans des véhicules et se rendre à l'usine près de Kore
  2. Lorsqu'ils arrivent à l'usine, une nouvelle tâche est ajoutée, ils doivent rencontrer la résistance et prendre des munitions
  3. Là ils reçoivent une nouvelle tâche pour aller déposer ces caisses dans une cache de la résistance à Zaros
Si vous avez déjà lu le tutoriel sur les tâches vous voyez directement où je souhaite en arriver...

IMPORTANT! Je prends l'exemple des tâches ici, pas pour parler des tâches, vous pouvez utiliser les modules de BIS si vous voulez pour ça (ce module n'existait pas quand j'ai écris la Base Mission), mais pour parler de la synchronisation d'informations.

Bon, faut dire que le module de BIS pour les tâches c'est carrément de la merde en MP... mais chacun ses goûts.
C'est déjà bien qu'ils aient prévu quelque chose pour ceux qui ne programment pas. C'est juste dommage que ce soit si mal écrit.

Le premier point

Si vous n'utilisez pas la Base Mission, comment allez vous faire? Simplement avec createSimpleTask, dans un script ou dans un déclencheur. Mais si le groupe de joueur est déjà passé par l'usine, le joueur qui vient d'arriver ne le sait pas, il n'y a rien pour lui dire que l'objectif est déjà accompli.
De manière à contourner ce problème, vous devez:
  • Ajouter une variable sur un objet de la carte avec setVariable
  • Dans le déclencheur qui ajoute la tâche, il faut contrôler que cette variable existe avec getVariable
  • En fonction de ce test, il faut créer la tâche et la mettre comme réussie ou créée
En code ça donne..
Dans votre déclencheur à la base:

Code : Tout sélectionner

MA_TACHE_1 = player createSimpleTask [localize "STR_tache_usine"];
MA_TACHE_1 setSimpleTaskDescription [localize "STR_tache_usine_description", localize "STR_tache_usine", localize "STR_tache_usine_waypoint"];
if (objet_synchro getVariable ["tache_usine_reussie",false]) then {
    MA_TACHE_1 setTaskState "Succeeded";
};
Dans votre déclencheur qui détecte l'arrivée à l'usine:

Code : Tout sélectionner

MA_TACHE_1 setTaskState "Succeeded";
objet_synchro setVariable ["tache_usine_reussie",true,true];
Allez, un problème de résolu...

Avec la BaseMission, il suffit d'appeler la fonction de création des tâches et la tâche sera automatiquement synchronisée avec le joueur qui arrive, inutile de contrôler quoi que ce soit...
Dans votre déclencheur à la base:

Code : Tout sélectionner

["STR_tache_usine","created","STR_tache_usine_description","",1] call edt_fnc_task;
Dans votre déclencheur à l'usine:

Code : Tout sélectionner

1 call edt_fnc_completed;

Le deuxième point

Idem ici, on a un déclencheur qui détecte la présence des Blufor et qui va créer la tâche.
Même problème que ci-dessus, le joueur qui se connecte plus tard ne passera JAMAIS par l'usine, puisque tout le reste de l'action est tout à fait ailleurs. Donc il n'aura jamais la tâche.
Comment le résoudre?
La ça devient plus compliqué.
  • Dans votre déclencheur, il faut modifier la condition pour qu'elle vérifie la présence des blufor OU le fait que la tache est ajoutée, comme ça quelqu'un qui se connecte plus tard, aura la tâche parce que la variable d'ajout est vraie
  • Ensuite, dans votre déclencheur, il faut mettre une variable sur un objet (avec setVariable) pour indiquer que cette tâche a été ajoutée.
  • Il faut ensuite créer la tâche.
  • Il faut alors contrôler que la tâche est déjà réussie ou pas, en contrôlant encore une autre variable avec getVariable.
En code:

La condition de votre déclencheur qui détecte les blufor:

Code : Tout sélectionner

this || (objet_synchro getVariable ["tache_munitions_reussie",false])
Dans l'activation du déclencheur:

Code : Tout sélectionner

MA_TACHE_2 = player createSimpleTask [localize "STR_tache_munitions"];
MA_TACHE_2 setSimpleTaskDescription [localize "STR_tache_munitions_description", localize "STR_tache_munitions", localize "STR_tache_munitions_waypoint"];
if (objet_synchro getVariable ["tache_munitions_reussie",false]) then {
    MA_TACHE_2 setTaskState "Succeeded";
};
Dans votre déclencheur qui détecte que la caisse de munitions a disparu:

Code : Tout sélectionner

MA_TACHE_2 setTaskState "Succeeded";
objet_synchro setVariable ["tache_munitions_reussie",true,true];
Et un autre problème de résolu...

Avec la BaseMission, ben vos tâches sont synchronisées, inutile de passer par le déclencheur pour recevoir la tâche, c'est la Base Mission qui vous la donne lorsque vous vous connectez.
Donc rien à écrire en plus que la mise à jour de la tâche!
Dans votre déclencheur à l'usine:

Code : Tout sélectionner

["STR_tache_munitions","created","STR_tache_munitions_description","",2] call edt_fnc_task;
Dans votre déclencheur qui détecte la disparition de la caisse:

Code : Tout sélectionner

2 call edt_fnc_completed;
La tâche, puisque créée avec edt_fnc_task sera synchronisée automatiquement avec le joueur qui se connecte! Qu'il passe par le déclencheur ou pas!

On voit directement que c'est nettement plus simple avec les commandes de la Base Mission...
Vous pouvez le faire dans l'éditeur, mais sérieusement, tous les modules et autres que vous devez relier par des synchronisations et tout ça, moi ça me saoule.. en même temps, je suis un programmeur :)

Pourquoi est-ce plus simple et qu'est-ce que "edt_fnc_completed"?
On en parle dans les points suivants....



2) Les variables synchronisées

Un des boulots de la Base Mission c'est de synchroniser tout ce qui se passe entre les joueurs et être sûr qu'un joueur qui se connecte en cours de jeu a bien les mêmes informations que les autres.
Pour cela, le serveur stocke les informations importantes et les envoie au joueur qui se connecte.

Pour pouvoir synchroniser le fonctionnement des déclencheurs (qui rappelons le encore sont LOCAUX au PC sur lequel ils sont exécutés et donc NE SONT PAS SYNCHRONISÉS, on va utiliser des variables synchronisées. Du coup quand on place un déclencheur, on sait qu'il s'exécutera s'il doit s'exécuter.

Pour synchroniser des variables on a 5 fonctions:
  • edt_fnc_getVar : lit la valeur d'une variable synchronisée
  • edt_fnc_setVar : assigne la valeur d'une variable synchronisée
  • edt_fnc_status : donne l'état d'un objectif (c'est en fait un alias de edt_fnc_getVar)
  • edt_fnc_completed : assigne l'état 'true' à un objectif (c'est un alias de edt_fnc_setVar)
  • edt_fnc_canceled : assigne l'état 'false' à un objectif (idem que ci-dessus)
Le principe dans la Base Mission, c'est qu'on stocke des variables, qui sont représentées par un nom.
Par exemple: "tache_usine_réussie".
Et tout client qui se connecte, recevra le contenu de la variable et pourra le lire.

C'est de cette manière qu'on synchronise les tâches, le déclenchement ou non des déclencheurs. Les scripts qui tournent sur les objectifs (assassiner, détruire, ramasser, etc.).
Et pour moi c'est la manière la plus simple de m'assurer que tous les joueurs ont la même information et que la mission se comportera de la même manière pour tous.



3) Comment utiliser les variables synchronisées

Rien de plus simple, la plupart des scripts et fonctions acceptent ces variables pour soit, donner leur état, soit pour récupérer une information.
Prenons la fonction edt_fnc_task comme exemple. On l'utilise de la manière suivante:

Code : Tout sélectionner

["STR_TASK_DESTROY_TITLE", "created", "STR_TASK_DESTROY_DESC","marker_task_destroy","jip_var_destroyed","jip_var_failed"] call edt_fnc_task;
Les paramètres dans l'ordre sont:
  1. Le titre de la tâche, ici une chaîne magique automatiquement traduite
  2. Le statut initial de la tâche
  3. La description de la tâche, ici encore une chaîne magique
  4. Le nom du marqueur qui indique où il faut mettre le marqueur de tâche (la petite boule noire sur carte) [Optionel]
  5. La variable synchronisée qui indique si la tâche est réussie [Optionel]
  6. La variable synchronisée qui indique si la tâche est échouée [Optionel]
Donc, on a créé la tâche avec une petite ligne de code. Et pour changer le statut de cette tâche, on ne touchera plus jamais à la tâche, il suffit de modifier le contenu de la variable qu'on a défini ici, les variables sont: "jip_var_destroyed" et "jip_var_failed"
edt_fnc_task est donc une fonction qui surveille le contenu d'une ou plusieurs variables.

A noter que le nom "jip_var_" est une convention que j'ai choisi pour moi-même pour bien indiquer qu'il s'agit d'une variable synchronisée en JIP. Ca me permet entre autre, de faire des recherches dans notepad++ dans une mission pour récupérer tous les endroits où sont utilisés cette variable. Vous pouvez donner le nom que vous voulez...

De l'autre côté, on a des scripts qui donnent une valeur à une variable. Par exemple, le script assassiner.sqf.
Vous placez un camion sur carte et vous mettez dans son initialisation:

Code : Tout sélectionner

nul = [this,getPos this,"jip_var_destroyed","STR_TRUCK_DOWN"] execVM "assassiner.sqf";
Petite note au passage, pourquoi assassiner.sqf et pas détruire.sqf?
Parce que détruire.sqf c'est quand on veut utiliser des explosifs pour détruire un objet. Ici je veux pouvoir le détruire à la roquette ou même au fusil mitrailleur.

Les paramètres ici sont:
  1. L'objet à détruire, on aurait pu donner un type pour qu'il soit créé à la volée.
  2. La position (elle n'est en fait utile que lorsqu'on donne un type)
  3. Le nom de la variable qui va être mise à "true" lorsque le véhicule est détruit.
  4. Le message qui s'affichera pour tous les joueurs quand le véhicule est détruit, une fois de plus une chaîne magique
Notez qu'on a utilisé le même nom de variable "jip_var_destroyed" dans les deux cas. Ce qui veut dire qu'une fois le camion détruit, le script va assigner une valeur à la variable, ce qui va automatiquement mettre la tâche à jour.

Maintenant, la partie échec de la tâche.
Notre camion roule sur la carte, s'il atteint sa destination, la tâche doit échouer. Il suffit de placer un déclencheur qui détecte la présence de notre camion.
Dans la condition du déclencheur on mettra:

Code : Tout sélectionner

mon_camion in (list trigger_de_fin)
En partant du principe que le déclencheur est nommé: "trigger_de_fin" et le camion est nommé "mon_camion".
Dans l'activation du déclencheur on mettra:

Code : Tout sélectionner

nul = ["jip_var_failed",true] call edt_fnc_setVar;
Et voilà, on affecte un contenu à la variable "jip_var_failed" qui sert à détecter l'échec de la tâche et du coup on ne touche pas à la tâche non plus.

En résumé, le code nécessaire pour créer une tâche, un objectif et l'échec de la tâche:

Code : Tout sélectionner

// A mettre dans le script "mission\start.sqf", dans la partie serveur, ou dans un déclencheur
["STR_TASK_DESTROY_TITLE", "created", "STR_TASK_DESTROY_DESC","marker_task_destroy","jip_var_destroyed","jip_var_failed"] call edt_fnc_task;
// A mettre dans l'initialisation du camion nommé: "mon_camion"
nul = [this,getPos this,"jip_var_destroyed","STR_TRUCK_DOWN"] execVM "assassiner.sqf";
// A mettre dans l'activation du déclencheur qui détecte l'arrivée du camion "mon_camion"
nul = ["jip_var_failed",true] call edt_fnc_setVar;
Si on compare avec tout ce qu'on devrait écrire normalement pour faire fonctionner tout ça et pour le synchroniser en JIP... ce n'est vraiment rien du tout!

edt_fnc_getVar
Pour lire le contenu d'une variable synchronisée on va utiliser la fonction suivante:

Code : Tout sélectionner

["nom_variable",valeur_par_défaut] call edt_fnc_getVar
Les paramètres sont:
  1. Le nom de la variable à lire
  2. La valeur par défaut à donner si la variable n'a pas encore reçu de valeur (si on n'a pas encore appelé edt_fnc_setVar
edt_fnc_setVar
Pour assigner un contenu à une variable synchronisée on va utiliser la fonction suivante:

Code : Tout sélectionner

["nom_variable",valeur_donnée] call edt_fnc_setVar
Les paramètres sont:
  1. Le nom de la variable à lire
  2. La valeur qu'on donne à la variable et qu'on peut ensuite récupérer avec edt_fnc_getVar



4) Les variables synchronisées simplifiées
La plupart du temps, je n'ai besoin que de deux états: "true" ou "false" pour un objectif.
Pour ça, j'ai crée 3 fonctions qui sont des raccourcis.
  • edt_fnc_status
  • edt_fnc_completed
  • edt_fnc_canceled
Dans un déclencheur, pour tester un objectif on pourrait écrire dans la condition;

Code : Tout sélectionner

["tmf_edt_1", false] call edt_fnc_getVar
Mais il serait plus rapide de se contenter de:

Code : Tout sélectionner

1 call edt_fnc_status
Les deux fonctions font exactement la même chose!
D'ailleurs, quand vous écrivez le "1" en fait derrière on stocke la variable dans "tmf_edt_1", c'est une variable synchronisée comme les autres... les scripts de la base mission feront la conversion automatiquement tel que assassiner.sqf:

Code : Tout sélectionner

nul = [this,getPos this,1,"STR_TRUCK_DOWN"] execVM "assassiner.sqf";

// Si on veut utiliser une chaîne:
nul = [this,getPos this,"tmf_edt_1","STR_TRUCK_DOWN"] execVM "assassiner.sqf";
Lorsque le camion sera détruit, mon déclencheur va s'activer puisqu'il surveille l'objectif "1".
Attention toutefois à bien passer la valeur en numérique et pas en chaîne de caractère!
Si vous voulez passer une chaîne de caractère, ce sera: "tmf_edt_1"

De la même manière, on peut donner une valeur "vraie" ou "fausse" à l'objectif en utilisant les fonctions:

Code : Tout sélectionner

1 call edt_fnc_completed:
1 call edt_fnc_canceled;
Prenons un cas simple pour un début de mission.
Vous voulez que les joueurs démarrent en chute libre en début de mission et ensuite ils doivent rejoindre un poste avancé.
Si un joueur arrive en cours de route... inutile de le faire démarrer en chute libre... autant le mettre directement au poste avancé.

Mais comment savoir ça? Les joueurs ne sont plus dans le poste avancé (ils sont en cours de mission) et donc un déclencheur dans le poste avancé ne sert à rien!
Eh bien c'est simple.
Placez un déclencheur avec détection des blufor sur le poste avancé. Dans l'activation du déclencheur:

Code : Tout sélectionner

1 call edt_fnc_completed;
Ensuite dans le script "mission\start.sqf" dans la partie joueur, placez le code suivant:

Code : Tout sélectionner

titleText ["", "BLACK FADED"];                                               // Fondu au noir pendant qu'on teste où mettre le joueur.
sleep 3;                                                                                         // pour permettre la synchro des variables
if (1 call edt_fnc_status) then {                                             // On teste si l'objectif est accompli et que les joueurs sont déjà passés par l'outpost
    player setPos (markerPos "marqueur_outpost");    // On place le joueur sur un marqueur dans l'outpost
} else {
    _pos = markerPos ("marqueur_parachutage");         // On récupère la position de largage des joueurs pour leur parachutage
    _pos set [2, (2000 + random(200))];                                // On défini une hauteur aléatoire
    player setPos _pos;                                                              // On place le joueur en hauteur pour sa descente
};
titleFadeOut 5;                                                                          // Fin du fondu au noir
Voilà...
On peut faire ça dans l'éditeur, mais ce ne sera pas lisible... et avec des déclencheurs et des synchros de variable à la main dans l'éditeur... moi je dis "bon courage!".



5) Ce qu'on ne peut pas encore voir

L'un des objectifs de la Base Mission est de pouvoir contenir plusieurs missions dans un même PBO.
Pour ce faire, les missions seront instanciées à la volée et peuvent être même instanciées en même temps.

On ne le voit pas, mais les tâches, les variables, etc. vivent dans un espace qui est propre à cette mission. Et qui n'entrerait pas en collision avec une mission lancée en parallèle dans la même partie.

Pourquoi prévoir ça?
Eh bien pour permettre par exemple d'avoir un serveur public, basé sur la Base Mission qui pourrait enchaîner automatiquement les missions à accomplir. Sans relancer un nouveau PBO à chaque fois. C'est l'objectif initial de tout ce projet, recréer la mission Foreveron d'ArmA 2.

Inutile de charger 20 missions sur votre serveur quand vous voulez organiser une soirée entre amis ou dans votre team, La mission contiendrait elle même déjà une série de missions. Et ça évite un temps de chargement à chaque fois, le script qui défini une mission est très petit, 10/20KB comparé à tous les scripts qui constituent les fonctionnalités de la Base Mission (Btc Revive, Drones, Artillerie, Menu, etc.).

On pourrait encore l'utiliser pour lancer des missions de type "side" sur une autre mission comme la Domination pour peu qu'on y intègre les scripts de la Base Mission. Ce qui permettrait d'avoir des missions plus avancées à jouer sur un serveur public.

Tout cela demande simplement un fichier SQF qui définit le contexte de la mission, place les unités et les objets et lance les scripts appropriés.

Il faudra probablement encore attendre quelques mois... mais ça viendra :)

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

BaseMission - Créer une tâche et la mettre à jour

Message par Tyrghen » 11 juil. 2013, 09:29

Mise à jour: 17/04/2014

Tutoriel - Exemple pas à pas de création et de mise à jour d'une tâche

Dans cette exemple je ne vais créer qu'une seule tâche et la mettre à jour de plusieurs manières, en utilisant les possibilités de la Base Mission.


1) Créer une tâche

Dans notre exemple nous allons simplement créer une tâche qui sera réussie si on atteint une zone et échouée si on atteint une autre.

La méthode la plus simple est de placer la création de vos tâches dans un déclencheur. ATTENTION!!! Il faut laisser quelques secondes après le déclenchement de la mission, mettez un délai au déclencheur de création des tâches. De cette manière le framework est initialisé et les joueurs seront déjà sur place et feront attention à la fenêtre qui s'affiche pour signaler l'ajout d'une tâche.
Un délai de minimum 5 secondes est recommandé!

Le code a entrer dans la zone activation du déclencheur pour cette tâche est:

Code : Tout sélectionner

["Ma tâche","created","Ma description"] call edt_fnc_task;
Pour un rappel des paramètres, voyez le message dédié.
taches_05.jpg
Lancez le jeu et voyez la tâche apparaître lorsque vous vous connectez
taches_10.jpg
taches_10.jpg (15.01 Kio) Consulté 50754 fois


2) Marqueur de tâche

Placez ensuite un marqueur nommé "marker1_1" sur la carte, comme il a été utilisé lors de la création de la tâche, il donnera la position affichée sur carte pour la tâche.

Modifiez le code du déclencheur pour obtenir:

Code : Tout sélectionner

["Ma tâche","created","Ma description","marker1_1"] call edt_fnc_task;
Dans l'éditeur on aura quelque chose du style:
taches_15.jpg
Et lorsqu'on lance le jeu on obtiendra notre tâche, avec un marqueur de tâche.
Pour que le marqueur de tâche aient du texte lorsqu'on passe le curseur dessus. Il suffit de mettre du texte dans le marqueur placé dans l'éditeur.
taches_20.jpg


3) Mettre à jour une tâche - Manuellement

On a plusieurs façons de mettre à jour une tâche, la première est de le faire manuellement en appelant une ligne de code pour mettre à jour le contenu de la tâche et ici, son statut.
Créez un deuxième déclencheur, près du hangar et mettez le en détection de présence des blufors.
Le code d'activation du déclencheur sera:

Code : Tout sélectionner

["Ma tâche","succeeded"] call edt_fnc_task;
taches_17.jpg
Approchez-vous de la zone et vous verrez la tâche se mettre à jour.
taches_35.jpg
taches_35.jpg (15.22 Kio) Consulté 50754 fois
Personnellement, j'évite cette méthode et j'utilise les suivantes, pourquoi?
Eh bien simplement parce que si je me trompe dans mes mises à jour manuelles, c'est possible qu'un déclencheur mette la tâche à réussie alors qu'un autre, toujours actif la mette comme échouée.
Tandis que si je travaille au travers de variables, une fois qu'une de ces variables est passée comme réussie ou échouée, la tâche est mise à jour et ne changera pas, sauf si je fais une mise à jour manuelle.



4) Mettre à jour une tâche - Par une variable

C'est ma méthode préférée....
On va commencer avec une variable classique, qu'on met à jour à l'aide de edt_fnc_setVar (voir le message dédié pour l'explication).
Modifiez le premier déclencheur qui crée la tâche et changez le code d'activation en:

Code : Tout sélectionner

["Ma tâche","created","Ma description","marker1_1","jip_var_done"] call edt_fnc_task;
Notez qu'on a ajouté un nom de variable synchronisé: "jip_var_done".
Le format "jip_var_" n'est pas obligatoire, moi je l'ajoute simplement pour des raisons de lisibilité et pour le retrouver plus vite quand je cherche dans mon code avec NotePad++.
taches_25.jpg
taches_25.jpg (31.52 Kio) Consulté 50754 fois
Modifiez ensuite le deuxième déclencheur près du hangar et remplacez le code par:

Code : Tout sélectionner

["jip_var_done",true] call edt_fnc_setVar;
taches_30.jpg
Une fois de plus, avancez vous vers le hangar et vous verrez que le statut de la tâche changera.
taches_40.jpg


5) Faire échouer une tâche - Par une variable

Le principe est le même que ci-dessus, à part qu'on ne parle pas de la réussite, mais de l'échec de la tâche.
Il faut une fois de plus modifier la création de la tâche.

Code : Tout sélectionner

["Ma tâche","created","Ma description","marker1_1","jip_var_done","jip_var_failed"] call edt_fnc_task;
Notez qu'on a ajouté un nom de variable synchronisé: "jip_var_failed".
Si on met cette variable à "true" (vrai), la tâche sera échouée.
taches_45.jpg
taches_45.jpg (35.38 Kio) Consulté 50754 fois
On crée donc un deuxième déclencheur sur un autre hangar. Et si on entre dans ce déclencheur, la tâche sera échouée.
Le déclencheur sera du type "Detect Blufor Present".
Le contenu du code d'activation sera:

Code : Tout sélectionner

["jip_var_failed",true] call edt_fnc_setVar;
taches_50.jpg
Lorsqu'on s'approche du deuxième hangar, la tâche sera échouée. Même si on s'approche du premier hangar, ça ne change plus rien...
taches_55.jpg
taches_55.jpg (27.04 Kio) Consulté 50754 fois
Et sur la carte ça donne:
taches_60.jpg


6) Mettre à jour une tâche par variable "numérique"

Pour accélérer la création et la lecture des missions, je travaille généralement avec des objectifs numériques.
Sur un bout de papier j'ai décris le déroulement de ma mission et j'y associe des numéros. Je peux ensuite traduire ce déroulement en objectifs dans ma mission.
Pour ce faire, j'utilise les fonctions:
  • edt_fnc_status : donne l'état d'un objectif
  • edt_fnc_completed : assigne le statut réussi à un objectif (met sa valeur à "true")
  • edt_fnc_canceled : annule le statut d'un objectif (met sa valeur à "false")
Le détail de ces fonctions se trouve dans le message dédié.

Ces fonctions utilisent des valeurs numériques (1, 2, 100, 2000, etc.) qui sont traduites en variables synchronisées équivalentes ("tmf_edt_1", "tmf_edt_2", "tmf_edt_100", "tmf_edt_2000").
Ces valeurs ne doivent pas se suivre et généralement j'essaye de les regrouper par tranches.
Par exemple, toutes les valeurs entre:
  • 1 et 100 (exclu) sont pour la réussite des objectifs
  • 100 et 200 (exclu) sont pour les échecs, le fait d'être détecté par l'ennemi, etc.
  • 200 et 300 (exclu) sont pour les conditions de fin de mission
Là, pas de règle.. chacun ses goûts.
Mais je conseille fortement, quand on crée une mission compliquée, de se munir d'un papier et de noter le déroulement de la mission et des objectifs.

Commençons par modifier la création de la tâche.
Le nouveau code est:

Code : Tout sélectionner

["Ma tâche","created","Ma description","marker1_1",1,2] call edt_fnc_task;
taches_65.jpg
taches_65.jpg (31.77 Kio) Consulté 50750 fois
Il faut ensuite modifier le code d'activation des deux déclencheurs pour qu'ils utilisent eux aussi les objectifs numériques.

Pour la zone réussite:

Code : Tout sélectionner

1 call edt_fnc_completed
taches_70.jpg
Pour la zone d'échec:

Code : Tout sélectionner

1 call edt_fnc_completed
taches_75.jpg


Conclusion

On a parcouru les différentes étapes de la création et de la mise à jour d'une tâche, avec les différentes possibilités.
Ca demande un minimum de pratique et une fois qu'on l'a fait une ou deux fois, ça devient pratiquement automatique.

La meilleure règle à suivre, c'est de commencer avec des choses simples.
Si vous démarrez directement par une mission tirée par les cheveux, ça ne fonctionnera JAMAIS.
Prenez un scénario simple, mettez le sur pied et ensuite ajoutez au fur et à mesure que vous vous sentez à l'aise...
Pièces jointes
[V]Exemple.Stratis.zip
Version 2.06a - Exemple complet
(1.01 Mio) Téléchargé 549 fois
[V]Exemple.Stratis.zip
Version 2.07 - Exemple partiel
(1.79 Mio) Téléchargé 523 fois

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

BaseMission - Mettre à jour vos missions

Message par Tyrghen » 14 juil. 2013, 19:58

Mise à jour: 14/09/2014

Tutoriel - Mettre à jour vos missions

Ici je couvre deux cas possibles:
  1. Mettre à jour vos missions pour les versions supérieure ou égale à la 2.07
  2. Mettre à jour une mission pour plus ancienne que la 2.07
1) Mise à jour avec une version 2.07 ou plus

La procédure est extrêmement simple, si vous avez respecté la logique de création et placé tous vos scripts dans le sous-répertoire "mission", il suffit de:
  • faite une copie de sauvegarde de votre mission en l'état actuel (je fais généralement un répertoire "[nomDeMission].bkp"
  • effacer le répertoire TMF
  • copier le répertoire TMF depuis la nouvelle version de la Base Mission
  • copier tous les fichiers à la racine de la Base Mission SAUF le mission.sqm vers votre répertoire de mission
Voilà... rien de plus simple.

2) Mise à jour avec une version antérieure à la 2.07

Bon... là c'est plus compliqué, il faudra être plus prudent.
Voici une liste de points à vérifier qui devraient vous permettre de passer cette étape sans encombre.
  • Si vous avez des marqueurs nommés "buildingXXX", renommez les en "building_XXX" avec notepad++ éditez votre fichier mission.sqm directement.
  • Si votre version est vraiment très ancienne, les fonctions edt_fnc_task et edt_fnc_taskSilent ont changé dans l'ordre des paramètres. Le statut (created, succeeded, etc) est passé en deuxième position.
  • Ajouter un sous-répertoire "mission" si vous ne l'avez pas déjà
  • Déplacer le fichier setup.sqf depuis la racine de la mission vers le sous-répertoire "mission"
  • Si vous ne les avez pas, ajouter les fichiers vide suivant au sous-répertoire "mission":
    • conversation.hpp
    • start.sqf
    • init.sqf
    • cfgFunctions.hpp
    • description.hpp
  • Déplacez tous les fichiers spécifiques à votre mission qui sont dans le répertoire racine de votre mission
  • Editez le fichier "mission\description.hpp" et enlevez le code suivant: #include <conversations.hpp>
    Le script est référencé directement dans le description.ext
  • Editez le fichier description.ext et déplacez TOUS les éléments spécifiques à votre mission dans le fichier "mission\description.hpp"
  • Vérifiez les chemins des images éventuelles si vous les avez déplacées dans le répertoire "mission"
  • Editez votre fichier start.sqf si nécessaire
Image

Répondre