NWScript - pour niveau 5

Un nouveau monde s'ouvre à nous, celui de la persistance. Vous verrez comment danser avec des variables de natures différentes. De la variable globale à la variable de campagne, et en passant par la variable locale, vous naviguerez en eaux profondes dans un immense océan de données baladeuses. Des données grâce auxquelles vous pourrez faire parler les scripts entre eux.

En espérant que vous aurez le pied marin... Mais n'enfilez pas votre tenue de matelot, car c'est le chapeau de capitaine qui couvrera votre chef.



NWScript - Page générale

NWScript - pour niveau 1
- Bases et notions de programmation -

NWScript - pour niveau 2
- Conditions if/else et opérateurs ET / OU -

NWScript - pour niveau 3
- Boucles while/for et sélection switch/case -

NWScript - pour niveau 4
- Constantes, fonctions, et bibliothèques -

NWScript - pour niveau 5
- Variables persistantes et exécution de scripts -

Variables globales

Une variable globale est semblable en tout point à une variable commune, à ceci près qu'elle est valable pour la totalité du module. En effet, une variable globale créée continue d'exister au delà de l'enceinte d'un script. On peut comparer une variable globale à un post-it collé sur le module, que l'on pourrait consulter à tout moment, et à partir de n'importe quel script.

De ce fait, une variable globale existe jusqu'à l'arrêt du module.

Une variable globale ne peut être que du type "float", "int" ou "string". De plus, étant donné qu'elle est omniprésente, il ne peut exister deux variables globales ayant le même nom.


Pour inscrire une variable globale, on utilise les fonctions suivantes :
- "SetGlobalBool(...)" : inscrit une variable de type "int" booléenne*
- "SetGlobalFloat(...)" : inscrit une variable de type "float"
- "SetGlobalInt(...)" : inscrit une variable de type "int"
- "SetGlobalString(...)" : inscrit une variable de type "string"
* de valeur TRUE ou FALSE, respéctivement égal à 1 ou 0

Ces fonctions utilisent deux paramètres permettant :
- de définir le nom* de la variable
- de définir la valeur de la variable
* le nom est soumis au mêmes règles que les variables normales.


Pour consulter une variable globale, on utilise les fonctions suivantes :
- "GetGlobalBool(...)" : consulte une variable de type "int" booléenne
- "GetGlobalFloat(...)" : consulte une variable de type "float"
- "GetGlobalInt(...)" : consulte une variable de type "int"
- "GetGlobalString(...)" : consulte une variable de type "string"

Ces fonctions utilisent un paramètre permettant de définir le nom de la variable à consulter.

Notez que ces fonctions renverront une valeur, même si on consulte une variable globale inexistante :
- "GetGlobalBool(...)" : renverra la valeur FALSE (0)
- "GetGlobalFloat(...)" : renverra la valeur 0.0
- "GetGlobalInt(...)" : renverra la valeur 0
- "GetGlobalString(...)" : renverra une chaîne de caractères vide

Variables locales

Une variable locale est semblable en tout point à une variable globale, à ceci près qu'elle s'inscrit sur un objet du jeu. Deux variables locales portant le même nom, et étant du même type peuvent exister sur deux objets différents. On peut comparer une variable locale à un post-it collé sur un objet spécifique.

De ce fait, une variable locale est totalement indépendante. Elle existe jusqu'à l'arrêt du module, à moins qu'on ne la supprime soi-même.

Une variable locale peut être de type "float", "int", "string", mais aussi de type "location" ou encore de type "object". De plus, une variable locale existe pour l'objet sur lequel on l'a inscrite. Deux variables locales du même nom et du même type peuvent exister si leur support est différent.


Pour inscrire une variable locale, on utilise les fonctions suivantes :
- "SetLocalFloat(...)" : inscrit une variable de type "float"
- "SetLocalInt(...)" : inscrit une variable de type "int"
- "SetLocalString(...)" : inscrit une variable de type "string"
- "SetLocalLocation(...)" : inscrit une variable de type "location"
- "SetLocalObject(...)" : inscrit une variable de type "object"

Ces fonctions utilisent trois paramètres permettant :
- de définir l'objet supportant la variable
- de définir le nom* de la variable
- de définir la valeur de la variable
* le nom est soumis au mêmes règles que les variables normales.

