3. Les variables
Précédemment, nous avons vu les différents types proposés dans le langage NWScript : il nous faut encore savoir comment les utiliser ! Une variable doit tout le temps être déclarée avant d'être utilisée : si vous tentez d'utiliser une variable 'x' qui n'existe pas, le script ne fonctionnera pas. Cette même variable devra être typée : ceci permettra à l'ordinateur d'allouer de la mémoire pour stocker la variable.
Quoiqu'il arrive, lorsque vous définissez une variable vous devez lui donner un nom: ce nom ne devra pas commencer par un caractère autre que des lettres (minuscules, ou majuscules) et ne devra pas contenir autre chose que des chiffres (0 à 9), des lettres (a à z, A à Z) et le tiret « _ ».
Pour définir une variable, nous utiliserons la syntaxe suivante :
type NomVariable1[, ...[, NomVariableN]][ = Valeur];
Où type correspond à un des différents types que nous avons vus dans la section 2. NomVariable1 à un nom de variable et Valeur à une valeur en fonction du type.
- action, command, void, constant : vous ne pouvez pas définir de variable de ces types là. Pour constant : vous en saurez plus en allant en fin de cette section.
- effect :
effect Effect1, Effect2 = EffectBlindness();
effect Effect1, Effect2;
effect Effect1 = EffectBlindness();
effect Effect1 ;
- event :
event DoNothing, DoSomething = EventUserDefined( 0 );
event DoNothing, DoSomething;
event DoNothing = EventUserDefined( 0 );
event DoNothing;
- float : un nombre décimal doit tout le temps posséder un chiffre après la virgule. Vous devez aussi faire suivre votre nombre d'un 'f' tel que :
float fFloat1, fFloat2 = 1.3f;
float fFloat1, fFloat2 ;
float fFloat1 = 1.3f;
float fFloat1;
- int :
int iInteger1, iInteger2= 1;
int iInteger1, iInteger2;
int iInteger1= 1;
int iInteger1;
- location : pour créer une location, nous devons passer par d'autres variables. Les variables sZone, sWayPoint et oPlayer ont été définies en tant qu'argument de fonction (voir section sur les fonctions).
object oArea = GetObjectByTag( sZone );
float fOrientation = GetFacing( oPlayer );
vector vPosition = GetPosition( GetObjectByTag( sWayPoint ) );
location lWhereToGo = Location( oArea, vPosition, fOrientation );
- object :
object oPlayer1, oPlayer2, ..., oPlayer6 ;
object oSelf = OBJECT_SELF ;
object oInvalid = OBJECT_INVALID ;
- string : pour définir une chaîne de caractère, vous devez délimiter celle-ci par le symbole double-quote « " ». Vous ne devrez pas inclure d'autre symbole double-quote dans votre chaîne de caractères.
string sFoo1, sFoo2 = "Salut" ;
string sFoo1, sFoo2 = "Sal"ut" ;
string sFoo1, sFoo2 = "Sal\"ut" ;
string sFoo1, sFoo2 = "Sal""ut" ;
string sFoo;
- struct :
Avant d'utiliser une structure vous, devez déclarer celle-ci : voici comment on la déclare. Ce bloc doit être placé à l'extérieur de tout bloc main(), ou StartingConditionnal() sinon cela ne fonctionnera pas correctement.
struct FX
{
int fx;
float time;
int damage;
int damageType;
int damageMin;
int damageMax;
};
Vous ne devez pas oublier le « ; » après le « } » sinon le compilateur vous avertira de l'erreur. N'oubliez pas : vous ne pouvez pas définir de structures dans votre structure. Aussi, vous ne pouvez pas donner de valeur initiale à vos différents éléments.
Maintenant, pour définir une variable utilisant une structure :
Vous devez commencer par struct, jusque là, c'est comme pour les autres types. Ensuite, vous devez faire suivre struct de FX et ensuite des noms de variable que vous désirez définir.
Vous devrez ensuite donner une valeur à vos variables par vous-même :
aura.fx = VFX_DUR_AURA_COLD;
aura.time = 3.0;
Vous comprenez bien sûr que ce n'est pas forcément très appréciable : si vous voulez vous débarrasser de ce problème, voici une solution (nous l'expliciterons plus en détails dans la section sur les fonctions).
struct FX ReturnFX()
{
struct FX beam;
beam.fx = VFX_BEAM_LIGHTNING;
beam.time = 0.5;
beam.damage = FALSE;
return beam;
}
Ensuite, vous n'aurez plus qu'à définir vos deux variables ainsi :
struct FX aura, beam = ReturnFX();
Note : la structure devra être déclarée avant la fonction.
- talent :
talent Talent1, Talent2 = GetCreatureTalentBest( 0, 0 );
talent Talent1, Talent2;
talent Talent1 = GetCreatureTalentBest( 0, 0 );
talent Talent1;
- vector : un vecteur est en fait une structure comprenant 3 nombres décimaux x, y, z.
vector vVecteur = vAutreVecteur ;
vector vVecteur = 0.0 ;
vector vVecteur1 ;
vVecteur.x = 0.0 ;
vVecteur.y = 0.0 ; .
vVecteur.z = 0.0 ;
Une fois que vous avez déclaré vos variables, vous pouvez bien sur définir ou redéfinir le contenu de celles-ci:
int iValue = 5 ;
iValue = 4 ;
(note : cela iValue est un entier, n'oubliez jamais le type de la variable, et n'essayez jamais de rentrer autre chose que des entiers dans une variable déclarée comme étant un entier ; c'est un peu comme une serrure A: vous ne pourrez jamais rentrez la clef B de la serrure B dans la serrure A car les serrures ne sont pas de mêmes types)
Nous n'avons vu que des variables locales : l'intérêt, c'est que celles-ci sont automatiquement supprimées (elles n'occupent plus de place en mémoire) après l'exécution du script. Voyons maintenant les variables globales : imaginez juste par exemple que vous décidiez de stocker une chaîne de caractères qui contiendrait le blueprint d'un item (note : le blueprint est en quelque sorte la carte génétique d'un objet : avec celui-ci, vous serez à même de pouvoir recréer à l'infini un objet. Vous ne devez pas confondre Tag qui correspond au nom usuel (pour les scripts) de l'objet, et le blueprint qui correspond donc à une référence permettant de recréer l'objet)).
Vous pourriez décider de mettre 'item' (si 'item' est le blueprint de votre item) dans la fonction CreateItemOnObject tel que :
CreateItemOnObject( "item", oPlayer );
CreateItemOnObject( "item", oPlayer );
Bien sur, si vous connaissez déjà les NWScripts, vous devriez savoir qu'on peut utiliser le paramètre nStackSize de la fonction CreateItemOnObject. Cependant, cela ne fonctionnera qu'avec des objets particuliers (par exemple, des flèches). Maintenant, mettons que vous voulez des blueprint génériques : c'est-à-dire sous une forme typée : par exemple « item_fleches_feu » qui est plus clair que « item ». Vous devriez alors changer 100 lignes de code !
Dans notre exemple, on suppose que l'item est créé 100 fois dans le même script : mais imaginons que vous ayez refait la même chose dans un autre script : vous devriez changer aussi ces valeurs là ! Bien sur, vous pouvez utiliser l'option Rechercher/Remplacer dans des fichiers, mais mettons que vous vouliez finalement ne modifier que les 50 premières lignes : la recherche vous demanderait toutes les deux secondes si oui ou non il faut modifier la ligne, etc...
Non, ce procédé serait bien évidemment trop long.
Il vaut mieux utiliser une variable par exemple :
string sBluePrint = "item" ;
CreateItemOnObject( sBluePrint, oPlayer );
CreateItemOnObject( sBluePrint, oPlayer );
Cependant, cette variable est locale: c'est-à-dire que si vous devez changer le blueprint de votre item vous devriez alors le faire dans les autres fonctions où le blueprint est utilisé : ce serait trop de travail (oui, les programmeurs sont parfois des feignasses) et aussi il se pourrait qu'en cours on réutilise la variable sBluePrint.
C'est pour cela qu'on va faire appel aux variables globales : vous pourrez utiliser les variables n'importe où dans le script pour peu qu'elles soient déclarées
Pour vos variables globales, n'hésitez pas à créer un script uniquement pour cela : une fois que vous l'avez crée (nommez le par exemple « inc_constantes » : une constante est normalement globale, et son contenu ne change pas : ce qui est le cas de nos variables globales), vous n'aurez plus qu'à l'inclure avec :
#include "<nom_du_script>"
Cette instruction doit être placée en entête de script de préférence.
Par exemple :
#include "inc_constantes"
void main()
{
CreateItemOnObject( ITEM_FLECHE_DE_FEU, oPlayer );
CreateItemOnObject( ITEM_FLECHE_DE_FEU, oPlayer );
}
Une variable globale est typée bien entendu : voici ce que contiendrait notre fichier-script (ou script) « inc_constantes »
string ITEM_FLECHE_DE_FEU = "item" ;
Vos constantes pourront être d'à peu près n'importe quel type. Vous pourrez les définir à l'intérieur d'un script et vous resservir de la valeur de la variable globale sans problèmes (note : nous n'avons pas testé si la variable globale était redéfinie ou si la valeur actuelle (et modifiée) de celle-ci était gardée en mémoire (ce qui logiquement devrait être le cas).
Note : notre exemple ne le montre pas forcément, mais votre variable globale doit être impérativement déclarée à l'extérieur de tout bloc.