Archives des forums MMO/MMORPG > Neverwinter Nights > NWN - Maskado > Cours de Scripts pour les Quiches. Leçon Quatre.
Cours de Scripts pour les Quiches. Leçon Quatre.
Par Amaranthe le 9/7/2002 Ă 13:23:17 (#1780897)
Par Celowin mailto:james.foxglove@verizon.net
traduit par Amaranthe mailto:amaranthe@free.fr
Introduction
Le but de cette série de leçons, est d'apprendre a se servir des scripts a n'importe qui.
Commençons.
Bon, les plus perspicaces ou acharnés d’entre vous aurons remarqué que notre garde de la leçon trois n’a pas exactement le comportement voulu. A chaque fois que le garde est amical, il salue deux fois. Il faut bien faire attention pour s’en apercevoir, mais quand même, c’est… gênant. De plus, cela me donne la chance d’expliquer une autre concept.
Premièrement, tâchons de comprendre le pourquoi de la chose. Il faut pour cela en venir au fonctionnement du script du « OnPerceive ». Il y a quatre chose qui « appellent » ce script.
Le npc voit quelque chose.
Le npc entend quelque chose.
Le npc s’aperçoit de la disparition de quelqu’un.
Le npc s’aperçoit du silence de quelqu’un.
Ce qui s’est passé dans notre exemple est que notre garde a vu ET entendu le personnage, ce qui fait que le script a été appelé deux fois. Il y a plusieurs moyen de corriger cela, mettons que nous voulons que le garde ne réagisse qu’a la VUE de l’objet. Ce qui correspond plus a ce que nous cherchons a faire. Il est en effet peu probable qu’il entende l’anneau…
On pourrait faire cela en rajoutant une imbrication dans nos tests. Mais ceux ci étaient déjà un peu compliqués. Ce que nous voulons est que notre script ne soit activé que si l’objet perçu est un personnage, et que cet objet ait été perçu par la vue.
Il suffit donc de modifier la condition en ajoutant l’opérateur « && » qu’il suffit de lire comme un « ET ». Notre condition sera vraie, si et seulement si les deux parties sont vraies.
if (GetIsPC(oSeen))
Changée en
if (GetIsPC(oSeen) && GetLastPerceptionSeen())
La commande GetLastPerceptionSeen ramène TRUE si la dernière chose perçue a été vue, et FALSE dans les trois autres cas.
Il y a un autre opérateur qui peut être utilisé pour relier deux conditions, c’est le « || » qui peut être lu comme « OU ». La condition se réalise si l’une ou l’autre de ses deux parties est vraie.
Ces opérateurs nous ramènent a Boole… vous vous souvenez de lui ?
Boole a créé ce qu’on appelle aujourd’hui « l’algèbre de Boole ». Et comme dans toute algèbre, il y a des opérateurs et des opérandes.
Si j’insiste sur ce point, c’est parce que c’est un des sujets les plus difficiles a maîtriser pour un développeur. Et que c’est un des plus vitaux.
On parle ici de logique et de mathématique. Cela n’a que peu de rapport avec le français.
A la question : « Est ce un garçon ou une fille ? » N’importe qui répondra « un garçon » ou « une fille »… Un script répondra « VRAI ».
Si cela vous intéresse je vous ferai un vrai cours de logique booléenne. Mais il y a déjà beaucoup de sites très bien fait…
Confession.
Jusqu'à présent, je vous ai toujours dit que je vous proposais des scripts comme je les aurai écrit. Je doit maintenant vous avouer que c’est faux. Jamais je n’aurai écrit les scripts comme cela.
Le problème vient du fait de tous ces scripts par défaut que l’on a effacés pour mettre les nôtres. Vous vous en souvenez ? Maintenant, notre garde fait ce qu’on lui demande, mais il ne répond plus a aucun autre stimulus. Essayez par exemple de l’attaquer… il ne se défendra même pas ;(
La question qui se pose donc est, comment ajouter un comportement, tout en gardant tous les comportements par défaut. Et la réponse est : En utilisant les « User defined » scripts. Ce qui est l’objet de ce cours. Avouez que cela tombe bien non ?
Retravaillons donc notre garde.
- Ouvrez votre module de Test.
- Supprimez le garde.
- Créez un autre npc a sa place, de façon a récupérer tous les scripts par défaut.
- Changez son tag en « GARDE ».
- Vérifiez dans l’onglet « Advanced » que sa faction soit bien « Commoner ».
- Activez l’onglet « Scripts ».
- Editez le script du « OnSpawn ». Il y a beaucoup de choses ici, nous allons en ignorer la plupart. Mais vers la fin du script, il y a une ligne qui nous intéresse.
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
- Supprimez les // au début de cette ligne.
- Sauvegardez le script en tm_garde_os
- Fermez la fenêtre de scripts et allez sur le « OnUserDefined »
- Choisissez le script tm_garde_op
- Editez le, sauvegardez le en tm_guard_ud
- Changez éventuellement les commentaires pour refléter le fait qu’il aie changé de place.
- Sauvegardez le tout et lancez votre module.
Maintenant le garde réagit beaucoup plus normalement, et en plus, il fait toujours ce que l’on veut.
Bien, qu’avons nous fait ? En enlevant les commentaires « // » dans le script de « OnSpawn », nous avons dit au script que nous voulions que ce bout de code optionnel prévu par Bioware soit exécuté.
De façon schématique nous lui avons demandé. Quand tu fait ton script de « OnPerceive », fait en plus le nôtre.
Bien sur les plus malins d’entre vous demanderons… Et si je veux ajouter plusieurs comportement spéciaux, sur le « OnPerceive » et sur le « OnHeartbeat » par exemple ?
CÂ’est toujours faisable, mĂŞme si cela demande un tout petit peu plus de travail.
Si par exemple nous voulions que notre garde dise toutes les six secondes « Je m’ennuie » .
- Retournez dans le script de « OnSpawn » de votre garde et enlevez le commentaire devant le « OnHeartbeat ».
- Remarquez que les lignes « OnPerceive » et « OnHeartbeat » ont chacune un numéro d’associé. 1002 pour le « OnPerception » et 1001 pour le « OnHeartbeat ».
- Sauvegardez votre script en tm_ennui_os.
- Modifiez votre script de « OnUserDefined » comme suit et sauvegardez le en tm_ennui_ud.
// « OnUserDefined » Script : tm_bored_ud
// Appele par les scripts OnHeartbeat et OnPerception
//
// Le npc se plaint de sÂ’ennuyer toutes les six secondes
// et salue un pc des quÂ’il le voit.
//
int nAppelePar = GetUserDefinedEventNumber();
void main()
{
switch(nAppelePar)
{
case 1001: // Appele par OnHeartbeat
ActionSpeakString("Je mÂ’ennui.");
break;
//
case 1002: // Appele par OnPerception
object oSeen = GetLastPerceived();
if (GetIsPC(oSeen) && GetLastPerceptionSeen())
ActionPlayAnimation(ANIMATION_FIREFORGET_BOW);
break;
}
}
Questions / RĂ©ponsesÂ…
QuÂ’est ce que le GetUserDefinedEventNumber?
C’est exactement le nombre auquel je vous ai demandé de prêter attention un peu plus haut. Bioware a bien fait les choses. Non seulement chaque événement peut appeler le script « UserDefined » mais en plus, chacun lui passe un paramètre différent.
Et la commande « switch » ?
Je pourrai vous en parler pendant des pages et des pages… qu’il suffise de dire que cette commande prend une constante en paramètre et fait « sauter » le script jusqu'à ce nombre. Le script continue alors de s’exécuter jusqu'à ce qu’il rencontre la commande « break ».
Donc si notre nAppelePar vaut 1001, le script va rechercher la ligne « Case 1001: »
Quand j’écris des scripts « UserDefined » je me sert toujours de la commande « switch ». Même si j’en ai qu’un seul. Cela me permet plus tard, d’en rajouter de façon simple et rapide.
Ehhh tu as oublié des { et des } avec ton if ?
EuhhÂ… non ;)
Quand il n’y a qu’une seule commande attachée au « if », les { et les } ne sont pas obligatoires. Dans ce cas, le script est plus propre sans.
VoilĂ pour aujourdÂ’huiÂ…
Amaranthe.
Par gaeriel le 9/7/2002 Ă 23:08:55 (#1783549)
Continue comme ca, je suis sûir que tu aides plein de nb ;)
Au fait, c'est quoi le ActionPlayAnimation(ANIMATION_FIREFORGET_BOW);
C'est pour dire bonjour ??? Vu le nom, oh et puis je sais pas moi :p
Par John Hawkmoon le 10/7/2002 Ă 4:00:01 (#1784470)
Par adol le 11/7/2002 Ă 1:52:22 (#1789325)
Par drclick le 22/10/2002 Ă 23:52:48 (#2386598)
Je suis en train de faire les tuto et j'en suis a la lecon 4 et y a un truc que je ne comprends pas !
// « OnUserDefined » Script : tm_bored_ud
// Appele par les scripts OnHeartbeat et OnPerception
//
// Le npc se plaint de sÂ’ennuyer toutes les six secondes
// et salue un pc des quÂ’il le voit.
//
int nAppelePar = GetUserDefinedEventNumber();
void main()
{
switch(nAppelePar)
{
case 1001: // Appele par OnHeartbeat
ActionSpeakString("Je mÂ’ennui.");
break;
//
case 1002: // Appele par OnPerception
object oSeen = GetLastPerceived();
if (GetIsPC(oSeen) && GetLastPerceptionSeen())
ActionPlayAnimation(ANIMATION_FIREFORGET_BOW);
break;
}
}
Quand je teste ca je m'approche de mon mec et il ne fait rien alors qu'il devrait dire je m'ennuie si j'ai bien compris le script
case 1001: // Appele par OnHeartbeat
ActionSpeakString("Je mÂ’ennui.");
break;
Et des qu'il me dois me dire "Bien le bonjour, messire et me faire la reverence !!
case 1002: // Appele par OnPerception
object oSeen = GetLastPerceived();
if (GetIsPC(oSeen) && GetLastPerceptionSeen())
ActionPlayAnimation(ANIMATION_FIREFORGET_BOW);
break;
Alors que des qu'il me vois il me dit bien le bonjourmessire vu que j'ai l'anneau et apres il dit je m'ennuie en faisant la reverence tt les 6 sec !!
Ya un pb la !!
Autre chose, je ne comprends pas la fonction GetUserDefinedEventNumber() ?? Qui peut m'aider ??
Autre chose, j'ai lu dans le tuto que le script se "déroulé" jusqu'a ce qu'il rencontre l'instruction BREAK alors dans le cas du script ci dessous il en devrait pas faire la deuxieme case 1002:
case 1001: // Appele par OnHeartbeat
ActionSpeakString("Je mÂ’ennui.");
break;
Qq'un peut m'expliquer tt ca car je deteste faire un truc qui ne m'arche et ne pas savoir pq !!
Merci d'avance ;)
JOL Archives 1.0.1
@ JOL / JeuxOnLine