Ces fonctions sont de type "void", et ne renvoient pas de valeur.

Par exemple, dans un script exécuté lors de l'utilisation d'un plaçable, je peux inscrire une variable locale sur un joueur de cette manière :

void main()
{
    object oJoueur = GetLastUsedBy();

    // Je vais inscrire une variable de type "int" :
    // - Mon support sera "oJoueur"
    // - Le nom de ma variable sera "MA_VARIABLE_INT"
    // - La valeur de ma variable sera 1
    SetLocalInt(oJoueur,"MA_VARIABLE_INT",1);
}


Pour consulter une variable locale, on utilise les fonctions suivantes :
- "GetLocalFloat(...)" : consulte une variable de type "float"
- "GetLocalInt(...)" : consulte une variable de type "int"
- "GetLocalString(...)" : consulte une variable de type "string"
- "GetLocalLocation(...)" : consulte une variable de type "location"
- "GetLocalObject(...)" : consulte une variable de type "object"

Ces fonctions utilisent deux paramètres permettant :
- de sélectionner l'objet supportant la variable
- de définir le nom de la variable à consulter

Le type de chaque fonction correspond à la valeur que l'on souhaite obtenir. "GetLocalInt(...)" est donc une fonction de type "int" et renvoie ce même type de valeur. La variable que l'on veut consulter avec cette fonction devra être de type "int".

Par exemple, dans un script exécuté lors de l'utilisation d'un autre plaçable, je peux récupérer ma variable de cette manière :

void main()
{
    object oJoueur = GetLastUsedBy();

    // Je récupère la valeur de ma variable :
    // - Mon support est "oJoueur"
    // - Le nom de la variable est "MA_VARIABLE_INT"
    int nVariable = GetLocalInt(oJoueur,"MA_VARIABLE_INT");

    // J'annonce la valeur de ma variable au joueur :
    SendMessageToPC(oJoueur,"Valeur : "+IntToString(nVariable));
}

Notez que ces fonctions renverront une valeur, même si la variable que vous essayez de consulter n'existe pas :
- "GetLocalFloat(...)" renverra la valeur 0.0
- "GetLocalInt(...)" renverra la valeur 0
- "GetLocalString(...)" renverra une chaîne de caractères vide
- "GetLocalObject(...)" renverra la valeur OBJECT_INVALID.


Pour supprimer une variable locale, on utilise les fonctions suivantes :
- "DeleteLocalFloat(...)" : supprime une variable de type "float"
- "DeleteLocalInt(...)" : supprime une variable de type "int"
- "DeleteLocalString(...)" : supprime une variable de type "string"
- "DeleteLocalLocation(...)" : supprime une variable de type "location"
- "DeleteLocalObject(...)" : supprime une variable de type "object"

Ces fonctions utilisent deux paramètres permettant :
- de sélectionner l'objet supportant la variable
- de définir le nom de la variable à Supprimer

Par exemple, dans le script exécuté lors de l'utilisation de mon deuxième plaçable, je peux supprimer ma variable après l'avoir consultée :

void main()
{
    object oJoueur = GetLastUsedBy();

    int nVariable = GetLocalInt(oJoueur,"MA_VARIABLE_INT");
    SendMessageToPC(oJoueur,"Valeur : "+IntToString(nVariable));

    // Je supprime ma variable :
    DeleteLocalInt(oJoueur,"MA_VARIABLE_INT");
}


Il est également possible d'inscrire des variables locales de type "float" / "int" / "string" sur un objet, directement à partir de l'éditeur. Il suffit pour cela d'éditer les paramètres de l'objet, et d'ouvrir sa fenêtre de variables locales :

image

Faire communiquer des scripts

Grace au système des variables locales, deux scripts peuvent se communiquer des valeurs précises.

Par exemple, je désire qu'un joueur utilise trois fois un premier plaçable pour qu'un deuxième plaçable lui envoie un gentil message. Dans mon premier script, j'inscrirai et ferai évoluer ma variable sur le joueur. Dans le deuxième, je vérifierai s'il a au moins répété l'opération trois fois :

void main()
{
    object oJoueur = GetLastUsedBy();

    int nVariable = GetLocalInt(oJoueur,"MA_VARIABLE_INT");

    // De cette manière, j'incrémente ma variable locale :
    SetLocalInt(oJoueur,"MA_VARIABLE_INT",nVariable+1);
}

void main()
{
    object oJoueur = GetLastUsedBy();

    int nVariable = GetLocalInt(oJoueur,"MA_VARIABLE_INT");

    // Je vérifie si la variable a bien été incrémentée :
    if(nVariable >= 3)
    {
        SendMessageToPC(oJoueur,"Félicitations !");
    }

    else
    {
        SendMessageToPC(oJoueur,"Allez cliquer encore un peu...");
    }
}

On peut aisément imaginer les possibilités qu'offre le système des variables locales. Cette méthode est utilisée par les scripts de Neverwinter Nights 2, notamment pour définir des paramètres de jeu, ou encore lors de l'utilisation de certains sorts.

Exécuter un script à partir d'un autre script

Un script peut en cacher un autre. Il existe une fonction permettant à un script d'exécuter un autre script. Il s'agit de "ExecuteScript(...)", dont les paramètres devront désigner l'objet qui supportera le script, ainsi que le nom du script à exécuter.

Dans un script, le processus sera le suivant :
- Les lignes de code avant la commande "ExecuteScript(...)" seront exécutées
- Le script appelé par la commande "ExecuteScript(...)" sera exécuté
- Les lignes de code après la commande "ExecuteScript(...)" seront exécutées

Je vais combiner ce système avec celui des variables locales. Je préparerai donc deux scripts, dont les noms seront respéctivement "exemple1" et "exemple2" :

// Script "exemple1" :

void main()
{
    object oJoueur = GetLocalObject(OBJECT_SELF,"VARIABLE_OBJECT");

    SendMessageToPC(oJoueur,"Exemple 1");
}

// Script "exemple2" :

void main()
{
    object oJoueur = GetLocalObject(OBJECT_SELF,"VARIABLE_OBJECT");

    SendMessageToPC(oJoueur,"Exemple 2");
}

Ensuite, à partir de l'éditeur, je poserai deux plaçables utilisables dans une zone, et leur inscrirai une variable de type "string". Pour les deux plaçables, le nom de variable que je choisirai sera "SCRIPT". Pour le premier plaçable, la valeur de cette variable sera "exemple1". Pour le deuxième plaçable, la valeur sera "exemple2" :

image

Enfin, je créerai un troisième script "exemple 3" destiné à l'événement déclenché lors de l'utilisation des deux plaçables :

// Script "exemple3" :

void main()
{
    object oJoueur = GetLastUsedBy();

    // Je mets l'utilisateur en variable locale de type "object" :
    SetLocalObject(OBJECT_SELF,"VARIABLE_OBJECT",oJoueur);

    // Sur le plaçable, je récupère la valeur de la
    // variable que j'ai inscrite dans l'éditeur
    string sScript = GetLocalString(OBJECT_SELF,"SCRIPT");

    // Et je lance le script dont le nom correspond
    // à cette valeur :
    ExecuteScript(sScript,OBJECT_SELF);
}

Au final, le script "exemple3" fera référence à une variable locale de type "string", dont la valeur sera le nom du script à exécuter. La valeur de la variable locale étant différente sur chacun des plaçables, le script exécuté sera différent.

Vous constaterez aisément que le champ des possibilités au niveau de la programmation s'en trouve grandement élargi.

Variables de campagne

Il existe une troisième variable pouvant exister hors d'un script : la variable de campagne. A la différence d'une variable globale ou locale, la variable de campagne existe au dela de la durée de vie du module. Elle créera et/ou modifiera un fichier afin de stocker une valeur.

Une variable de campagne peut être de type "float", "int", "string", mais aussi de type "location" ou "vector". De plus, il est possible de leur assigner un personnage joueur en référence. Deux variables de campagne du même nom peuvent exister si le personnage joueur de référence est différent, et/ou si le fichier dans lequel elles sont stockées est différent.


Il existe donc cinq fonctions permettant d'inscrire une variable de campagne :
- "SetCampaignFloat(...)" : inscrit une variable de type "float"
- "SetCampaignInt(...)" : inscrit une variable de type "int"
- "SetCampaignString(...)" : inscrit une variable de type "string"
- "SetCampaignLocation(...)" : inscrit une variable de type "location"
- "SetCampaignVector(...)" : inscrit une variable de type "vector"

Chacune de ces fonctions utilise quatre paramètres permettant :
- de définir le nom du fichier* dans lequel la variable sera stockée
- de définir le nom de la variable à stocker
- de définir la valeur de la variable à stocker
- de définir si un joueur doit être pris comme référence (facultatif)
* Il s'agit simplement du nom, et non du nom.extension. De plus, si le fichier n'existe pas, il sera automatiquement créé pour stocker la variable.

Par exemple, je désire stocker la date du module en tant que variable de campagne :

void main()
{
    // Je récupère les valeurs de la date du module,
    // soit l'année, le mois, et le jour :
    int nAn = GetCalendarYear();
    int nMois = GetCalendarMonth();
    int nJour = GetCalendarDay();

    // Puis je stocke ces trois valeurs dans un fichier.
    // Ce fichier s'appellera "date_module" :
    SetCampaignInt("date_module","DATE_ANNEE",nAn);
    SetCampaignInt("date_module","DATE_MOIS",nMois);
    SetCampaignInt("date_module","DATE_JOUR",nJour);
}


Les fonctions suivantes permettent de consulter une variable de campagne :
- "GetCampaignFloat(...)" : consulte une variable de type "float"
- "GetCampaignInt(...)" : consulte une variable de type "int"
- "GetCampaignString(...)" : consulte une variable de type "string"
- "GetCampaignLocation(...)" : consulte une variable de type "location"
- "GetCampaignVector(...)" : consulte une variable de type "vector"

Chacune de ces fonctions utilise trois paramètres permettant :
- de définir le nom du fichier* dans lequel la variable est stockée
- de définir le nom de la variable stockée
- de définir si un joueur doit être pris comme référence (facultatif)

Dans un autre script, je peux donc récupérer mes valeurs et attribuer au module la date sauvegardée :

void main()
{
    // Je récupère mes valeurs stockées
    // dans le fichier "date_module"
    int nAn = GetCampaignInt("date_module","DATE_ANNEE");
    int nMois = GetCampaignInt("date_module","DATE_MOIS");
    int nJour = GetCampaignInt("date_module","DATE_JOUR");

    // Puis j'attribue ces trois valeurs
    // à la date du module :
    SetCalendar(nAn,nMois,nJour);
}

Notez que ces fonctions renverront une valeur, même si on consulte une variable de campagne inexistante :
- "GetCampaignFloat(...)" : renverra la valeur 0.0
- "GetCampaignInt(...)" : renverra la valeur 0
- "GetCampaignString(...)" : renverra une chaîne de caractères vide
- "GetCampaignVector(...)" : renverra le vecteur [0.0, 0.0, 0.0]


Il existe une fonction supplémentaire permettant de supprimer une variable de campagne : "DeleteCampaignVariable(...)". Celle-ci comporte deux paramètre définissant le fichier, et le nom de la variable à effacer. Notez que l'utilisation de cette fonction n'efface pas totalement la variable. En fait elle ne fait que marquer cette variable comme "inutilisable".

Vous avez gagné un niveau !

Désormais le champ d'action des scripts s'est considérablement élargi. Vous devriez pouvoir créer des scripts complexes, aux valeurs persistantes ou semi-persistantes.

Vous aurez ici tous les outils nécessaires pour vous amuser jusqu'à notre prochain niveau.



NWScript - Page générale

NWScript - pour niveau 1
- Bases et notions de programmation -

NWScript - pour niveau 2
- Conditions if/else et opérateurs ET / OU -

NWScript - pour niveau 3
- Boucles while/for et sélection switch/case -

NWScript - pour niveau 4
- Constantes, fonctions, et bibliothèques -

NWScript - pour niveau 5
- Variables persistantes et exécution de scripts -

Réactions


Personne n'a encore réagi. Soyez le premier.

Que pensez-vous de Neverwinter Nights 2 ?

127 aiment, 20 pas.
Note moyenne : (155 évaluations | 5 critiques)
8,4 / 10 - Très bien

315 joliens y jouent, 840 y ont joué.