neverwinter nights: intro to the toolset - part 1sandrine.fabrice1.free.fr/toolsetintro.doc  ·...

228
Introduction au Toolset NdT: Certains termes sont volontairement gardés en anglais pour rester cohérent avec l'Aurora Toolset qui est en anglais. Quelques termes a connaitre Module: L'aventure en entier que vous avez créée. Contient toutes les locations (localisations), areas (zones), creatures (créatures) que vous avez inclus dans votre aventure. Area (Zone): Un lieu spécifique dans votre module tel qu'une auberge, un château à l'ambiance malsaine ou des grottes souterraines par exemple. NPC (PNJ): Non-Playing Character (Personnage Non Joueur). Tous personnage qui n'est pas contrôlé par un joueur: marchands, bandits, gamins des rues etc. PC (PJ): Player Character (Personnage Joueur). Un personnage qui est un contrôlé par un joueur réel dans votre aventure Créateur de Module: C'est vous. Si vous faites un module avec le Toolset, vous êtes officiellement un Créateur de Module. DM (MD): Dungeon Master (Maître du Donjon); La personne qui contrôle la partie et toutes choses s'y trouvant. Le DM est différent du Créateur du Module. Le Créateur du Module fabrique le module alors que le DM le contrôle lorsque les joueurs jouent le module. Bien sûr le Créateur du Module et le DM peuvent être la même personne – vous faites un module et ensuite vous le faites jouer à des joueurs. Palette: Le mot palette est utilisé pour décrire la partie de l'interface où se trouve tout ce que vous pouvez ajouter ou 'peindre' dans une area. Par exemple, dans le Toolset, vous avez une liste, située à un endroit spécifique de l'écran, des monstres que vous pouvez placer dans les areas de votre module ; Ceci est appelé la Palette de monstres. Pour ajoutez un monstre à votre module, vous le sélectionneriez depuis la Palette. Tile (Tuile): Le plus petit élément d'un Tileset qui peut être peint dans une area. Par exemple, l'auberge (inn) est un tile particulier à l'intérieur du Rural Tileset qui peut être peint dans votre area rurale. Tileset (Ensemble de Tuiles): Un groupe de tiles qui correspondent à un thème particulier. Par exemple, le Forest Tileset (Tileset Forêt) possèdent des tiles d'arbres, de ruines en pierre, une source, del l'eau, un campement, etc. qui pourrait tous être trouvés dans une forêt.

Upload: hanhi

Post on 12-Sep-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Introduction au ToolsetNdT: Certains termes sont volontairement gardés en anglais pour rester cohérent avec l'Aurora Toolset qui est en anglais.

Quelques termes a connaitre

Module: L'aventure en entier que vous avez créée. Contient toutes les locations (localisations), areas (zones), creatures (créatures) que vous avez inclus dans votre aventure.

Area (Zone): Un lieu spécifique dans votre module tel qu'une auberge, un château à l'ambiance malsaine ou des grottes souterraines par exemple.

NPC (PNJ): Non-Playing Character (Personnage Non Joueur). Tous personnage qui n'est pas contrôlé par un joueur: marchands, bandits, gamins des rues etc.

PC (PJ): Player Character (Personnage Joueur). Un personnage qui est un contrôlé par un joueur réel dans votre aventure

Créateur de Module: C'est vous. Si vous faites un module avec le Toolset, vous êtes officiellement un Créateur de Module.

DM (MD): Dungeon Master (Maître du Donjon); La personne qui contrôle la partie et toutes choses s'y trouvant. Le DM est différent du Créateur du Module. Le Créateur du Module fabrique le module alors que le DM le contrôle lorsque les joueurs jouent le module. Bien sûr le Créateur du Module et le DM peuvent être la même personne – vous faites un module et ensuite vous le faites jouer à des joueurs.

Palette: Le mot palette est utilisé pour décrire la partie de l'interface où se trouve tout ce que vous pouvez ajouter ou 'peindre' dans une area. Par exemple, dans le Toolset, vous avez une liste, située à un endroit spécifique de l'écran, des monstres que vous pouvez placer dans les areas de votre module ; Ceci est appelé la Palette de monstres. Pour ajoutez un monstre à votre module, vous le sélectionneriez depuis la Palette.

Tile (Tuile): Le plus petit élément d'un Tileset qui peut être peint dans une area. Par exemple, l'auberge (inn) est un tile particulier à l'intérieur du Rural Tileset qui peut être peint dans votre area rurale.

Tileset (Ensemble de Tuiles): Un groupe de tiles qui correspondent à un thème particulier. Par exemple, le Forest Tileset (Tileset Forêt) possèdent des tiles d'arbres, de ruines en pierre, une source, del l'eau, un campement, etc. qui pourrait tous être trouvés dans une forêt.

Pour debuter1. Cliquez sur le bouton Toolset au démarrage de Neverwinter Nights pour entrer dans le Toolset. La première fois que vous ouvrez le Toolset, un menu de bienvenue est lancé qui vous permet de choisir entre 'create new module' (créer un nouveau module), 'open an existing module' (ouvrir un module existant), ou 'start normally' (démarrer normalement). Choisissez de créer un nouveau module, ce qui lance le 'Module Wzard'. Nommez votre module à ce moment. Souvenez vous que ce n'est pas pour une area spécifique (comme 'L'Auberge') mais pour l'aventure dans sa totalité, du début à la fin (comme 'Assaut sur les Cavernes de la Destruction'). Ensuite, sélectionnez le 'Area Wizard', car tout module nécessite au moins une area.

2. Vous devez sélectionner quel Tileset vous souhaitez utiliser pour cette première area. Pour notre module, nous choisirons le 'City Interior' (Intérieur urbain) car je veux que mes aventuriers commencent le module dans une taverne ou une auberge en rase campagne.

3. Quelle taille souhaitez-vous donner à votre area ? Chaque case dans le Toolset est une zone de 10x10 mètres. Vous pouvez faire une area de 32 cases sur 32. Vous pouvez aussi faire une area ayant pour taille

Page 2: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

n'importe quelle combinaison de cette taille, par exemple 4 cases sur 20. La seule limite est 32 cases sur un côté.

NdT: Ouch même en anglais je ne trouve pas cela très clair. Pour résumer, une case dans le Toolset représente 10 mètre sur 10 dans le jeu. Une area peut avoir n'importe quelle dimension comprise entre 2x2 cases et 32x32 cases. Notez qu'une area ne nécessite pas d'être carré et vous pouvez très bien faire des areas de 20x4 cases par exemple.

4. Il y a quatre parties principales dans le Toolset:A. La Barre d'Outil – Liste de commandes et de préférencesB. La Palette – Contient tout ce que vous pouvez placer dans

votre module.C. Le Contenu du Module – Une liste ordonnée de tout le

contenu que vous avez déjà placé dans le moduleD. Affichage de l'Area – Où vous pouvez réaliser la majeure

partie du travail sur votre module

Construire la base5. Pour rendre cette area plus intéressante, vous devez peindre des Tiles speciafiques pour en faire une zone que les joueurs peuvent explorer. De plus, notez que la Start Location (le Point de Départ) a été automatiquement placée. Lorsque vos joueurs lancent ce module, il apparaîtront aux abords de cette Start Location.

6. Au niveau de la Palette, vous remarquerez deux séries de boutons. Le bouton vert en haut à droite est le bouton pour 'Peindre le Terrain' et celui en haut à gauche est celui pour 'Peindre la Start Location'. Ce sont les deux choses minimales que vous devez inclure à votre module. Vous devez avoir une area d'un type de terrain où les joueur peuvent vadrouiller et vous devez placer flèche cette Start Location quelquepart où les joueurs peuvent se tenir.

7. Peignez un peu de terrain pour votre première area. Vous remarquerez, dans les sections de la Palette, une large variété de tiles individuels à utiliser pour votre area. Ces tiles diffèrent d'un Tileset à un autre. Nous utilisons actuellement le Tilset City Interior (Interieur urbain), nous pourrions donc avoir des tiles comme Kitchen (Cuisine), Living Room (Salon), Barn (Grange) et ainsi de suite. Peignez quelques tiles pour donner un peu de corps à votre area.

Astuce: Le Toolset peut "cacher" la limite d'une area en mettant des tiles se répétant indéfiniment à perte de vue. Cependant, ceci peut être relativement choquant pour un joueur. Il est recommandé de mettre des tiles qu'un joueur ne peut pas traverser comme des murs, de vaste étendue d'eau, des précipices, ou autre selon ce qui est disponible selon le Tileset que vous utilisez. Avec ces "bords" en place, votre area aura une bien meilleure apparence.

8. Jetez un œil aux différents tiles pour déterminer quel type de choses vous souhaiteriez placer dans votre area. Nous sommes en train de faire l'intérieur d'une auberge, je pourrais donc mettre Inn (Auberge), Inn Room (Chambre d'auberge), Kitchen (Cuisine) etc. en fonction de la taille que je souhaite attribuer à mon auberge. Vous remarquerez que lorsque vous mettez une pièce, quelques décors supplémentaire viennent avec (tables, torches, tapis, etc.). Vous pouvez faire un clique droit lorsqu'un tile est "illuminé" (comprenez sélectionné dans la partie d'affichage de l'area) pour passer en revue les différentes apparences de ce tile.

9. Comment puis-je faire effectuer une rotation à un tile ? Faites un clique gauche sur ce que vous souhaitez utilisez (disons le tile Kitchen) dans la Palette, vous remarquerez une image fantôme (translucide) du tile

Page 3: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

attaché au pointeur de votre souris. Quand vous avez trouvé un endroit où vous pouvez peindre ce tile (vous verrez apparaître une case verte autour du tile) faites un clique droit sur le tile et il effectuera une rotation de 90 degrés. Lorsque vous avez trouvé l'orientation qui vous convient, faites un clique gauche et le tile sera placé.

10. Vous noterez l'existence d'une possibilité spéciale avec certains Tilesets appelée Raise/Lower (Monter/Baisser). Ceci vous permet de surélever certaines parties du terrain que vous avez créé pour faire des collines ou des vallées.

Astuce: Les tiles ont été fabriqués de façon à se côtoyer harmonieusement. Si vous souhaitez utilisé un tile spécifique et que le Toolset montre un case rouge, c'est parce que ce tile en particulier n'est pas prévu pour être placé à cet endroit précis. Essayez en faisant effectuer des rotations au tile ou en en utilisant un autre.

Astuce: Si vous faites un clique droit sur un tile particulier, cela fera apparaître le menu Properties (Propriétés) (NdT: en fait il faut faire un clique droit ET sélectionner properties). Ce menu vous permet de changer manuellement l'éclairage de cet endroit en particulier. Chaque tile a un Main Lightning (Eclairage Principal) et certains ont des Source Lightning (Source d'Eclairage) (comme une torche), vous pouvez changez a couleur des deux. Certains tiles ont des parties animées, comme le Smithy (Forge) du City Interior, qui peuvent être off (désactivées) ou on (activées).

Ajouter du contenu11. Maintenant que nous avons un peu d'espace créé dans notre auberge, nous devons meubler le lieu – jetons un coup d'œil au reste des boutons de la Palette.

De la gauche vers la droite, il y a:

Creatures: Une longue liste de tous les monstres et NPCs de NWN. Cette liste est divisée en deux sections: Standard, qui sont disponibles pour tous les modules, et Custom (Personnalisé, ou Fait-Maison) qui sont des Creatures Standard qui ont été altérées par vous-même pour votre module actuel.

Doors (Portes): Les Portes sont spéciales dans le sens où elles peuvent être des points d'Area Transition (Changement de zone). Vous trouverez plus de détails sur les Portes plus bas.

Encounters (Rencontres): Vous permet de placer des rencontres échelonnable déclenchées par le passage des joueurs. Par exemple une rencontre pourrait être n'importe quoi d'un bandit solitaire à un troupeau de cochons enragés.

Items (Objets): Armures, Objets de Quête, Armes, etc.

Placeable Objects(Objets Plaçables): Tout des lits et catapultes aux flammes et autres panneaux indicateurs. Ils sont divisés en catégorie comme Military (Militaire), Battle Field (Champ de Bataille), Parks and Nature (Parcs et Nature) et ainsi de suite.

Sound Objects (Objets Sonores): Vous permet de placer des sons comme des objets dans votre area.

Merchants (Marchands): Ceci est quelque chose de vraiment particulier dans NWN qui demande à avoir sa propre catégorie. Il s'agit de longue liste de différentes sorte de marchands comme General Store (Magasin Général) ou Temple Store (Magasin du Temple).

Triggers (Déclencheurs): Peuvent être des Area Transitions, des Traps (Pièges), ou des Generic Triggers (Déclencheur Générique)

Waypoints ( ): Marquent les lieux importants d'une areas, comme les deux points entre lesquels se déplace un garde lors de ses rondes, le point exact où vous apparaissez lorsque vous traversez un portail.

Page 4: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

12. Se familiarisez avec le nombre affolant de choses que vous pouvez placer dans votre module prend un certain temps. Chercher parmi des listes et des listes de choses est l'activité qui demande le plus de temps dans l'utilisation du Toolset jusqu'à ce que vous soyez familiarisé avec ce dont vous avez besoin.

Un mot sur les monstres13. Les monstres sont la première chose sur laquelle tout vaillant aventurier va focaliser son attention. Le choix de Creatures que vous pouvez peindre dans votre module est vaste, aussi, au début, prenez votre temps pour explorer les différentes possibilités. Lorsque vous trouvez une créature qui vous convient, vous avez la possibilité de faire un clique droit sur son nom dans la palette, en choisissant 'Edit Copy', vous ferez apparaître une fenêtre qui contient toutes les informations sur cette créature en particulier. Si vous modifiez l'un des paramètres, cela créera une copie une version personnalisée de la créature qui sera automatiquement ajoutée à la section 'Custom' de la Palette de Creatures. Pour mon auberge, je pense que je vais ajouter quelques poulets non menaçants et un chien.

14. Lorsque vous placez une Creature quelque part dans votre area, vous remarquerez qu'elle apparaît automatiquement dans la partie montrant le contenu du Module, sur le côté gauche du Toolset.

Vue d'ensemble15. Maintenant que nous avons un peu rempli notre auberge, jetons un coup d'oeil aux options de la Barre d'outil.

Edit: (Edition): Vous permet de faire d'importants changements globaux à votre module ou à une area particulière que vous avez ouverte. Exemples: Resize (Redimensionner), Rotate (Rotation), Area Properties (Propriétés de l'Area), ou Module Properties (Propriétés du Module).

View (Affichage): Permet à l'utilisateur de changer ce qu'il voit dans la partie principale du Toolset. Exemples – Enlever les Items, les Triggers,...

Environnement: Changer certains aspects visuels de l'area sur laquelle vous êtes en train de travailler. Exemple – Activer ou Désactiver le Fog (Brouillard) pendant que vous travaillez.

Build (Construction): Donne des détails sur l'area actuelle ou le module.

Tools (Outils): Contient les Conversation, Faction, Script et Journal Editors

Wizards: Contient une série de Wizards pour vous aider dans la création du contenu du jeu. Exemple – Encounter Wizard, Door Wizard et Item Wizard

Help (Aide): Contient un lien vers la partie Support du Site de la Communauté NWN ainsi que des informations sur la version actuelle du Toolset.

Astuce: Tout en bas du menu Edit – 'Area Porperties' ouvre une fenêtre qui vous permet de changer certains paramètres visuels comme les cycles jour/nuit, la couleur des éclairages, du brouillard etc. De plus elle contient une liste paramétrages tout prêts tels que Interior Dark (Intérieur Sombre) ou Exterior Raining (Extérieur Pluvieux).

Page 5: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Astuce: Sous 'Environnement' – Vous verrez 'Fog'. Ceci permet d'activer ou de désactiver le brouillard pendant que vous travaillez sur une area. Un brouillard épais peut rendre difficile le travail sur le module. Vous verrez aussi 'Use Area Lighting' qui active ou désactive les éclairages que vous avez paramétrez, ce qui rend le travail sur un area plus facile aussi.

De nouveaux lieux a explorer16. Il y un monde entier au dehors, grand et dangereux, et l'un des éléments clé que vous devez comprendre est l'Area Transition (Changement de zone). A moins que le module entier n'ait lieu dans l'espace confiné de l'auberge, vous allez devoir inclure plusieurs areas que les joueurs pourront explorer.

17. Faites un clique droit sur le mot 'Area' dans le coin en haut à gauche, puis cliquez sur 'New'. Ceci vous amène au même Area Wizard que vous avez déjà utilisé une fois lorsque vous avez commencé. Nommez votre area et choisissez quel nouveau tileset vous souhaitez utiliser. Comme nous souhaitons avoir notre auberge en pleine campagne rustique, nous choisissons Rural comme Tileset.

18. Je fais une jolie area en peignant les Tiles, Placeable Objects, Creatures et ainsi de suite jusqu'à ce que j'ai une area intéressante à explorer pour les joueurs. L'une des choses que je ne dois pas oublié de peindre est une auberge. Vous remarquerez que l'auberge a un palier ouvert qui peut être utilisé pour entrer à l'intérieur.

Astuce: Rappelez vous de 'sceller' les bords de votre carte rural avec des éléments infranchissables, come de l'eau, des falaises et ainsi de suite pour que votre area n'ait pas l'air inachevée.

Faire la connexion19. Toujours dans notre area rurale, je clique sur l'icône en forme de porte de la Palette. Je vois que je peux sélectionner des portes spécifiques à ce tileset (Tileset Specific) ou que je peux choisir parmi des portes universelles (Universal) qui sont les mêmes quel que soit le Tileset que j'utilise. Je clique sur une porte et nous voyons cette porte en bois en rotation attachée au pointeur de ma souris.

20. Les portes sont spéciales parce que vous ne pouvez pas les placer n'importe où. Les portes ne peuvent être placées que là où un 'crochet' a été placé. Ces crochets sont des lieux comme les pas de portes, les entrées de cavernes et ainsi de suite. Vous ne pouvez pas décider de la place de ces crochets – ils sont des parties spécifiques de certains tiles. Dans notre exemple, nous avons besoin d'une porte à l'entrée de notre auberge, je clique sur l'entrée et voilà, une porte apparaît.

21. Si vous faites un clique droit sur votre porte (et choisissez Poperties), vous verrez plusieurs propriétés concernant cette porte (open (ouverte) ou locked(fermée à clé), hardness (résistance), trapped (piégée), etc.). Celle qui est importante pour les Area Trasitions (Changements de zone) est sous l'onglet Basic. Vous verrez 'Tag'. Un Tag, ou ScriptTag, est le nom qui rend cette porte différente de toutes les autres portes que vous placerez dans votre module. Pensez à un Tag qui vous aidera à vous souvenir de ce qu'est cette porte. Pour notre exemple, Je vais utiliser le Tag "PorteVersAubergeRural", ainsi je pourrai me rappeler de ce qu'est cette porte d'un seul coup d'œil.

Page 6: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

22. Maintenant que j'ai nommé cette porte, je dois retourner à l'intérieur de mon auberge, et y ajouter de la même façon une porte. Je double-clique sur l'area de l'auberge que j'ai créée en premier (allez sur le côté gauche de l'écran et trouvez votre première area), puis je clique sur l'icône en forme de porte et ajoute une porte à l'entrée. Ensuite, nous faisons un clique droit sur la porte et ajoutons le Tag "InterieurAubergeRural", de façon à pouvoir l'identifier facilement.

23. Restez dans le menu des propriétés de la porte et cliqués sur 'Area Transition', puis sur le bouton 'Setup Area Transition'. Vous verrez une grille rouge qui montre toutes les portes que vous avez placées dans cette area. Nous devons choisir notre area rurale dans le menu déroulant 'Target Area'. Vous remarquerez que notre porte " PorteVersAubergeRural" est listée. Cliquez dessus et selectionnez 'Both Way' (dans les deux sens) dans la partie 'Connection Type' (type de connexion).et bam! Vous venez juste de configurer votre Area Transition. Maintenant les joueurs pourront passer d'une area à une autre dans votre module.

Parler librement24. Pour ajouter de la conversation à vos NPCs, vous allez devoir utiliser le Conversation Editor, que vous pouvez lancer depuis la Section 'Tools' de la barre d'outil. Ceci fera apparaître une nouvelle fenêtre.

25. Pour commencer votre dialogue, vous devez cliquer sur le bouton 'Add', situé sur le côté gauche. Une plus petite fenêtre apparaîtra, ayant pour titre 'Enter the NPC Greeting' (Entrez le message de salutations du NPC). Tapez dans cette fenêtre ce que vous voulez que le NPC dise en premier.

26. Après avoir cliqué sur 'Ok', vous remarquerez que votre ligne de dialogue a été ajoutée à la fenêtre en rouge. Vous pouvez maintenant y mettre une réponse qui serait prononcée par le joueur. Sélectionnez la ligne de dialogue et appuyez à nouveau sur le bouton 'Add'.

27. Pour ajouter un autre choix de dialogue pour le joueur, re-sélectionnez simplement la ligne de salutation initiale et cliquez sur 'Add'.

28. Vous pouvez maintenant faire répondre votre NPC différemment pour chaque option du dialogue que vous avez écrite. Pour cela, vous sélectionnez le dialogue du PC et cliquez sur 'Add'.

29. Maintenant, vous devez attacher cet arbre de dialogue particulièrement réussi à un NPC en particulier. Lorsque vous quittez le Conversation Editor; il vous est demandé de donner un nom à votre arbre de dialogue. Faites un clique droit sur un NPC à qui vous voulez donner cette conversation et faites apparaître le menu de propriété. En bas de la fenêtre, à droit du portrait du NPC, il y a un champ nommé 'Conversation'. Cliquez sur la flèche du menu déroulant et trouvez votre dialogue en cherchant dans la liste le nom que vous lui avait donné. C'est tout! Vous avez maintenant un NPC avec un dialogue. J'ai attaché mon arbre de conversation à l'aubergiste, pour qu'il ait quelque chose à dire au PCs lorsqu'ils arriveront.

ConclusionCeci était la verion la plus dénudée, la plus elliptique, la plus condensée, la plus résumée du Reader's Digest sur le Toolset. Evidemment, il existe environ 1000 boutons supplémentaire ayant chacun différentes fonctions à connaître. Les possibilités d'utilisation du Toolset sont sans fin, et vous pouvez vous attendre à voir

Page 7: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

aparaître de nombreux, de très nombreux documents d'aide sur le site de la Communauté de Neverwinter Nights de Bioware dans un avenir proche.

Construction de moduleNdT: Certain mots ont volontairement été conservé en anglais afin de rester cohérent avec le logiciel Toolset qui est en anglais.

Sommaire de l’histoire

Une tribu de gobelins dirigés par Barash l’effroyable se regroupe pour lancer une guerre à l’encontre du peuple de Hyatt, un petit royaume géré par le roi Percy le juste. La principale source de fer du royaume utilisé pour la fabrication des armes est la mine de Fernesk proche de la zone rurale de Fern. Chaque semaine, une caravane transportant le minerai quitte Fern pour le Château de Hyatt, au sud,  et reviens avec les fournitures nécessaires au village. La survie de la communauté dépend de cette caravane et il est fréquent que des mercenaires soient engagés pour l’escorter.

Le premier objectif de Barash est de s’emparer de la mine de Fernesk. Cette action lui permettra de couper le château de Hyatt de sa source d’approvisionnement de fer et, dans le même temps, augmentera ses ressources. Barash envoi Gnashgab, un de ses plus dévoué shamans, s’emparer de la mine et de capturer les mineurs pour les utiliser comme esclaves. Sous le couvert de la nuit, Gnashgab et ses guerriers envahissent la mine pendant qu’elle est inoccupée et préparent une embuscade. L’équipe qui entra dans la mine le jour suivant tombèrent dans le piège tendu par les gobelins. Il travaillent maintenant comme esclaves pour le compte des gobelins, incapable de s’enfuir et de prévenir le village du danger. Les jours ont passé depuis que l’équipe fut entrée dans la mine et le départ de la prochaine caravane approche. Le peuple de Fern est désespéré.

Inconnu des habitants de la ville, Barash a un allié. Veran, un marchand local et le manager de la mine, travaille secrètement pour Barash afin de lui fournir des informations et du matériel. Sous l’apparence de former une équipe de secours, Veran envoie en réalité des nouveaux esclaves à Gnashgab afin de remplacer ceux qui sont morts ou qui furent tués. Malheureusement pour Veran, le peuple de Fern a trop peur d’entrer dans la mine.

Au milieu de ce chaos arrivent les joueurs, mercenaires dont les services ont été loués afin d’escorter la prochaine caravane à destination du château de Hyatt. Quand les joueurs entrent dans Fern, ils découvrent que la caravanne est reportée indéfiniment jusqu’à ce que le mystère de la mine de Fern soit résolu. Le maire du village, Falstadd, leur demande de se joindre à l’équipe de secours formée par Veran pour aider à trouver son fils Jacen qui faisait parti de l’équipe malchanceuse. Si les joueurs acceptent d’aider, Falstadd leur promet une récompense.

Pendant cette aventure, les joueurs découvrent la mine infestée de gobelins, les survivants de l’équipe de mineurs travaillant comme esclaves et Jacen, une des nombreuse victimes de cette attaque.

Fern, le village frontiere

Introduction

Ce tutorial présente les “Wizards” permettant de créer de nouveaux modules, de nouvelles zones et comment dessiner le terrain.

Objectif

Créer le village frontière de Fern, le point de départ de ce module.

Page 8: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Tutorial

Création automatique de nouveau module : New Module Wizard

Pour créer un nouveau module, suivez ces étapes :

1. Démarrer le logiciel “BioWare Aurora Neverwinter Nights Toolset”. Sélectionnez "Create a New Module" dans la fenêtre de bienvenue et appuyez sur "OK". Si la fenêtre de bienvenue n’apparaît pas, sélectionnez l’option "New" dans le menu "File".

2. Le “New Module wizard” va s’ouvrir (un "wizard" est un outil de génération automatique). Appuyez sur "Next" pour commencer.

3. Appelez le module "tutorial" et cliquez sur "Next".

4. Cliquez sur "Area Wizard". Les zones (Areas) sont là où l’action du module et l’histoire ont lieu. Un module doit avoir au minimum une zone pour travailler, généralement plusieurs.

5. Appelez la zone "Fern" et sélectionnez le “tileset” "Rural", puis cliquez sur "Next". Les zones sont construites avec des cases (tile) de 10 mètres par 10 mètres. Les cases sont regroupées par thèmes comme les extérieurs d’une ville (City Exterior), un donjon (Dungeon) ou une zone rurale (Rural). Ces thèmes sont appelés “tilesets” (traduction groupe de cases).

6. Acceptez la taille de la zone par défaut : 8 cases par 8 cases (tiles). Appuyez sur "Next" et sur "Finish". Le toolset crée une zone et retourne au wizard “New Module Wizard”.

7. Cliquez sur "Next" et sur "Finish" pour sortir du wizard.

8. Sauvegardez le module et sortez du toolset.

Regardez le module dans le jeu en suivant ces étapes :

1. Lancer le jeu Neverwinter Nights. Sur la fenêtre principale cliquez sur "New".

2. Puis sur "Other Modules..."

3. Sélectionnez le module "tutorial" et cliquez sur "Load".

4. Choisissez un personnage (ou créez en un).

5. Enfin, appuyez sur "Play".

Après avoir exploré la zone quelques minutes, sortez du jeu. Retournez sur le toolset et chargez le module "tutorial".

Contrôle de la camera

Le panneau "Module Contents" sur la partie gauche de la fenêtre principale affiche les zones (areas), les conversations (conversations) et les scripts (scripts) contenus à l’intérieur du module chargé. Ouvrez la liste des zones; le module "tutorial" contient uniquement une zone : Fern. Double cliquez sur le nom de la zone ou sélectionnez "View Area" à partir de son menu contextuel pour l’afficher dans le panneau d’affichage des zones : "Area Display".

Toutes les zones vont apparaître au début avec une vue de haut. Remarquez la barre d’outil permettant le contrôle de la caméra en bas du panneau d’affichage de la zone. Le premier des quatre boutons déplace la caméra (NDT: doute sur la traduction), le second fait tourner la caméra et les deux suivant contrôlent le zoom. Deux autres boutons vous permettent de contrôler l’orientation des objets que vous avez disposé dans la zone et seront décris plus tard.

Page 9: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

La camera peut être aussi contrôlée de la manière suivante :

SourisClavier numérique

Déplacement [Ctrl] + bouton souris gauche enfoncé 2 / 8 et 4 / 6Rotation 1. [Ctrl] + bouton souris droit enfoncé.

2. Bouton du milieu enfoncé1 / 3 et 7 / 9

Zoom Roulette de souris + / -Récentrer 5

Table 1.1 Contrôle de la camera

Dessiner le terrain

On trouve dans la partie droite de la fenêtre principale un ensemble de boutons permettant d’accéder à des palettes. Ces palettes contiennent les cases caractéristiques (feature), les cases de groupe (group) et les cases terrains (terrain) ainsi que les prototypes (blueprint) des objects disponible dans le jeu et qui peuvent être disposé sur la zone en cours. Il y a plusieurs palettes, une par chaque type d’object de jeu. Les prototypes (blueprint) de chaque palette sont organisés par catégories afin de les rendre plus facile à trouver.

Pour dessiner un terrain :

1. La palette Terrain est en haut à gauche de la liste des boutons de palettes (NdT: les boutons de palettes sont eux en haut à droite de la fenêtre principale). Cliquez sur le bouton de palette "Terrain" pour l’ouvrir.

2. Ouvrez la liste des terrains. Sélectionnez l’outil permettant de creuser / surélever "Raise / Lower Terrain". Cliquez avec le bouton gauche sur le coin nord-est de la zone. Remarquez que cette portion de la zone a été surélevée. Cliquez avec le bouton droit au même endroit et cette portion de zone s’enfoncera.

3. Sélectionnez l’auberge "Inn" à partir de la liste "Groups". L’auberge est un groupe de cases ce qui fera qu’un ensemble de cases seront dessinées en même temps pour former une grande structure. Lorsque l’auberge est sélectionnée, son image fantôme apparaît, attaché à la souris. Cette image indique l’orientation que le groupe va avoir si vous le dessinez et peut être changé par un clic sur le bouton droit. Chaque clique tourne l’image fantôme à 90 degrés. Dessinez l’auberge en cliquant sur le bouton gauche n’importe où dans la section en haut à droite de la zone.

Note: La dernière action peut être annulée en utilisant [Ctrl] + Z ou l’option "Undo" du menu "Edit" de manière répétitive. La dernière action annulée peut être ré appliquée en utilisant [Shift] + [Ctrl] + Z ou l’option "Redo" du menu "Edit".

4. Sélectionnez l’une des cases qui forment l’auberge. Remarquez que les deux cases qui forment le groupe sont maintenant sélectionnées. Un groupe de cases ne peut être sélectionné indépendamment. Supprimez l’auberge de la zone en utilisant la touche [Delete] ou en utilisant l’outil de suppression "Erase tool" sur l’auberge. Cet outil est accessible à partir de la palette terrain.

5. Redessinez l’auberge en utilisant [Ctrl] + Z, en sélectionnant l’option "Undo" du menu "Edit" ou tout simplement en sélectionnant l’auberge dans la palette Terrain et en le dessinant à nouveau.

6. Sélectionnez la caverne "Cave" à partir de la liste des caractéristiques "Feature list" sur la palette terrain. Dessinez la caverne dans le coin nord est de la zone, changez son orientation pour que son entrée soit face au sud.

Note: Pour des raisons de performance, le toolset ne recalcule pas automatiquement l’ombre. Ca qui veut dire que l’ombre reste quelques soit les modifications de terrain ou d’objects apportés. Appuyez sur "F5" pour recalculer l’ombre et les effets de lumière.

Page 10: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Lieux de départ (Start Locations)

Quand un joueur démarre un module, le jeu va placer son personnage au lieu de départ du module. Par défaut, le point de départ est le centre de la première zone créé en utilisant le wizard "New Module wizard.

Pour changer ce lieu de départ, suivez ces étapes :

1. Cliquez sur le bouton "Paint Start Location" à l’extrême droite en haut de la liste des boutons de palettes.

2. Dessinez le dans un lieu approprié de la zone, proche de l’auberge par exemple.Note: Les lieux de départ sont un peu différent des autres terrains et objects de jeu. Il n’y a pas de palette a partir de laquelle on sélectionne le lieu de départ. Une fois que vous avez pressé le bouton, cliquez simplement sur le lieu où vous voulez que les joueurs démarrent.

3. Changez l’orientation dans laquelle le personnage du joueur apparaîtra en sélectionnant le lieu de départ dans la zone et en utilisant les boutons de rotation des objects sur la barre d’outil de la camera ou en utilisant [Shift] + bouton droit enfoncé.

Pour aller plus loin

Continuez d’ajouter d’autres terrains dans la zone. Peut être une route qui traverse le village, ou peut être que le village est proche d’un lac ou d’un océan. Souvenez vous de sauvegarder votre module régulièrement.

Pour voir votre module dans le jeu à tout moment, suivez les instructions qui ont été donnés précédemment.

Astuce: Pour copier un ensemble de cases connectées, sélectionnez le rectangle désiré et utilisez [Ctrl] + C ou l’option "Copy" à partir du menu "Edit". Pour coller l’ensemble dans la zone en cours ou dans une autre zone (à condition qu’elle utilise le même "tileset") utilisez [Ctrl] + V ou l’option "Paste" à partir du menu "Edit". Cela attachera les cases à votre souris de la même façon qu’un groupe de cases. Dessinez les alors dans votre zone là ou vous le souhaitez.

Passez au tutorial suivant quand vous avez terminé.

La mine de Fernesk

Introduction

Ce tutorial enrichit les connaissances de construction de terrain acquises sur le tutorial précédent et présente des nouvelles commandes de manipulation de zone. Dessiner et éditer des objets de jeu sont aussi couvert par le présent tutorial.

Objectif

Créer une zone représentant la mine de Fernesk et y placer des objets intéressants.

Tutorial

Une nouvelle zone (Area)

Créez une nouvelle zone qui vous servira à définir la mine envahie par Gnashgab et ses guerriers en suivant ces étapes :

1. Démarrez le Toolset et chargez le module "Tutorial".

Page 11: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Choisissez l'option "Area Wizard" à partir du menu "Wizards".

2. Nommez la zone "La mine de Fernesk ", choisissez le modèle de cases (tileset) "Mines and Caverns" et appuyez sur "Next".

3. La mine doit être petite, choisissez 5 cases de hauteur par 4 cases de largeur et cliquez sur "Next".

4. Assurez vous que la boite à cocher "Open Area in the Area Viewer" est sélectionnée et cliquez sur "Finish".

Astuce: Le Toolset utilise par défaut la lumière du jeu dans la zone. Mais cela peut être trop sombre pour pouvoir travailler correctement. Plusieurs commandes dans le menu "Environment" vous permettent d'activer ou de désactiver des fonctions graphiques qui vous rendront la visibilité meilleure dans votre phase de construction sans affecter la manière dont la zone apparaîtra aux joueurs. Par exemple, pour mettre une lumière très forte pendant que vous travaillez sur un module, cliquez sur "Environnement", désactiver la commande de brouillard et basculez la commande "Use Area Lighting" sur off.Note: Eloignez vous de la zone avec la fonction de zoom pour voir la totalité de la zone (area). Remarquez que la zone est en grande partie constituée de murs excepté un petit espace au centre. Ceci est du au fait que le terrain initial de ce "tileset" est de type "Wall" (mur) et requiert que la zone jouable soit "creusée" tout autour.

5. Sélectionnez "Wall" (mur) à partir de la liste des types de terrain et remplissez la région qui a été initialisé avec le type "Floor", de cette manière la totalité de la zone est maintenant recouverte de murs.

6. Sélectionnez la case (tile) "Exit 3" à partir de la liste des fonction (Feature list), orientez le de manière à ce que l'entrée soit face au nord et posez le dans le coin en bas à gauche ( ligne 0, colonne 1).

Note: Quand une zone (area) est chargée, la caméra est positionnée par défaut de manière à ce que le nord soit vers le haut de l'écran.Note: La barre d'état indique la position de la souris (x, y), la position sur la grille (ligne, colonne) et le nom de la ressource de la case où se trouve la souris.

7. Sélectionnez "Tracks" (ligne de chemin de fer) à partir de la liste de terrains et posez les jusqu'au bord gauche de la zone mais ne les faites pas aller jusqu'à la fin de la carte.

8. Sélectionnez "Mineshaft" à partir de la liste des fonctions (Feature list) et posez le à la ligne 3, colonne 2, près du centre de la zone, créant ainsi une pièce isolée avec une excavation au centre. Cette pièce sera connectée à la ligne de chemin de fer plus tard.

Manipulation avancée de zone

Comme résultat des modifications apportées à la zone causée par la précédente étape, la zone est maintenant pratiquement pleine. Dans cet état, ajouter de nouveaux éléments ou groupes sans altérer ce qui existe déjà serait extrêmement difficile. Heureusement, le toolset inclus une commande très spéciale dans le menu "Edit" : "Resize Area".

1. Sélectionnez la commande "Resize Area" à partir du menu "Edit".

2. Entrez les nouvelles dimensions de la zone : 8 cases de haut par 5 cases de large et appuyez sur "OK".

DANGER: Le Toolset ajoute et enlève des cases à partir de la ligne du haut et de la colonne de droite quand la zone est redimensionnée. Ce n'est normalement pas un problème si la zone est agrandie mais si la zone est réduite, les objets sur les lignes du haut et les colonnes de droite seront automatiquement supprimés.Astuce: La commande "Resize Area" peut être annulée en utilisant [Ctrl] + Z ou la commande "Undo".

3. Sélectionnez "Tracks" (voie de chemin de fer) à nouveau et disposez en le long du bord gauche de la zone mais ne n'allez pas jusqu'au bout de la carte.

4. Puis, dessinez un petit "Floor" (sol) proche du centre de la zone, au dessus du "MineShaft" et à droite des "Tracks".

Page 12: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

5. Connectez le "Mineshaft" avec les "Tracks" en utilisant un "Corridor". Faites le à nouveau pour connecter le "Floor" avec les "Tracks".

6. Enfin, dessinez un peu d'eau "Water" sur la droite et entre le "Mineshaft" et le "Floor".

Positionnez le lieu de départ du module proche de la sortie puis sauvegarder le module et fermez le Toolset. Chargez le module au sein du jeu et faites le tour de votre zone.

Objets de jeu (Game Objects)

La palette sur la partie droite de la fenêtre inclus tout les prototypes (blueprints) que vous pouvez positionner dans la zone. Un prototype (blueprint) est une ressource du jeu qui représente un objet qui est placé dans le jeu. Quand un prototype est dessiné dans une zone, une instance de ce prototype est créée à cet endroit.Note: Les palettes sont divisés par type de prototypes (blueprint) et sont organises par catégories. Chaque catégorie va afficher soit des sous-catégories soit des noms de prototypes. Une catégorie ne peut pas avoir à la fois des sous catégories et des prototypes au même niveau.Astuce: Utilisez la commande "Object Preview" disponible dans le menu "View" pour examiner les détails importants d'un prototype (blueprint) avant de le poser dans une zone.

Objets placables (Placeable Objects)

1. Démarrez le Toolset et chargez le module "tutorial".

2. Ouvrez la zone "Mine de Fernesk" en double cliquant sur le nom ou en sélectionnant "View Area" à partir de son menu contextuel dans le panneau "Module Contents" (contenu du module).

3. Ouvrez la palette des objets placables (Place-able Object) en appuyant le quatrième bouton à partir de la droite sur la colonne du bas de la barre des palette (le bouton ressemble à une table).

4. Sélectionnez une "Table" à partir de la catégorie "Miscellaneous Interior" (Intérieur divers) et posez là dans la zone, proche de la sortie.

Note: Une fois que la table est posée, elle apparaît dans la liste des objets placables en dessous de la zone dans le panneau "Module Contents" (NdT: à gauche de l'écran) Chaque instance dans le module est ainsi localisé par type dans la zone où il a été placé.Note: Utilisez les boutons "Rotate Object" (faire tourner les objets) sur la barre d'outil de la camera ou appuyez sur [Shift] + souris bouton droit enfoncé pour changer l'orientation de vos instances d'objets.

5. Sélectionnez une chaise "Chair" à partir de la même catégorie et positionnez quelques unes autour de la table.

Astuce: Pour poser plusieurs copies du même prototype (blueprint), maintenez la touché [Shift] enfoncé pendant que vous posez votre objet.

6. Posez quelques caisses à partir de la catégorie "Containers and Switches" (conteneurs et interrupteurs) autour de l'entrée et de l'excavation (mineshaft).

Astuce: Lorsqu'un object placable est posé ou sélectionné, une flèche en fil de fer apparaît pointant en direction où le joueur devra être pour utiliser cet objet. Assurez vous qu'aucun object placable avec lequel un joueur devra interagir n'a sa flèche pointant vers un mur ou tout type d'obstruction similaire.

7. Posez une torche sur pied "torch bracket" à partir de la catégorie "Miscellaneous" (divers) proche de l'entrée. Fixez l'état initial de cet objet sur "Activated" à partir de son menu contextuel. Ceci allumera la torche.

8. A la fin de la région "Floor" (sol), proche du coin en haut à droite de la zone, posez un autel "Altar" à partir de la catégorie "Miscellaneous Interior" et deux braseros "Brasiers" à partir de la catégorie "Miscellaneous".

9. A partir de la catégorie "Battlefield", ajouter quelques corps "Corpses" criblés de flèches "Arrow-Filled" et transpercés par une lance "Speared" près de l'entrée, de l'excavation (mineshaft) et de la zone "floor" en haut à droite.

Page 13: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

10. Finalement, placez le corps d'une victime de la peste "Plague Victim Corpse" sur l'autel (altar). Ce corps est celui de Jacen, le fils de Falstadd.

Astuce: Déplacer un objet placable qui a déjà été posé afin de le mettre au dessus d'un autre peut etre un peu énervant parce que l'objet peut tomber sur le sol et devenir partiellement dissimulé. Appuyez sur F5 pour rafraîchir la zone et faire que tout les objets s'ajustent proprement.

Contrôlez votre module à partir du jeu. Remarquez que les caisses peuvent contenir quelques trésors. Certains objets peuvent avoir des scripts qui leurs sont automatiquement assignés comme les trésors des caisses quand ils sont ouverts.

Rencontres (Encounters)

Une rencontre est un déclencheur (trigger) qui génère (spawn) des instances de créatures de sa liste de prototypes (blueprint) de créatures spécifiques en fonction de la puissance de la créature qui l'a activé. (NdT: Tout les développeurs utilisent le terme de trigger, je laisse désormais ce terme tel quel) La même rencontre qui génère uniquement une créature pour un personnage solitaire de bas niveau peut générer quatre créatures pour un groupe de personnages de bas niveau ou un personnage de haut niveau.

En général, il vaut mieux utiliser des rencontres pour des combats typiques que le joueur engage pendant un voyage ou une aventure. Cela réduit la charge au niveau du serveur et prends en compte le fait que l'auteur du module peut ne pas connaître le niveau exact du groupe de joueurs à l'avance. Seules les créatures nécessaires à faire avancer l'histoire(comme des donneurs d'actions ou des méchants) doivent être placés explicitement dans le module.

1. Démarrez le Toolset et chargez le module "tutorial".

2. Ouvrez la zone "Mine de Fernesk".

3. Ouvrez la palette rencontre "Encounter" en appuyant sur le troisième bouton à partir de la gauche sur la colonne du bas (il ressemble à une paire d'épées croisées entre elles).

4. Sélectionnez un groupe de gobelins "Goblin Group" à partir de la catégorie "Very Easy" (très facile).

5. Cette rencontre doit être un rectangle place en face de l'entrée de la mine. Dessinez la région (polygone) où les joueurs devront marcher pour activer la rencontre en plaçant des points à chaque coin du polygone. Pour fermer ce polygone, double cliquez sur le dernier point.

Note: Les rencontres sont plus efficaces lorsqu'elles sont placées sur des points stratégiques de la zone comme près des entrées, des portes et des ponts. Cela permet de s'assurer que les joueurs iront bien activer ces rencontres.

6. Sélectionnez la rencontre et choisissez "Properties" (propriétés) à partir de son menu contextuel pour ouvrir la fenêtre des propriétés d'une rencontre. Changez la difficulté de "Normal" à "Very Easy" (très simple), Affecter la valeur 2 au nombre minimum de créatures et appuyez sur "OK".

7. Sélectionnez la rencontre et faites un clic droit juste après le départ de la voie de chemin de fer (Tracks). Sélectionnez "Add Spawn Point" (ajout d'un point d'apparition) à partir de son menu contextuel pour placer un point d'apparition pour cette rencontre. Un point d'apparition "spawn point" dit à au système de rencontre de placer les créatures à cet endroit.

Note: Les points d'apparition apparaissent uniquement lorsque la rencontre est sélectionnée. La taille de la grosse flèche qui indique la position du point d'apparition peut être ajusté à partir des options.

8. Placez un autre rencontre de gobelins très facile similaire à celui décrit à l'étape 4, avant l'entrée de la pièce où se trouve l'excavation (mineshaft).

Contrôlez le module à partir du jeu. Cette fois, assurez vous que votre personnage est prêt à combattre !

Page 14: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Créatures

Une créature définit tout ce qui bouge. Cela inclus les joueurs (PCs), les personnages non-joueurs (NPCs) et les monstres (monsters).

1. Démarrez le Toolset et chargez le module "tutorial".

2. Ouvrez la zone "Mine de Fernesk".

3. Ouvrez la palette créatures en appuyant sur le premier bouton à partir de la gauche sur la colonne du bas (Il ressemble à une tête de monstre).

4. Sélectionnez le premier "Goblin Shaman" dans la catégorie "Monsters" | "Humanoid" | "Goblin" et placez le dans la pièce où se trouve l'autel (altar).

5. Faites un clic droit sur le gobelin dans cette zone et choisissez "Properties" à partir de son menu contextuel. Cela ouvre la fenêtre de propriétés d'une créature.

6. Changez le prénom (first name) de la créature par "Gnashgab".

7. Sur l'onglet "Statistics", réduisez les points de vie de base "Base Hit Points" à 10.

8. Allez dans l'onglet sorts "Spells" et selectionnez la classe clerc "Cleric". La liste des sorts de clerc devrait apparaître.

9. Selectionnez le sort d'aide "Aid" en cliquant dans sa cellule préparée "Prepared" (Appuyez sur F1 pour voir la description de ce sort).

10. Pour réduire le nombre de fois que Gnashgab a ce sort en mémoire, changez la valeur dans la cellule à 0 et appuyez sur la touche entrée. Remarquez le sommaire du sort en bas de l'onglet.

11. Appuyez sur "OK" pour accepter les changements.

Pour aller plus loin

Placez une rencontre de type mort vivant (undead) ou vermine (vermin) proche de la fin de la voie de chemin de fer avec son point d'apparition dans la pièce suivante. Dans ce cas, laissez la difficulté sur Normal mais fixez le nombre minimum de créatures à 1.

Astuce: Utilisez la commande "Edit" / "Find Instance" pour trouver l'instance spécifique d'un prototype (blueprint) place dans n'importe quel zone du module.Note: Editer un prototype (blueprint) n'a aucun impact sur les instances qui auront été préalablement placés dans les zones. does not impact any instances that were previouslypainted in any of the areas. Egalement, éditer une instance d'un objet du jeu dans une zone n'affectera pas le prototype (blueprint) à partir duquel il a été créé.

Portes et transition de zones

Page 15: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Introduction

En plus de vous présenter la gestion des portes, ce tutorial va vous expliquer comment lier des zones entre-elles.

Objectif

Le but de ce tutorial est de lier la zone contenant le village de Fern avec la mine de Fernesk.

Tutorial

Portes (Doors)

Les portes sont des objets spéciaux du jeu qui ne peuvent être placées qu'à des endroits spécifiques que l'on appelle point d'accrochage (hook points) sur certaines cases. En général il y a deux types de portes, universelles (universal) et spécifique à un groupe de cases (tileset specific). Les portes universelles peuvent être placées dans n'importe quelle zone. Les portes "tileset specific" ne peuvent aller qu'avec la zone en cours et son "tileset" associé.

1. Démarrez le Toolset et chargez le module "tutorial".

2. Ouvrez la zone "Fern".

3. Ouvrez la palette portes en appuyant sur le second bouton à partir de la gauche sur la ligne du bas.

4. Sélectionnez une des portes universelles en bois (universal wooden doors). Remarquez qu'une porte tournoyante est attachée à votre curseur de souris.

5. Amenez la porte sur l'entrée de l'auberge (Inn). La porte doit arrêter de tourner et une image de porte doit apparaître sur l'encadrement de la porte de l'auberge.

6. Posez la porte tant que l'image est sur l'encadrement de la porte en cliquant sur la zone (de même manière que n'importe quel autre objet). L'instance de cette porte doit être sélectionnée.

7. Supprimez la porte.

8. Sélectionnez une des portes spécifique au "tileset".Note: Une porte spécifique au "tileset" va apparaitre comme une porte standard en bois jusqu'à ce que vous la posiez sur un point d'accrochage (hook point) qui attends un porte spécifique au "tileset".

9. Essayez de la poser sur l'entrée de l'auberge (Inn). Le prototype (blueprint) utilisant un modèle de porte standard doit apparaître.

Note: Poser une porte spécifique au "tileset" à un endroit qui attend une porte universelle aura pour conséquence que la porte apparaîtra avec une apparence standard et ses autres propriétés resteront non-affectées.

10. Supprimez la porte spécifique au "tileset" et posez une des portes universelles.

Les portes ont plusieurs usages. Leur fonction principale est de bloquer une partie de la zone jusqu'à ce que le joueur remplisse certaines conditions, comme retrouver une clé. Une autre fonction est qu'une porte peut servir de transition de zone et lier des zones entre-elles.

Transition de zones (Area Transitions)

Une zone de transition (area transition) signifie que les joueurs seront transportés d'une zone à une autre. Ces transitions peuvent partir d'une porte ou d'un "trigger" et arriver à une porte, un "trigger" ou un "waypoint" (étape).

Page 16: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

1. Ouvrez la zone "Mine de Fernesk".

2. Sélectionnez la porte à l'entrée.

3. Sélectionnez ses propriétés "Properties" à partir de son menu contextuel.

4. Changez le nom du tag de la porte (script tag) à "dt_MineToFern" et appuyez sur "OK".Note: Définir des transitions de zones de cette manière permet de s'assurer que les tags de porte fonctionneront proprement. Chaque porte doit avoir un nom unique sinon le résultat dans le jeu est imprévisible. Le Toolset affiche un avertissement si une tentative de lier une transition de zone est faite sur une porte dont le tag n'a pas été changé.

Astuce: Essayez de commencer le tag de chaque object avec la première lettre du type de l'objet suivi par un "t_" et son nom comme "MineToFern" qui dans ce cas indique la zone et la direction vers laquelle la transition de zone va.

5. Ouvrez la zone "Fern", sauvegardez vos modifications quand le logiciel vous le demande.

6. Sélectionnez la porte de l'entrée de la mine "Cave Entrance" et affichez ses propriétés.

7. Changez le tag de la porte à "dt_FernToMine".

8. Sur l'onglet zone de transition (Area Transition) cliquez sur "Setup Area Transition" pour ouvrir la fenêtre de transition de zones.

9. Sélectionnez "Mine de Fernesk" à partir de la liste des zones cibles (Target Area). Laissez les valeurs type de cible (Target Type) et type de connexion (Connection Type).

10. Sélectionnez "dt_MineToFern" à partir de la liste des portes disponibles, appuyez sur OK pour fermer la fenêtre de transition de zones et appuyez sur "OK" pour sauvegarder les changements effectués sur la zone.

11. Appuyez sur "OK" pour fermer la fenêtre des propriétés de la zone.

12. Placez le point de démarrage du module (module's start location) proche de l'auberge (Inn).

Ecrans de chargement (Load Screens)

Chaque zone a son écran de chargement par défaut, basé sur son type de "tileset", qui apparaît quand le joueur transitent vers cette zone. Cet écran de chargement peut être spécifié à partir de la fenêtre des propriétés d'une zone. Les zones de transitions peuvent avoir leur propres écrans de chargement qui remplaceront celui par défaut. Par défaut, le jeu utilise un écran de chargement choisi au hasard en fonction du "tileset" utilise par la zone de destination.

1. Démarrez le Toolset et chargez le module "tutorial".

2. Ouvrez la zone "Fern".

3. Sélectionnez les propriétés de zone "Area Properties" à partir du menu "Edit".

4. Allez dans l'onglet avancé "Advanced" et appuyez sur le bouton à coté du nom de l'écran de chargement qui doit normalement dire "choisi au hasard" (Random) par défaut. Cela permettra d'ouvrir la fenêtre de sélection de la page de chargement.

5. Désactivez le bouton "Use Random Loading Screen" (utiliser un écran au hasard).

6. Sélectionnez l'écran de chargement de votre choix parmi ceux disponibles.

7. Basculez sur la zone "Mine de Fernesk".

8. Select "Properties" from the context menu of the door in the cave entrance, the one with the Script Tag: dt_MineToFern.

Page 17: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

9. Allez sur l'onglet "Area Transition" (transition de zone) et appuyez sur le bouton à coté de l'écran de chargement, lequel doit normalement dire "Default" par défaut. Ce qui veut dire que l'écran choisi au niveau des propriétés de la zone sera utilisé.

10. Désactivez le bouton "Use Random Loading Screen" (utiliser un écran au hasard).

11. Changez le filtre (filter) pour utiliser le "tileset" "Rural" et sélectionnez un écran différent que celui choisi à l'étape 6.

Sauvegardez vos changements et contrôlez les directement au sein du jeu.

Pour aller plus loin

Créez une zone intérieure basée sur le "tileset" "City Interior" (intérieur de ville) et liez là à l'auberge de Fern en utilisant des portes.

Fermez à clé la porte de l'auberge en activant la propriété "Locked" (fermé). Sur le même onglet spécifiez le tag de l'article (item) requis pour déverrouiller la porte. Ceci permettra à toute créature possédant un article (item) avec ce tag dans son inventaire d'ouvrir cette porte.

Astuce: Il est possible de définir une transition de zone au sein de la même zone.

Jouez avec les portes spécifiques au "tileset" et les universelles. Trouvez une place où poser un terrain "Wall 2 Gate" (Porte de mur 2) dans la catégorie "Feature". Sélectionnez et supprimez la porte. Choisissez une porte spécifique au "tileset" et posez là sur ce terrain. Supprimez là et faite la même chose avec une porte universelle. Dans les deux cas, la même porte devrait apparaître mais il devrait y avoir de subtiles différences sur les propriétés de la portes en fonction des différents prototypes (blueprints) utilisés.

Creer les personnages de l'histoire (Create the Cast)

Introduction

Maintenant que les deux zones, Fern et la mine de Fernesk ont été crées et reliées, les joueurs peuvent passer de l’une à l’autre librement. La prochaine étape consiste à créer les personnages principaux de l’aventure. Il y a des personnages qui ont un rôle significatif à jouer, que ce soit à travers un combat ou une conversation.

Ce tutorial explique la différence entre la palette standard et la palette personnalisée (standard and custom palettes) et les différentes manières de créer des «objets » personnalisés.

Objectif

Le but de ce tutorial est de créer des modèles personnalisés (custom creature blueprints) pour Falstadd, Gnashgab, et Veran, en employant à chaque fois une méthode différente.

Tutorial

La palette standard par rapport à la palette personnalisée

Page 18: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Chaque type d'objet de jeu possède une palette où sont listés les différents prototypes disponibles (blueprints). Chaque palette est divisée en deux sous-palettes : Standard et personnalisée. La palette standard contient les prototypes disponibles dans tous les modules. La palette personnalisée contient les prototypes disponibles uniquement dans le module actuel.

Il y a différentes manières d’ajouter des prototypes uniques dans la palette personnalisée.

Gnashgab

Gnashgab est un shaman gobelin qui a conduit ses guerriers dans la mine de Fernesk et a capturé les mineurs, les transformant en esclaves.

1. Démarrez le « toolset » et chargez le module "tutorial".

2. Ouvrez la zone (area) de la mine de Fernesk.

3. Trouvez et sélectionnez Gnashgab dans la liste des créatures à partir du panneau «Module Contents»

4. Sélectionnez "Focus on Object" à partir du menu contextuel de Gnashgab. Cela déplacera l’affichage de la zone, mettant Gnashgab au milieu de l’écran et entouré d’une boite en fil de fer.

5. Faites un clic droit sur Gnashgab pour afficher son menu contextuel et sélectionnez "Add to Palette". Cela active la fenêtre de propriété de la créature.

6. Un nouveau nom de prototype (blueprint) sera crée automatiquement et tout ce qu'il vous reste à faire est de spécifier la nouvelle catégorie : "Special" | "Custom 1" dans l'onglet "Basic".

Note: Neverwinter Nights requiert que chaque prototype d’un objet ait un nom unique. Ce nom n’est ni le nom qui apparaît dans le jeu, ni le tag de l'objet (script tag), c’est un nom différent utilisé uniquement pour identifier le prototype (blueprint). La plupart du temps, un nom unique sera généré automatiquement. Si nécessaire, vous pourrez aussi un créer un manuellement, moyennant quelques restrictions:

Deux prototypes ne peuvent avoir le même nom. La taille du nom doit être inférieur à 16 caractères. Le nom ne peut contenir comme caractères que : a - z (minuscules uniquement),les chiffres 0

- 9 et le tiret "_" (sans les guillemets).

7. Cliquez sur "OK". Cela crée un nouveau prototypes (blueprint) pour Gnashgab, permettant de le placer à un autre endroit dans le module, ou pour que le maître du jeu puisse le faire apparaître à la demande pendant le jeu.

Falstadd

Falstadd est le maire de Fern, et le père de Jacen, un des travailleurs qui fut capturé pendant le raid.

1. Basculez sur la palette des créatures standards si elle n’est pas déjà fait.

2. Sélectionnez "Shop Keeper" (gardien de boutique) dans la catégorie NPCs / Human.

3. Sélectionnez "Edit Copy" dans le menu contextuel du "Shop Keeper". Cela ouvre la fenêtre de propriétés d'une créature.

4. Changez le prénom du personnage par "Falstadd" et donnez lui un nom de famille aléatoire en cliquant sur le bouton "Generate Random Name" (il y a dessus l’image d’un visage)

5. Changez le tag (Script Tag) en "ct_Falstadd" (bien sur sans les guillemets).

6. Changez la catégorie du personnage en "Special" | "Custom 2".

Page 19: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

7. Cliquez sur "OK". Remarquez que la palette de la créature bascule immédiatement sur la sous-palette « custom » et sélectionne le nouveau prototype (blueprint).

8. Positionnez une instance de Falstadd près du lieu de départ des joueurs dans la zone de Fern.

Veran

Veran est un collaborateur, travaillant avec les gobelins pour asservir les mineurs et conquérir le royaume de Hyatt.

1. Sélectionnez "Creature Wizard" dans le menu « Wizard ». Cela va lancer le générateur assisté de créature " New Creature Blueprint wizard". Cliquez sur next pour commencer.

2. Sélectionnez "Human" comme race (racial type) et cliquez sur "Next".

3. Enlevez la classe de guerrier "Fighter" en cliquant sur le "x" rouge près du niveau.

4. Ajoutez le classe de roublard "Rogue" et montez le niveau à 3. Cliquez sur next pour continuer.

5. Laissez le genre de Veran tel quel, mais sélectionnez l’apparence "Human, Male 01" et choisissez un portrait.

ATTENTION: Toutes les créatures, portes et objets plaçables ont besoin d’un portrait.

6. Cliquez sur "Next", mettez la « faction » de Veran "Hostile" et cliquez sur "Next".

7. Entrez "Veran" comme prénom du personnage et cliquez sur "Next".

8. Sélectionnez comme catégorie Special | Custom 1 pour ce prototype.Note: Tous les méchant ont comme catégorie Special | Custom 1. Ce n’est évidemment pas obligatoire mais organiser les palettes ainsi aide le maitre du jeu (DM) à retrouver un personnage non joueur (PNJ en français ou NPC en anglais) rapidement.

9. Cliquez sur "Next".

10. Regardez le sommaire décrivant les caractéristique du prototype à créer et cliquez sur "Next".

11. Enfin, vérifiez que le case "Launch Creature Properties" n’est pas cochée et cliquez sur "Finish".

12. Placez Veran à quelques cases du départ des joueurs et de l’emplacement de Falstadd.

Sauvegardez le module, quittez le Toolset et allez vérifier le module dans le jeu. Veran va probablement attaquer soit Falstadd soit les PC immédiatement, à cause du système de « faction » et des scripts attribué par défault.Astuce: Pour effacer un prototype (blueprint), cliquez simplement sur "Delete" à partir de son menu contextuel. Les prototypes standards ne peuvent pas être effacés.

Pour aller plus loin

Page 20: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Les règles de D&D dans le Toolset

En utilisant le « Creature Wizard », il est possible de créer des créatures à peu près en accord avec les règles de D&D, 3ème édition. En utilisant la fenêtre des propriétés de la créature, il est possible de créer des créatures qui dévient significativement de ces règles.

La table des capacités spéciales ("Special Abilities") dans la fenêtre des propriétés de la créature permet d’attribuer des capacités spéciales à une créature en dehors des capacités données par une classe.

1. Créez un nouveau prototype (blueprint) d’Elfe niveau 1 de Mage en utilisant le « Creature Wizard. »

2. Vérifiez que la case "Launch Creature Properties" est décochez avant de terminer la génération assistée (wizard).

3. Le « Creature Wizard » assigne automatiquement un nombre approprié de sorts (tenant compte d’un bonus nul en intelligence) au personnage. Essayez d’ajouter 2 sorts ou plus de niveau zéro, de niveau 1 ou n’importe quel quantité de sorts de haut niveau et appuyez sur "OK".Le Toolset indique par un message d’avertissement que la créature a reçu trop de sorts pour son niveau ou qu’elle ne peut pas lancer de sort de ce niveau.

4. Appuyez sur "No" pour retourner dans la fenêtre des propriétés et enlevez les sorts en excès.

5. Allez dans l'onglet des capacités spéciales ("Special Abilities") et assignez le même nombre de sort que dans l’étape 3 et appuyez sur "OK". Cette fois le Toolset accepte les modifications et autorise la fermeture de la fenêtre des propriétés

6. Supprimez ce modèle.Note: Les capacités spéciales et extraordinaires des objets de l’inventaire d'une créature ne sont pas prise en compte dans l'onglet de ses statistiques.

Attitudes generales: Factions

Introduction

A la fin du dernier tutorial, les villageois de Fern étaient laissés à la merci de Veran, un maniaque des homicides. Cela était alors trop facile pour les joueurs de trouver le traitre (villain). Il est nécessaire de rendre Veran un peu plus tolérant envers les autres personnes.

Objectif

Ce tutorial explique les « Factions » et présente l’éditeur de Factions (Factions Editor) dans le Toolset. De plus, deux nouvelles factions, et un nouveau prototype (blueprint) seront crées.

Tutorial

Factions

Les factions sont le moyen de décrire les relations générales entre les différents groupes de créatures et autres "objets" joueurs compris.

Page 21: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Les scripts assignés par défaut aux événements des différents "objets" du jeu s'appuient sur ce système pour déterminer le comportement de l'objet en fonction de son environnement. C’est pourquoi Veran attaque brutalement quiconque n’appartenant pas à sa faction.

Chaque module commence avec 5 factions standards: "PC" (joueurs), "Hostile", "Commoner" (communs), "Marchant" et "Defenders" (Défenseurs). Les « objets » du jeu peuvent être assignés à n’importe quel factions sauf les "PC" (réservés aux joueurs). De nouvelles factions peuvent être crées en utilisant le Toolset, ce qui permet des alliances personnalisées sans avoir besoin d’utiliser le language des scripts.

Faction collaboratrice (Collaborator faction)

Suivez les étapes ci-dessous pour assigner Veran à une faction collaboratrice. La faction collaboratrice est similaire à celle des marchants, mais n’est pas aggresive face à la faction Hostile.

1. Démarrez le Toolset et chargez le module tutorial.

2. Sélectionnez « Faction Editor » dans le menu « Tools ».Astuce: Le « Faction Editor » montre les informations dans un graphique (bar graph) dans l'onglet "Basic" et dans un tableau (grid) dans l'onglet « Advanced ».

3. Appuyez sur "Add Faction" dans le coin en bas à droite de la fenêtre.

4. Appelez la faction "Collaborator" et mettez "Merchant" en faction parente (parent faction). Laissez la boite « global effect » telle quelle et appuyez sur "OK".

5. Une nouvelle faction devrait apparaître dans la liste à droite.Note: Les boites à cocher (checkboxes) derrière chaque entrée dans la liste à droite indiquent si la faction apparaît ou non sur le graphique ou la tableau (selon le mode).Note: La valeur sur la colonne sur le graphique, ou sur la cellule dans la tableau indique comment la faction sélectionnée dans la liste réagit avec la faction correspondante.

Faction correspondant au nombreValeur 0-10 11-89 90-100Faction sélectionnée Ennemie : attaque à

vue.Neutre : Ignore Alliée : Aidera en cas

d’attaque.

6. Avec tout le reste coché, sélectionnez la faction « Hostile » dans la liste. Remarquez que le graphique montre que la faction « Hostile » considère les membres de toutes les autres factions comme des ennemies.

7. Avec la faction « Hostile » sélectionnée, faites glisser la barre de la faction « Collaborator » dans le graphique et augmentez la jusqu’à avoir une valeur de réaction de 50. Cela signifie que les membres de la faction « Hostile » n’attaqueront plus automatiquement les membres de la faction « collaborator ».

Astuce: Si déplacer la barre dans le graphique est trop compliqué, utilisez le tableau dans l'autre onglet pour définir la valeur voulue.Note: La faction « PC » (celle des joueurs) ne peut être modifiée.

8. Sélectionnez le faction « Collaborator » à partir de la liste. Déplacez la barre de la faction « Hostile » jusqu’à avoir une valeur de réaction de 50. Les membres de la faction « collaborator » n’attaqueront plus automatiquement les membres de la faction « Hostile ».

9. Cliquez sur "OK". Cela peut prendre quelques instants pour que le Toolset sauvegarde les informations de la nouvelle faction.

Veran

Page 22: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Pour assigner Veran à cette nouvelle faction :

1. Ouvrez le zone de Fern (« Fern Area »).

2. Ouvrez la palette des créatures personnalisées (« Custom Creature palette »), localisez Veran puis sélectionnez « Edit » à partir de son menu contextuel.

3. Sur l'onglet « Advance », changez la faction en « Collaborator »Note: Il est important de se souvenir que les modifications du prototype (blueprint) ne sont PAS prises en compte automatiquement par les instances de ce prototype. Cliquez sur « Update Instances », puis sur « Yes » pour mettre à jour toutes les instances présentes dans le module. Cliquez sur « No » pour éviter d'avoir la liste de toutes les instances qui vont être mise à jour. Enfin, appuyez sur « Ok ».

4. Appuyez sur « Ok » pour femer la fenêtre des propriétés des créatures (« Creature properties »). Recherchez l'instance de Veran dans l’affichache de la zone, ou dans la liste du contenu du module (« module contents list ») et vérifiez ses propriétés pour voir si la faction a bien été configurée, et appuyez sur « Ok ».

Sauvegardez le module, quittez le Toolseet et chargez le jeu pour voir les changements. Veran devrait être plus calme maintenant.

Faction des Mineurs. (Miner Faction)

Qu’est ce qu’une mine sans mineurs ? Les mineurs, maintenant esclaves des gobelins, doivent être présent dans la mine de Fernesk ; donc une nouvelle faction doit être créé pour eux.

1. Démarrez le Toolset et chargez le module tutorial.

2. Sélectionnez « Faction Editor » dans le menu « Tools ».

3. Ajoutez une faction, Mineur, avec pour faction parente « Commoner ».Astuce: Si le graphique est un peu trop surchargé, désélectionnez les factions « Merchant » et « Defender » dans la liste.

4. Sélectionnez la faction « Hostile ». Attribuez lui une valeur de réaction de 15 avec les mineurs.

5. Effectuez la même opération en attribuant aux mineurs, une réaction de 15 face à la faction « hostile ».

Note: Les réactions entre deux factions ne doivent pas forcément être réciproques. Et ce, simplement parce que si membre d’une faction A considère un membre d’une faction B comme un allié, la réciproque n’est pas forcement vraie.

6. Cliquez sur "OK" pour fermer l’éditeur des factions et accepter les changements.

Mineur (Miner)

La prochaine étape consiste à créer un nouveau prototype (blueprint) pour les mineurs.

1. Sélectionnez "Creature Wizard" dans le menu « Wizard ».

2. Créez un humain avec un niveau 1 de "commoner", un portrait, (choisissez en un) et avec l’apparence d’un mendiant "beggar".

3. Dans la table des factions du « creature Wizard », sélectionnez "Miner", et appuyez sur "Next".

4. Changez le prénom du Mineur, générez un nom de famille (Last Name) et cliquez sur "Next".

5. Assignez ce modèle (blueprint) à la catégorie Special | Custom 2 puis cliquez sur « finish »

Page 23: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

6. Ouvrez la fenêtre des propriétés (« Creature Properties Windows ») du prototype en sélectionnant "Edit" à partir de son menu contextuel. Changez le « scrip tag » en « ct_miner » et appuyez sur « Ok ».

Rencontre du groupe des mineurs.(Miner Group Encounter)

Finalement, une nouvelle rencontre doit être crée afin de faire apparaître les miners pendant l’exploration de la mine de Fernesk par les joueurs.

1. Sélectionnez le générateur assisté de rencontres "Encounter Wizard" dans le menu « Wizards »

2. Choisissez la catégorie Special | Custom 2 puis cliquez sur "Next".

3. Sélectionnez le prototype (blueprint) « Miner » dans la palette des créatures personnalisées et rajoutez le dans la liste des rencontres en appuyant sur le bouton "->" puis sur "Next".

4. Appelez ce nouveau prototype de rencontre « Miner Group », vérifiez que la case "Launch Properties Dialog" est décochée puis appuyez sur "Finish".

5. Ouvrez la zone de la mine de Fernesk, et posez une instance de ce nouveau groupe proche du 2ème

groupe de gobelins, juste à l’extérieur de la pièce où se trouve l'excavation (mineshaft).

6. Placez le point d’apparition (spawn point) pour ce nouveau groupe proche de l'excavation mineshaft elle même.

Sauvegardez le module et vérifiez ces changements dans le jeu.

Pour aller plus loin

La palette « Waypoint » inclus des prototypes (blueprint) pour des notes de carte "map notes" des postes "Posts" et des point de route "waypoints". Les annotations de la carte (Map Note) apparaîtront sur la carte du joueur et peut être utilisée pour indiquer des points spéciaux dans la zone. Placez une indication sur la carte (map note) à l’entrée de la mine. Son nom devra être changé.

Le script utilisé par défaut pour les créatures utilise des « waypoints »et des « posts » pour controler leurs mouvements. Lisez les commentaires de chacun de ces deux objets pour voir comment les utiliser. Placez des « waypoints » autour de l'excavation pour donner aux mineurs l’apparence de faire quelque chose. Sélectionnez tous les waypoints puis cliquez sur "Create Set" à partir du menu contextuel. Mettez comme nom du set WP_ct_Miner. Ceci génerera automatiquement les noms des waypoints de manière à ce que les mineurs puissent circuler d'un waypoint à l'autre.

Note: Les annotations de la carte, « post » ou « waypoint » n’apparaîtront pas dans le jeu comme ils le font dans l’éditeur.

Journal et Conversation

Introduction

Actuellement, le module de ce tutorial contient quelques areas complétées par les instances de quelques blueprints intéressants, quelques blueprints de NPCs uniques et quelques nouvelles factions. Cependant, il manque encore de quoi intéresser les PCs, ce qui les encouragera à commencer l'aventure.

Ce chapitre introduit le Journal Editor et le Conversation Editor. En général, la progression d'une intrigue ou d'une quête est mesurées par les entrées du journal mais elle est conduite par les dialogues prononcés par ses principaux acteurs.

Objectif

Page 24: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Créer des conversations pour Falstadd et Veran dans lesquelles les PCs peuvent participer et qui modifient leur journal.

Tutorial

Quêtes and Journal

Les aventures sont centrées sur les quêtes dans lesquelles s'embarquent les joueurs. Le journal du jeu permet aux joueurs de garder une trace de chaque étape de la quête, et de voir rapidement où aller ensuite. Chaque quête est classée par catégorie dans le journal (les ' journal category').

1. Lancez le Toolset et chargez le module "Tutorial".

2. Sélectionnez le 'Journal Editor' dans le menu 'Tools'.

3. Parmi les boutons situés sur le côté gauche, vous pouvez voir 'Add', 'Cut', 'Copy' et 'Paste'. Appuyez sur le bouton 'Add' ; c'est le seul bouton sur lequel vous pouvez cliquer initialement. Ceci crée une nouvelle Journal Category.

4. Sélectionnez la nouvelle catégorie. Changez son nom par "Quête de Falstadd", son Tag par "jt_Falstadd", sa 'Priority' (priorité) par 'Highest' (maximale) et son 'XP Value' (Valeur en XP) par 2000.

5. Ajouter 3 entrées (entry) à la catégorie en appuyant sur 'Add' ou en sélectionnant 'Add' dans le menu contextuel lorsque le nœud de la catégorie est sélectionné. Chaque entrée représente une étape spécifique de la quête.

6. Sélectionnez la première entrée et changez son texte par "Trouver le fils de Falstadd, Jacen, dans la mine de Fernesk".

7. Sélectionnez la seconde entrée et changez son texte par "Ramener l'anneau de Jarcen à son père, Falstadd."

8. Sélectionnez la troisième entrée et changez son texte par "L'anneau de Jarcen a été rendu à Falstadd". Cochez la case "Finish Category" et appuyez sur "OK".

Conversation: Falstadd

Les conversations sont des séries d'affirmations (ou de questions) de NPC alternant avec les réponses d'un PC.

1. Sélectionnez le 'blueprint' dans la Palette 'Custom Creature' et choisissez 'Edit' dans le menu contextuel.

2. Dans l'onglet 'Basic', cliquez sur 'Edit' à côté du menu déroulant 'Conversation' au bas de la fenêtre. Cela ouvre le 'Conversation Editor' et crée un nouveau fichier de conversation vide. Vous remarquerez à quel point le 'Conversation Editor' ressemble au 'Journal Editor'.

3. Cliquez pour créer une nouvelle phrase de NPC, puis entrez le texte ci-dessous dans la fenêtre qui apparaît et cliquez sur 'OK'. Vous verrez que le texte apparaît maintenant dans l'arbre, sous la racine (Root).

Nœud 1 Texte de NPC Bonjour à nouveau <FirstName>. Avez-vous appris quoi que ce soit au sujet de la mine ?

Note: <FirstName> est un 'token'. Un 'token' est une expression particulière que le jeu comprend et remplace par un autre texte approprié au contexte actuel. Ici, le jeu remplacera <FirstName> par le prénom du joueur à qui le NPC est en train de parler. Pour voir la liste des tokens ainsi que quelques exemples, sélectionnez 'Insert Token' dans le menu contextuel de la fenêtre où vous entrez le dialogue.

Page 25: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

4. Avec le nœud 1 sélectionné ("Bonjour à nouveau..."), appuyez sur 'Add'. Ceci crée un nouveau nœud de réponse de PC. Tapez ce texte:

Nœud 2 Texte de PC Oui, la mine était envahie par des gobelins et ils utilisaient les mineurs comme esclaves. Les gobelins ont été vaincus mais malheureusement, Jacen fut l'une de leurs victimes. L'anneau a été retrouvé sur son corps.

5. Avec le nœud 2 sélectionné ("Oui, la mine..."), appuyez sur 'Add'. Ceci crée un nouveau nœud de NPC. Tapez ce texte:

Nœud 3 Texte de NPC Je vous remercie pour le service que vous avez rendu à Fern, mais... mon pauvre fils!

6. Avec le nœud 1 sélectionné ("Bonjour à nouveau..."), appuyez sur 'Add' à nouveau et tapez ce texte comme autre possibilité de réponse pour le PC:

Nœud 4 Texte de PC Non, pas encore.

7. Avec le nœud 4 sélectionné ("Non, pas encore."), appuyez sur 'Add' et tapez ce texte comme nouveau nœud de NPC:

Nœud 5 Texte de NPC Vous devriez parler à Veran. Vous le trouverez près de son magasin. Il cherche des gens pour monter un expédition et vérifier ce qui se passe dans la mine. Je serai extrêmement reconnaissant si vous l'aidez à localiser mon fils.

8. Avec 'Root' sélectionné, appuyez sur 'Add' et tapez ce texte comme autre possibilité de salutation pour le NPC:

Nœud 6 Texte de NPC Soyez le bienvenu! Je suis Falstadd, le bourgmestre de Fern. Comment puis-je vous être utile ?

9. Avec le nœud 6 sélectionné ("Soyez le bienvenu! Je suis..."), appuyez sur 'Add'. Et tapez ce texte comme réponse du PC:

Nœud 7 Texte de PC Bonjour, je suis <FullName>, j'ai entendu que vous aviez besoin d'une escorte pour un chargement de fer en partance de Château Hyatt dans la matinée.

10. Avec le nœud 7 sélectionné ("Bonjour, je suis..."), appuyez sur 'Add'. Et tapez ce texte comme prochaine phrase du NPC:

Nœud 8 Texte de NPC Oui, la caravane. La cargaison n'est pas encore prête, voyez-vous. Les mineurs, ainsi que mon fils, Jacen, semblent avoir disparu.

11. Avec le nœud 8 sélectionné ("Oui, la caravane..."), appuyez sur 'Add' mais cette fois, ne tapez aucun texte.

Nœud 9 Texte de PC

Note: Un nœud de PC sans texte apparaîtra soit comme un nœud [CONTINUE], ou [END DIALOGUE] dans le jeu, selon qu'un nœud de NPC le suit ou non. Si la conversation finit par un nœud de NPC, le jeu ajoutera automatiquement un nœud [END DIALOGUE].

12. Ce nouveau nœud devrait dire aux joueurs de trouve Veran et d'obtenir plus d'informations de sa part. Un tel nœud a déjà été créé, le nœud 5 (Vous devriez parler..."). Il est possible de créer un lien depuis le dernier nœud, le nœud 9 vers le nœud 5. Sélectionnez 'Copy' dans le menu contextuel du

Page 26: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

nœud 5. Puis sélectionnez 'Paste as Link' (Coller en tant que Lien) dans le menu contextuel du nœud 9. Une version grisée du texte du nœud 5 devrait apparaître sous le nœud 9.

Note: Utilisez les liens pour permettre aux joueurs de suivre différentes voies dans les conversations, tout en vous assurant qu'ils reçoivent les mêmes informations. Ceci est particulièrement important lorsqu'il s'agit d'informations sur l'intrigue.

13. Sauvegardez la conversation sous le nom de 'falstadd', et fermez le Conversation Editor. Sauvegardez les changements effectués au blueprint de Falstadd et, soit cliquez sur 'Update all instances' dans le menu contextuel du blueprint, soit effacez simplement l'instance que vous aviez placé et repeignez la.

Sauvegardez le module et vérifiez la en jeu en parlant avec Falstadd.

Script Wizard

Il est clair que la conversation nécessite encore du travail avant qu'elle n'ait vraiment un sens. Heureusement, elle ne demande plus beaucoup de travail – en fait, seulement 4 scripts judicieusement placés, tous créés avec le Script Wizard.

1. Démarrez le Toolset et chargez le module "tutorial".

2. Dans la partie réservée au contenu du module, ouvrez la liste de conversations et sectionnez 'Edit' dans le menu contextuel de la conversation nommée 'Falstadd'. Ceci ouvrira la conversation sans avoir à passer par les propriétés de la créature.

3. Sélectionnez le nœud 1 ("Bonjour à nouveau..."). Dans l'onglet 'Text Appears When..." (Texte apparaît lorsque...), et appuyez sur le bouton du Script Wizard (il ressemble à un chapeau de magicien). Cochez la case "Local Variable" (Variable Locale) et cliquez sur 'Next'.

4. Ne paniquez pas! Ce n'est pas si terrible.

Note: L'utilisation de variables nécessite un peu d'organisation, mais ce n'est pas bien compliqué. Une variable a besoin d'un nom et représente un certain type de donnée (par exemple un nombre ou une série de caractères – appelée une 'string'). Attribuez ('Set') une valeur à une variable à un certain moment, lorsqu'une certaine action est accomplie, ou lorsqu'un certain évènement a lieu, et vérifiez la à une autre moment pour confirmer si l'action a été accomplie ou si l'évènement a eu lieu.

5. Tapez 'nFirstTimeTalked' dans le champ en haut à droite. Ceci est le nom de la variable, sa valeur est déterminée en utilisant un autre script.

6. Entrez '1' dans le champ en bas à droite (à côté du bouton 'Add'). Ceci est la valeur que la variable doit avoir pour que le script retourne TRUE (Vrai).

7. Appuyez sur 'Add' pour ajouter cette vérification au script et appuyez sur 'Next'.Note: Vous pouvez ajouter plus de variables en continuant à nommer des variables, configurer des conditions (is equal to (est égal à), is less than (est inférieur à), etc.) et spécifier les valeurs à tester.

8. Donnez au script le nom 'sc_falstadd01' et appuyez sur 'Finish'.

9. Sélectionnez le nœud 7 ("Soyez le bienvenu, je suis..."). Dans l'onglet 'Action Taken', cliquez sur le bouton du Script Wizard. Cochez la case 'Set Local Variable' et appuyez sur 'Next'.

10. Tapez 'nFirstTimeTalked' dans le champ en haut à droite.

11. Tapez '1' dans le champ situé sous le nom de la variable et appuyez sur 'Add'.

12. Appuyez sur 'Next', donnez au script le nom 'at_falstadd01' et cliquez sur 'Finish'.

Page 27: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

13. Sélectionnez le nœud 2 ("Oui, la mine..."). Ce nœud ne devrait apparaître que si les joueurs ont exploré la mine et trouvé l'anneau de Jacen.

14. Dans l'onglet 'Text Appears When...', appuyez sur le bouton du Script Wizard. Cochez la case 'Item in Inventory' (Objet dans l'Inventaire) et cliquez sur 'Next'.

15. Tapez le Tag de l'anneau de Jacen, 'it_RingJacen'. Cet anneau sera créé et placé un peu plus tard.

16. Appuyez sur 'Add', puis sur 'Next'. Donnez au script le nom 'sc_falstadd02' et cliquez sur Finish.

17. Sélectionnez le nœud 2 ("Oui, la mine..."). Lorsque ce nœud est sélectionné, le joueur devrait rendre l'anneau à Falstadd, il doit donc être retiré de l'inventaire du joueur.

18. Dans l'onglet 'Action Taken', cliquez sur le bouton du Script Wizard. Cochez la case 'Take From Player' (Prendre au Joueur) et appuyez sur 'Next'.

19. Entrez le tag de l'Item à retirer, ici 'it_RingJacen', et appuyez sur 'Add'.

20. Sélectionnez 'Keep' (Garder), sous la liste des objets requis (Required Items). Cela signifie que si la créature venait à mourir, cet objet serait laissé dans son inventaire.

21. Appuyez sur 'Next', nommez le script 'at_falstadd02' et appuyez sur 'Finish'.

Sauvegardez la conversation et le module, puis fermez le Toolset et vérifiez les changements en parlant deux fois à Falstadd.

Attacher des Entrées de Journal

Le journal du PC doit être mis à jour à certains moments de la conversation.

1. Démarrez le Toolset et chargez le module "tutorial".

2. Ouvrez la conversation de Falstadd à partir de la liste du contenu du module.

3. Sélectionnez le nœud 5 ("Vous devriez..."). Dans l'onglet 'Other Actions', sélectionnez "Quête de Falstadd" comme journal category et "1" comme journal entry.

4. Sélectionnez le nœud 3 ("Je vous remercie..."). Dans l'onglet 'Other Actions', sélectionnez "Quête de Falstadd" comme journal category et "3" comme journal entry

A nouveau, vérifiez les changements du module dans le jeu. Vous remarquerez que le journal est mis à jour après avoir parlé avec Falstadd.

Conversation: Veran

Après avoir parlé avec Falstadd, le PC va sûrement aller parler à Verna. Il faut donc qu'il ait quelque chose à dire.

1. Démarrez le Toolset et chargez le module "tutorial".

2. Sélectionnez le blueprint Veran dans la palette 'custom creature' et choisissez 'Edit' dans son menu contextuel.

3. Appuyez sur le bouton 'Edit' situé à côté du champ 'Conversation' au bas de l'onglet 'Basic' pour ouvrir le Conversation Editor avec une nouvelle conversation.

4. Sélectionnez le noeud 'Root', cliquez sur 'Add et tapez le texte suivant:

Nœud 1 Texte de NPC Salut à vous! Je suis Veran. Je suis en charge de la mine de fer locale, ainsi que le propriétaire du Commerce de Veran. Je pourrai ajouter que

Page 28: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

vous ne trouverez pas de prix plus intéressants que dans mon échoppe.

5. Sélectionnez le noeud 1 ("Salut à vous! Je suis..."), appuyez sur 'Add' et tapez le texte suivant:

Nœud 2 Texte de PC Bonjour, Veran. Je suis <FirstName>. Falstadd m'a laissé comprendre que vous auriez besoin d'aide pour une expédition visant à localisant les mineurs manquant.

6. Sélectionnez le noeud 2 ("Bonjour Veran..."), appuyez sur 'Add' et tapez le texte suivant:

Nœud 3 Texte de NPC Ah, pauvre Fastadd. Son propre fils, Jacen, fait partie des mineurs disparus. Si vous souhaitez aider, je vous ferai une intéressante ristourne sur tout ce que j'ai en stock. Voulez-vous voir ce que j'ai à vendre ?

7. Sélectionnez le noeud 3 ("Ah, pauvre..."), appuyez sur 'Add' et tapez le texte suivant:

Nœud 4 Texte de PC Oui, s'il vous plaît.

Note: Les Marchands sont expliqués dans le prochain tutorial.

8. Sélectionnez le noeud 3 ("Ah, pauvre..."), appuyez sur 'Add' et tapez le texte suivant:

Nœud 5 Texte de PC Non, merci.

9. Sauvegardez la conversation, ainsi que les changements apportés au blueprint Veran. Supprimez l'instance de Veran que vous aviez précédemment placée dans l'area Fern et peignez en une nouvelle, ou utilisez 'Update Instances' dans le menu contexuel du blueprint de la palette Custom Creature.

Pour aller plus loin

Placez une instance d'un blueprint Innkeeper (aubergiste) dans la catégorie 'NPC/Humans' dans l'area de l'auberge, créée dans la partie 'Pour aller plus loin' du chapitre 3. Si l'area de l'auberge n'a pas été créée, placez simplement l'aubergiste dans l'area Fern, à l'extérieur de l'auberge.

Créez une conversation qui récompense le PC avec 1000 points d'expérience (XP), ce qui est suffisant pour qu'un personnage niveau 1 atteigne le niveau 2, et attachez la à l'instance de l'aubergiste.

Items et Inventaire

Introduction

La conversation de Veran que nous avons créée dans le précédent chapitre offre la possibilité au joueur d'acheter des biens dans un magasin. Des biens peuvent être échangés entre un joueur et un NPC par l'intermédiaire d'un object du jeu, les Merchant Objects. C'est toujours une bonne idée de permettre aux joueurs de s'équiper avant de se lancer dans une aventure. Les objets peuvent être communs ou magiques, et comme tout le reste, si les items disponibles ne sont pas acceptables, ils peuvent être modifiés, vous pouvez même créer des items personnalisés.

Ce tutorial explique la création d'items et de merchants.

Objectif

Page 29: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Les objectifs de ce tutorial sont de placer l'anneau de Jarcen qui est trouvé sur son cadavre dans la mine, de créer une amulette magique que nous assignerons à une instance de merchant, ainsi que de déclencher cette instance de merchant par la conversation de Veran.

Tutorial

L'Anneau de Jacen

La première chose à faire est de placer une instance d'un item existant, un anneau (ring), dans l'inventaire du cadavre (corpse) sur l'autel (altar).

1. Démarrez le Toolset et chargez le module "tutorial".

2. Ouvrez l'area 'Mine de Fernesk'

3. Sélectionnez 'Porperties' dans le menu contextuel du 'Plague Victime Corpse' (Corps d'une victime de la peste) qui a été placé sur l' 'Altar' (autel) pour ouvrir le menu des propriétés de cette instance de Placeable Object.

4. Cochez les cases 'Plot', 'Useable' et 'Has Inventory'.

5. Cliquez sur 'Inventory' pour ouvrir le menu d'inventaire de l'object.

6. Selcetionnez 'Copper Ring' (Anneau de Cuivre) dans la catégorie 'Miscellaneous (Divers) / Jewelry (Joaillerie) / Rings (Anneaux) de la Palette Standard et déplacez le dans la partie 'Content' (Contenu).

Note: Pour retirer un item de l'inventaire, déplacez le de la partie 'Content' vers l'icône représentant une poubelle au bas de la fenêtre.

7. Faites un clique droit sur l'anneau dans la partie 'Content' pour ouvrir le menu de propriétés de cette instance de l'anneau. Changez le Tag en 'it_RingJacen'.

Note: Ce tag doit être le même que celui utilisé dans le tutorial précédent pour vérifier si le nœud 2 de la conversation de Falstadd apparaît.

8. Appuyez sur 'OK' pour fermer le menu des propriétés de l'item.

9. Appuyez sur 'OK' pour fermer le menu de l'inventaire.

10. Appuyez sur 'OK' pour fermer le menu des propriétés du Palceable.

Amulette de Protection +1

Ensuite, nous allons créer un nouveau blueprint pour une amulette de protection. Une instance de cette amulette sera placé dans le magasin pour que les PCs puissent l'acheter au début de l'aventure.

1. Sélectionnez 'Item Wizard' dans le menu 'Wizards' de la barre d'outil.

2. Sélectionnez 'Amulet' dans la liste 'Item Type' et cliquez sur 'Next'.

3. Tapez le nom de l'amulette, 'Amulette de Whyte', laissez la case 'Magical' non cochée et cliquez sur 'Next'.

4. Assignez l'amulette à la catégorie 'Special' / 'Custom 1' et cliquez sur 'Next'.

5. Cochez la case 'Launch Item Properties' (ouvrir les propriétés de l'item) et cliquez sur 'Finish'.

Page 30: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

6. Une fois que le menu de propriétés de l'item apparaît, sélectionnez l'onglet 'Properties'.

7. Trouvez la propriété 'AC Bonus' dans la liste sur le côté gauche et assignez la à l'amulette en cliquant sur bouton '->'.

8. Cochez la case 'Identified' (Identifiée).

9. Allez dans l'onglet 'Description' et entrez quelques détails à propos de l'amulette magique.

Astuce: Le texte dans 'Unidentified Description' apparaît lorsque l'item n'est pas identifié. Le texte dans 'Identified Description' apparaît après que l'item ait été identifié. Vous pouvez utiliser les deux pour donner des informations aux joueurs sur l'objet qu'ils ont acquis.

10. Appuyez sur 'OK' pour fermer le menu des propriétés de l'item. Vous remarquerez que l'amulette apparaît dans la palette 'Custom Item'.

Utiliser les Merchant Objects

Les Merchants sont quelque peu différents. Ils ressemblent à des Waypoints, mais ils ont des inventaires comme les Creatures ou les Placeables.

1. Ouvrez l'area Fern.

2. Ouvrez la palette 'Standard Merchant' (cinquième bouton en partant de la gauche dans la ligne du dessous – il ressemble à un sac d'or).

3. Sélectionnez le premier blueprint 'General Store' (marchandises générales) et peignez une instance de celui-ci près de l'instance de Veran.

Note: Le lieu où se trouve l'instance de Merchant n'a pas réellement d'importance parce que les joueurs n'ont pas d'interactions directes avec elle. A la place, les joueurs activent une instance de Merchant au travers d'une Creature, Door, Placeable, ou Trigger. Par souci d'organisation, il vaut mieux, en général, les placer près de l'Object par lequel le joueur peut les activer.

4. Sélectionnez 'Properties' dans le menu contextuel de l'instance su Merchant pour ouvrir le menu de propriété du Merchant.

5. Changez le Tag en 'mt_Veran'.

6. Ajustez le champ 'Sell Markup' à 1. Ceci fait que le Merchant vendra les items pour 1% de leur coût réel.

Note: Généralement, les marchands achètent les items à une partie de leur coût (< 100%) et vendent les items pour un profit (>100%). Ici, le marchand vend et achète les items pour 1% de leur coût réel.Attention: Les Merchants ne commerceront jamais à perte. Le Sell Mark Up doit toujours excéder (ou être égal) au Buy Mark Down (Pourcentage du coût réel auquel l'objet est vendu)

7. Cliquez sur 'Inventory' pour ouvrir les propriétés de l'inventaire de l'instance du Merchant.

8. Trouvez Amulette de Whyte, créée précédemment, dans la palette 'Custom Item' et déplacez la dans la partie 'Content'. Le Toolset va automatiquement ajouter une instance du blueprint de l'item à l'inventaire du Merchant, et le sélectionner (affichant l'onglet du magasin où il pourra être trouver).

Note: La section 'Options' de ce menu indique les prix d'achat et de vente (combien le marchand paiera ou demandera pour l'item). Avec un 'Sell Markup' de 1%, l'Amulette de Whyte, qui a un coût d'environ 600 pièces d'or), coûtera seulement 6 pièces d'or.

9. Appuyez sur 'OK' pour fermer le menu de l'inventaire.

10. Appuyez sur 'OK' pour fermer le menu des propriétés du Merchant.

Page 31: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Ouvrir un magasin

Enfin, le Merchant doit être activé par une action entreprise par le joueur. Le plus simple est de l'attacher à une conversation.

1. Ouvrez la conversation Veran dans la liste des conversations, située dans la partie listant le contenu du module, en sélectionnant 'Edit' dans son menu contextuel.

2. Sélectionnez le noeud 4 ("Oui, s'il vous plaît."). Dans l'onglet 'Action Taken', cliquez sur le bouton du Script Wizard.

3. Cochez la case 'Perform an Action" (Réaliser une action) et cliquez sur 'Next'.

4. Sélectionnez le bouton radio 'Start a Merchant' et entrez le Tag 'mt_Veran'.

5. Cliquez sur 'Next', nommez le script 'at_veran01', et cliquez sur 'Finish'.

Sauvegardez la conversation, fermez le Conversation Editor, sauvegardez le module et vérifiez si tou fonctionne en jeu.

Pour aller plus loin

Modifiez l'instance de Veran et déplacez la dague de sa main droite vers son inventaire. Créez un item Book (Livre) divulguant des détails à propos du "Plan" ainsi que l'existence d'un allié dans la ville. Placez cette note sur Gnashgab pour que les PCs la trouvent. Après avoir placé l'item dans l'inventaire de Gnashgab, sélectionnez le et cochez la case 'Droppable' (pour qu'il soit "lâché" par terre lorsque Gnashgab meurt).

Atmosphere

Introduction

Grâce à une utilisation intelligente de l'éclairage et des sons, une area qu'un joueur a déjà visitée et avec laquelle il est familier, peut être transformée en quelque chose de complètement nouveau et méconnaissable. Ce chapitre explique les bases pour manipuler les éclairages et les paramètres sonores d'une area.

Objectif

A la fin de ce tutorial, les areas de Fern et de la Mine de Fernesk seront éclairées correctement et possèderont des sons et des Sound Objects.

Tutorial

Eclairage d'area: Fern

Cette partie du tutorial va vous montrer comment ajuster l'éclairage à l'échelle d'une area.

1. Démarrez le Toolset et chargez le module "tutorial".

2. Ouvrez l'area Fern. Assurez vous que l'affichage de l'area utilise l'éclairage de l'area en vérifiant l'option 'Area Lightning' dans le menu 'Environment' de la barre d'outil.

Page 32: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

3. Dans la liste des areas, situées dans la partie listant le contenu du module, sélectionnez 'Properties' dans le menu contextuel de l'area Fern, ou cliquez sur 'Area Properties' dans le menu 'Edit' de la barre d'outil.

4. Dans l'onglet 'Visual' (Visuel), cliquez sur 'Exterior, Sunset' (Extérieur, Coucher de Soleil), puis cliquez sur 'Apply'. Vous remarquerez que l'éclairage de l'area devient joliment orange.

5. Ce n'est pas encore assez sinistre, l'éclairage principal du soleil doit être atténué. Cliquez sur 'Customize Environment' (Personnaliser l'Environnement) pour ouvrir le menu d'options de l'environnement.

6. Changez 'Sun Diffuse Color' (Couleur diffusée par le soleil) en cliquant sur la case colorée. Ceci ouvre la menu de couleurs. Cliquez sur 'Define Custom Color' (Définir une couleur personnalisée) et entrez les valeurs suivantes: Pour Red (Rouge) 100, Green (Vert) 150, Blue (Bleu) 160.

7. Cliquez sur 'OK' pour fermer le menu de Couleur, Cliquez sur 'OK' pour fermer le menu d'options de l'environnement, puis cliquez sur 'OK' pour fermer le menu des propriétés de l'area.

8. Pour voir complètement l'effet de l'éclairage, il est important d'activer le Fog (brouillard). Par défaut, le brouillard n'est pas montré dans le Toolset. Sélectionnez 'Fog' dans le menu 'Environment'.

Note: Selon la distance du sol à laquelle se trouve la caméra, l'area peut sembler partiellement ou complètement voilée par le brouillard. Si nécessaire, zoomez en avant pour voir un peu mieux.

9. La dernière étape est d'ajouter quelques effets du climat. Ouvrez à nouveau les propriétés de l'area Fern. Dans l'onglet 'Visual', cliquez sur 'Customize Environment'.

10. Mettez 'Weather - % Rain' à 100. Ceci signifie qu'il y a 100% de chance qu'il pleuve (il pleut toujours) lorsque les joueur entre dans cette area.

Note: Les effets du climat ne sont pas visibles dans le Toolset.

11. Cliquez sur 'OK' pour fermer le menu d'options de l'environnement, puis cliquez sur 'OK' pour fermer le menu des propriétés de l'area.

Enregistrez le module et vérifiez les modifications en jeu.

Eclairage de Tile: La Mine de Fernesk

L'éclairage à l'échelle d'une area fournit un moyen de régler l'ambiance générale d'une area. Cependant, il existe des cas pour lesquels il est important d'attirer l'attention des joueurs sur une partie de l'area en particulier. C'est dans ces cas-là que l'éclairage de Tile est utile.

1. Démarrez le Toolset et chargez le module "tutorial".

2. Ouvrez l'area Mine de Fernesk. Le Toolset devrait encore montrer l'éclairage d'area, vérifiez le menu 'Environment' ou la barre d'outils si nécessaire.

3. Ouvrez le menu des propriétés de l'area et allez dans l'onglet 'Visual'. Sélectionnez 'Interior Dark' (Intérieur Sombre) et cliquez sur 'OK'. L'area devrait être beacoup plus sombre maintenant.

4. Centrez la caméra sur Gnashgab en sélectionnant la créature dans a liste du contenu du module et cliquez sur 'Focus on Object' (Centrer sur l'object) dans son menu contextuel.

5. Changez manuellement le mode de sélection en sélection du terrain, en cliquant sur 'Select Terrain' dans le menu 'View / Selection Mode'.

6. Sélectionnez 'Tile Properties' dans le menu contextuel du tile où Gnashgab et les autres objects sont placés. S'ils sont sur différents tiles, répétez simplement la prochaine étape pour chaque tile.

Page 33: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

7. Le menu de propriétés du tile devrait s'ouvrir. Cliquez sur la couleur assignée à 'Main Light 1' (Eclairage principal 1) pour ouvrir le menu de sélection de couleur. Sélectionnez la couleur orange (en bas à droite) et cliquez sur 'OK'.

Astuce: La valeur RGB apparaît si vous laissez le curseur de votre souris sur la couleur sans bouger pendant 1 à 2 secondes.

8. Cliquez sur 'OK' pour fermer le menu des propriétés du tile.

9. Trouvez la pièce avec le Mineshaft (excavation). Si nécessaire, désactivez l'utilisation de l'éclairage de l'area jusqu'à ce que vous trouviez.

10. Réactivez l'éclairage de l'area, sélectionnez le tile avec le Mineshaft et changez sa 'Main Light 1' en gris (première ligne, troisième en partant de la gauche).

11. Enfin, modifiez les propriétés du tile de la sortie, là où les PCs entrent dans la mine. Changez la 'Main Light 1' en vert clair (seconde lige, troisième en partant de la gauche).

Note: Changer l'environnement général 'écrase' toutes modifications faites aux propriétés d'un tile en particulier.

Enregistrez le module et vérifiez les modifications en jeu.

Sons ambiants / Musique: Fern

Les sons ambiants sont utilisés dans le même esprit que l'éclairage des zones. Ils aident à définir l'ambiance et ton général de l'area.

1. Démarrez le Toolset et chargez le module "tutorial".

2. Ouvrez les propriétés de l'area Fern.

3. Dans l'onglet 'Audio', dans la partie 'Ambient Sound Day', sélectionnez 'Town, Day – Sparse' et dans la partie 'Ambient Sound Night', sélectionnez 'Town, Night.

Note: L'important avec la 'main area ambient track' (piste principale d'ambiance de l'area) est qu'elle aide à renforcer l'ambiance. Vous pouvez avoir deux fois la même area, l'une avec des bruits de forêt effrayants, des bruits de branches qui craquent, et une autre avec un léger bruit de vent soufflant plaisamment dans les feuilles, et créer deux ambiances complètement différentes.

4. Dans l'onglet 'Audio' des propriétés de l'Area, vous trouverez aussi des options pour les pistes musicales de jour, de nuit et de combat (Day, Night, et Battle Music Tracks). Laissez ces dernières en l'état pour l'instant, celles par défaut sont suffisantes.

5. Cliquez sur 'OK' pour fermer le menu des propriétés de l'area.

Astuce: Pour entendre les sons et les musiques dans le Toolset, sélectionnez les options 'Play Ambient Sound' et 'Play Ambient Music' dans le menu 'Evironment' ou cliquez sur les boutons correspondants dans la barre d'outil.

Reproduisez le même processus pour la Mine de Fernesk. Sélectionnez des pistes d'ambiance et des pistes musicale adaptées si celle par défaut ne sont pas appropriées. Cependant, comme il s'agit d'une area d'intérieur, la Mine de Fernesk n'a pas vraiment de cycle jour / nuit, aussi il vaut mieux jouer les même sons pour le jour et la nuit.

Sound Objects: Mine de Fernesk

Tout comme l'éclairage des tiles, les Sound Objects aident à attirer l'attention des joueurs et servent à mettre en valeur certaines parties d'une area. Placer des sons qui sous-entendent un mouvement ou une action mais qui ne peuvent être vus, peuvent vraiment donner vie à une area. Ceci peut être réalisé grâce à des sons s'exécutant une seule fois ou en boucle.

Page 34: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

1. Ouvrez l'area de la Mine de Fernesk.

2. Ouvrez la palette 'Sound Objects' (Troisième bouton en partant de la droite).

3. Sélectionnez 'Entrance Scary' (Entrée Effrayante) dans la catégorie 'Magical' et peignez la près de l'entrée de la mine. Vous remarquerez deux sphères concentriques. Zoomez un petit peu pour mieux voir l'object. Il ressemble à une note de musique posé sur une flèche.

4. Il y a beaucoup de choses à dire là-dessus. Ce sound object est "positionnel" – le son sera entendu comme s'il provenait d'un endroit spécifique. La sphère extérieure indique la distance maximale à laquelle le son peut être entendu, alors que quelque soit l'endroit de la sphère intérieure, le son y sera joué à son volume maximal. Le volume augmente progressivement lorsque le joueur se déplace de la sphère extérieure vers la sphère intérieure.

Astuce: Il peut être nécessaire de désactiver les sons et les musiques d'ambiance lorsque vous travaillez avec les sound objects.

5. Sélectionnez 'Water Drips' dans la catégorie 'Nature'. Peignez le au centre des rails? près de l'entrée de la pièce avec l'excavation. Celui-ci est un son "positionnel aléatoire" – le son sera entendu comme s'il provenait d'un endroit spécifique, mais cet endroit changera à chaque fois que le son sera joué.

6. La boîte indique la zone d'où pourra sembler provenir le son, et les sphères représentent les mêmes choses que pour les sons positionnels standards.

7. Sélectionnez 'Properties' dans le menu contextuel de ce sound object. Dans l'onglet 'Positioning', Mettez 'Random Range' (Limites de la zone aléatoire) à '70m North-South' (70 mètres Nord-Sud) et '5m East-West' (5 mètres Est-Ouest). Ceci devrait être assez pour couvrir les rails? sur toute leur longueur. Cela signifie que le son semblera apparaître depuis n'importe quel endroit à l'intérieur de la boîte.

8. Dans l'onglet 'Advanced', mettez l' 'Interval' à 8.00 secondes, et l' 'Interval Variation' à 2 secondes. Tout cela nous donnera un son qui pourra provenir de n'importe où dans la limite définie toutes les 6 à 10 secondes.

Note: Comme le volume n'est pas aussi élevée que la distance (Range), il est possible que les joueurs n'entendent pas le son à chaque fois.

9. Sélectionnez 'Miner Pickings' dans la catégorie 'Civilization'. Peignez le n'importe où dans l'area (près de l'entrée est généralement un bon endroit). Celui-ci est un son "général à l'area", c'est à dire qu'il ne semblera pas provenir d'un endroit précis.

10. Sélectionnez 'Properties' dans le menu contextuel de ce sound object. Dans l'onglet 'Basic', mettez le volume aux alentours de 7.

11. Dans l'onglet 'Advanced', mettez l' 'Interval' à 5 et l' 'Interval Variation' à 2.Astuce: Le but de l'utilisation de sons est de renforcer l'intrigue et l'atmosphère pour le joueur, de créer l'illusion d'actions qui n'ont pas réellement lieu dans le jeu, ainsi que d'attirer l'attention sur des gens, des lieux ou des objets grâce à des indices auditifs.

12. Sélectionnez 'Rope and Pulley Squeaks' (Grincements de cordes et de poulies) dans la catégorie 'Civilization'. Peignez en une instance près de l'entrée. Vous remarquerez qu'il est déjà configuré pour être un son positionnel aléatoire, mais dans le cas précis, il devrait être général à l'area.

13. Sélectionnez 'Properties' dans le menu contextuel de ce sound object. Dans l'onglet 'Basic', mettez le volume aux alentours de 7.

14. Dans l'onglet 'Positioning', sélectionnez 'Plays everywhere in Area' (jouer partout dans l'area).

15. Dans l'onglet 'Advanced', mettez l' 'Interval' à 10 et l' 'Interval Variation' à 3.Astuce: Equilibrez les sons dans l'area en ajustant les distances et volumes, pour que l'ensemble semble sonner naturellement. C'est à dire, par exemple, ne pas avoir une chant d'oiseau lointain au volume maximal

Page 35: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

alors que le volume du son d'une chute d'eau est proche de zéro. Si les sons de l'area sont équilibrés de manière adéquate, il sera plus facile pour les joueurs de différencier ceux qui sont importants de ceux qui sont là pour renforcer l'ambiance.

Pour aller plus loin

Ajoutez d'autres sons que vous vous attendriez à entendre dans une mine, tels que des chauve-souris.Add some other sounds you might expect to hear in a mine, such as bats.

Note: Un son qui ne s'exécute qu'une seule fois (single-shot) ne sera joué qu'une seule fois et possède un début et une fin définis.

Note: Gardez à l'esprit qu'il est aussi possible d'utiliser trop de sons dans une area et de la rendre fouillis. En ce qui concerne l'audio, le plus est parfois l'ennemi du mieux. Essayez de varier les durées entre les moments où les sons sont joués et les moments de silence pour donner une impression plus réaliste à une area.

Ajoutez les sons appropriés à l'area de l'auberge si elle a été créée.

Scripts

Introduction

Le langage NWScript est très puissant, et vous permet de réaliser des choses vraiment étonnantes. Le jeu tente d'exécuter un script sur une instance d'un object à chaque fois qu'un Event (évènement) particulier a lieu. Les instances de chaque type d'object du jeu ont une série d'events auxquels peuvent être attachés des scripts. De plus, chaque area et le module lui même ont des events particuliers. Il n'est pas nécessaire qu'un script soit attaché à chaque event du jeu. Le but de ce chapitre est d'introduire les bases du langage NWScript et du Script Editor du Toolset.

Objectifs

Attachez une script personnalisé à l'even onAcquireItem (A l'Acquisition d'un Item) qui mettra à jour le journal d'un joueur lorsque celui-ci ramasse l'anneau de Jacen.

Tutorial

OnAcquireItem Script

1. Démarrez le Toolset et chargez le module "tutorial".

2. Sélectionnez 'Module Properties' dans le menu 'Edit' pour ouvrir le menu de propriétés du module.

3. Cliquez sur le bouton 'Edit' de la ligne 'OnAcquireItem' dans l'onglet 'Event' pour ouvrir le Script Editor avec un nouveau script.

4. Remplacez le contenu original du script par le texte suivant:

void main(){ // déclaration des variables object oPC; // le PC qui acquiert l'item object oItem; // l'item qui a été acquis // récupérer l'item qui a été acquis oItem = GetModuleItemAcquired(); // si cet item est un objet valide if (GetIsObjectValid(oItem) == TRUE)

Page 36: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

{ // si le tag de l'item valide est "it_RingJacen" if (GetTag(oItem) == "it_RingJacen") { // récupérer le PC qui a acquis l'item oPC = GetItemPossessor(oItem); // amener le journal avec le tag "jt_Falstadd" à sa seconde entrée pour ce PC AddJournalQuestEntry("jt_Falstadd", 2, oPC); } // si } // si}

5. Enregistrez le script sous le nom 'me_acquireitem' et fermez le Script Editor.

Note: Un avertissement devrait apparaître, disant que les scripts doivent être compilés avec qu'il fonctionnent dans le jeu. A mois que cette option ne soit désactivée (ce qui est déconseillé), le Script Editor compilera automatiquement chaque script modifié.

6. Cliquez sur 'OK' pour fermer le menu de propriétés du module.

Un Script "Action Taken" Personnalisé

1. Ouvrez la conversation de Falstadd en sélectionnant 'Edit' dans son menu contextuel.

2. Sélectionnez le noeud 3 ("Je vous remercie..."). Dans l'onglet 'Action Taken', cliquez sur le bouton du ScrptWizard.

3. Cochez la case 'Give Rewards' (Récompenser) et cliquez sur 'Next'.

4. Tapez '2000' (basé sur la valeur entrée dans le Journal Editor pour cette quête) dans le champ 'Give XP' (Donner des XP), cochez la case 'Give To Party' (Donner à tout le groupe) située en-dessous et cliquez sur 'Next'.

5. Nommez le script 'at_falstadd03', cochez la case 'Start the Script Editor' (Ouvrir le Script Editor) et cliquez sur 'Finish'.

6. Une fois le Script Editor ouvert, le script devrait ressembler à cela:

void main(){ // Donner des XP au joueur qui parle GiveXPToCreature(GetPCSpeaker(), 2000);}

7. Le seul problème avec ceci est que lorsque la montant de la récompense spécifié pour cette quête dans le Journal Editor change, ce script doit être changé et recompilé aussi. Une meilleure façon de procéder serait de déterminer le montant d'expérience actuellement assigné à la catégorie du journal lorsque le module est joué et utilisé ce dernier à la place. Ceci nécessite d'écrire un script qui ressemble à ceci.

void main(){ // déclaration des variables int iXP; // Déterminer à combien d'XP s'élève la récompense de cette quête iXP = GetJournalQuestExperience("jt_Falstadd"); // give the speaker some XP GiveXPToCreature(GetPCSpeaker(), iXP);}

8.Après que le script ait été modifié, sauvegardez le, fermez le Script Editor, sauvegardez la conversation et fermez le Conversation Editor.

Sauvegardez le module, fermez le Toolset et essayez de tester le module du début à la fin.

Page 37: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Pour aller plus loin

Créez une conversation pour les mineurs. Le mineur à qui parle le PC devrait être reconnaissant pour avoir été secouru, et le PC devrait leur dire de quitter la mine immédiatement. Le PC devra être récompensé de 50XP et le mineur devrait alors se dirigeait vers la sortie et retourner à Fern. Si le PC parle à nouveau au mineur, ce dernier devrait le remercier à nouveau mais sans réaliser d'actions supplémentaires (pas de récompense en XP, ni de déplacements).

Ceci devrait être possible en créant trois scripts, dont 2 avec le Script Wizard (ne requérant que de légères modifications) et un fait "à la main". D'abord créez la conversation. Elle sera similaire à celle de Falstadd, dans le sens où la première fois qu'un PC lui parle, il dira une chose, puis lors des tentatives suivantes, il devra dire autre chose.

Les deux scripts qui contrôlent ce que le mineur dit devrait définir et vérifier une variable local du mineur. Ces scripts devraient être créés avec le Script Wizard, comme dans le chapitre 6 et modifiés de façon à utiliser la constante OBJECT_SELF à la place de la fonction GetPCSpeaker(). OBJECT_SELF renvoie simplement l'object qui exécute le script, dans ce cas le mineur. Ceci permet au PC de secourir plusieurs mineurs et de recevoir une récompense pour chaque. Si la variable était placée sur le PC, seul un mineur pourrait être secouru puisque la vérification sur les mineurs suivants indiquerait que le PC leur aurait déjà parlé.

Le troisième script devrait être lancé depuis une 'Action Taken' d'un nœud de conversation qui est uniquement accessible la première fois que le PC parle avec le mineur. Ce script devrait récompenser le PC de 50XP et ensuite faire que le mineur se déplace vers la sortie, puis vers la ville. La façon la plus simple pour déplacer une créature et de la faire se déplacer vers une Location ou un Object. Utilisez les fonctions GetObjectByTag, AssignCommand et ActionMoveToObject pour faire courir le mineur vers Falstadd.

N'oubliez pas d'utiliser OBJECT_SELF comme il faut et d'assigner la conversation au blueprint de mineur.

Et maintenant ?

Vous pouvez vérifier régulièrement http://nwn.bioware.com/builders pour plus d'informations sur la création d'aventures.

Comment Faire: Une Quête Simple dans Neverwinter Nights

Introduction

Il s'agit peut-être de la quête la plus simple que vous puissiez imaginer – un PC rencontre un NPC, le NPC a perdu un objet, le PC récupère l'objet, le NPC est content, et récompense le PC. Ceci devrait être trivial à faire avec le NWN Toolset. Mais attendez! On dirait que cela nécessite d'écrire des scripts! Argh! Je n'y connais rien en programmation!! Que puis-je faire ? Qui peut aider ? Il n'y a aucune documentation! PANIQUE!

N'ayez crainte – l'aide est à portée de main!

Le NWN Toolset possède une série de "Wizards" qui automatisent les tâches simples à scripter, ainsi il n'est pas nécessaire de savoir comment écrire des scripts pour créer des interactions dynamiques de NPC, et créer des quêtes. Pour vous mettre dans le bain, ce tutorial a pour but de décrire comment réaliser une simple quête du style 'Va chercher!' en utilisant uniquement les "Wizards", et sans écrire une seule ligne de code.

Pré requis

Comme tout tutorial, je dois partir du principe que vous avez certaines connaissances. J'ai essayé de le rendre abordable par tout le monde, mais il existe certains concepts que vous ne pouvez ignorez pour comprendre la suite. Par exemple, je pars du principe que vous en savez un petit peu sur les

Page 38: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

scripts – vous n'avez pas besoin de savoir comment écrire un script, mais vous devez être au moins familier avec:

Les Variables – ce que sont les variables. Si vous n'avez vraiment jamais été en contact avec la programmation, cela risque d'être un peu difficile. Vous trouvez des informations élémentaires sur le site NWVault, qui contient une très bonne introduction à la programmation/écriture de script en général.

Les Tags – Les "Objects" dans NWN ont des tags. Le nom d'un tag est sensible à la casse (NdT: il différencie les majuscules des majuscules, ainsi Wizard, wizard et WIZARD sont 3 tags différents), et ne nécessitent pas d'être uniques. Dans ce tutorial, vos tags devront cependant être uniques.

Le Toolset – Vous devez savoir comment "peindre" des zones(areas) et ajoutez des NPCs et des "items" à vos zones(areas)

Le "Conversation Editor" – La plupart de ce que vous aurez à faire se fera avec le "Conversation Editor", vous devez savoir comment ajouter des nœuds et comprendre ce que 'racine', 'parent', et 'enfant' signifie dans ce contexte. (NdT: Si vraiment tout cela ne vous rappelle absolument rien, il est temps de relire le tutorial sur les dialogues de Lumina)

Si vous êtes déjà découragé, ne le soyez pas! Continuez à lire et voyez si vous arrivez à suivre ce dont je parle. Les concepts qui sont un peu flous pour l'instant pourraient devenir plus clairs au fur et à mesure que vous progressez dans le tutorial.

Tutorial

Préparation

Vous êtes sur le point de construire une quête pour un NPC, Plott de Vice. Il a perdu son Machinchose de Destruction, et veut que vous alliez le récupérer pour lui. Avant que nous ne commencions, créez Plott et le Machinchose, et placez Plott dans une zone (area). Placez un Machinchose dans la zone (area) aussi et donnez lui pour tag itemPlottMachinchose. Nous allons aussi avoir besoin d'une variable pour garder une trace de la progression de notre quête, aussi décidons tout de suite que ce sera un "integer" (nombre entier),iPlottQuete.

Planification

Il s'agit peut-être d'une quête triviale, mais nous devons quand même la planifier un minimum. Nous devons déterminer quelles seront les différentes étapes de la quêtes, et comment nous allons les représenter avec notre variable de progression de quête. Nous déciderons à l'avance que iPlottQuete pourra avoir 3 valeurs potentielles:

0 – La quête n'a pas été donnée au PC (par défaut) 100 – La quête a été donnée au PC, mais il ne l'a pas achevée. 200 – Le PC a achever la quête, et ne peut pas la refaire une nouvelle fois.

Débuter la conversation

Le noyau de la quête est la conversation que le PC a avec Plott de Vice. Normalement, vous prépareriez l'arbre de dialogue à l'avance, et construiriez tous les nœuds de dialogue avant d'ajouter les scripts avec les "Wizards". Nous ferons cela en deux étapes, cependant, dans le but de mieux illustrer le mécanisme. Pour commencer, éditez les propriétés de Plott (clique droit sur Plott et choisissez "Properties") et cliquez sur "Edit" juste à côté du champ "Conversation" dans l'onglet "Basic". Ceci ouvrira le "Conversation Editor" avec un nouveau fichier de dialogue. Ajouter ces trois nœuds à la racine:

Page 39: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Notez que l'ordre des branches du dialogue semble inversé. En effet, lorsqu' il est confronté à des choix multiples pour un NPC dans le même niveau de conversation, le jeu choisira la première branche de dialogue, soit qui n'a aucun script dans l'onglet "Text Appears when...", soit dont le script dans l'onglet "Text Appears When..." renvoie TRUE (Si vous n'avez aucune idée de ce que cette dernière partie signifie, ne vous inquiétez pas, le "Wizard" s'en occupera tout seul). Ce que cela signifie, en pratique, c'est que vos dialogues commenceront fréquemment par la fin de la quête, progressant à rebours vers le commencement.

Pour faire varier le texte qui apparaît lorsque quelqu'un parle au NPC, nous devons définir des conditions sur les deux premiers nœuds du dialogue. En d'autres mots, nous devons décrire les conditions qui doivent être vraies pour que le texte apparaisse. Le premier nœud ne devrait apparaître que lorsque la quête est achevée, et c'est lorsque la variable iPlottQuete est égal à 200. Configurons cela avec le "Wizard":

Note à propos du nom des scripts

Pour cet exemple, le nom des scripts est sans importance, et si vous comptez n'utiliser que les "Wizards" lorsque vous créez un module, vous pouvez vous permettre d'accepter les noms par défaut et de les oublier. Mais pour des projets plus importants, vous devrez décider d'un code de dénomination pour vos scripts, de façon à être capable de les identifier rapidement. Vous risquez probablement d'en avoir un très grand nombre.

1. Sélectionnez le premier nœud (Encore merci...)2. Cliquez sur l'onglet 'Text Appears When...' en bas à droite du "Conversation Editor"3. Cliquez sur le bouton avec un chapeau de magicien pour lancer le "Script Wizard"4. Cochez la case 'Local Variable', et cliquez sur 'Next'5. Tapez le de la variable locale (iPlottQuete) dans la case en haut à droite6. Tapez la valeur que doit avoir iPlottQuete (200) dans la case en bas à gauche.7. Cliquez sur 'Add'. Vous devriez voir apparaître une ligne de code dans la case 'Local

Expressions', qui dit: GetLocalInt( GetPCSpeaker(), "iPlottQuete") == 2008. Cliquez sur 'Next', appelez le script 'dlg_plott_01' et sauvegardez le.

Le "Wizard" a généré un script de façon à ce que la première branche du dialogue n'apparaîtra que si le PC a achevé la quête. Vous n'avez pas besoin de modifier ce script, mais si vous voulez en apprendre plus sur l'écriture de script, un bon moyen de commencer est lire les scripts générés par le "Wizard", et déchiffrer ce qu'ils font et comment ils le font. Pour compléter notre conversation à l'étape intermédiaire de la quête, répéter le processus ci-dessus avec la ligne de dialogue Avez-vous trouvé..., en remplaçant la valeur 200 par 100

Achever la quête

Maintenant, vous devez complétez la conversation pour donner au PC quelques possibilités de réponses. Le PC doit avoir la possibilité d'accepter la quête, et de dire 'Oui' lorsqu'il possède le machinchose. Ajouter des branches au dialogue pour qu'il ressemble à l'arbre de dialogue ci-dessous. Vous pouvez modifiez le texte comme vous le souhaitez, mais pour l'instant, laissez la structure de l'arbre exactement comme montrer sur l'illustration.

Page 40: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Il est temps de déclencher la quête – de changer l'étape de la quête du PC de 'Pas commencée' à 'No achevée', ou pour le dire autrement, d'attribuer la valeur 100 à iPlottQuete. Nous savons déjà quand faire cela, puisque nous avons notre conversation toute prête. La branche 'Ouais. J'reviens de suite avec' déclenche le départ de la quête (et demanderait à être réécrite mais ce n'est pas mon problème). Jusqu'à présent, nous avons uniquement effectué des tests sur la valeurs de iPlottQuete, maintenant nous allons devoir lui effectuer des modifications. Vous vous en doutiez, nous ferons cela dans l'onglet 'Action Taken'. Voici comment:

1. Sélectionnez le nœud Ouais. J'reviens de suite avec2. Cliquez sur l'onglet 'Action Taken'3. Cliquez sur le bouton avec un chapeau de magicien pour lancer le "Script Wizard"4. Cochez la case 'Set Local Variable', et cliquez sur 'Next'5. Tapez le de la variable locale (iPlottQuete) dans la case en haut à droite6. Tapez la valeur que vous voulez attribuer à iPlottQuete (100) dans la case en bas à gauche.7. Cliquez sur 'Add'. Vous devriez voir apparaître une ligne de code dans la case 'Local

Expressions', qui dit: SetLocalInt( GetPCSpeaker(), "iPlottQuete",100)8. Cliquez sur 'Next', appelez le script 'dlg_plott_02' et sauvegardez le.

Jusque là tout va bien. Nous venons juste d'arranger la quête de façon à ce que le PC puisse la commencer, et nous avons déjà le mécanisme tout prêt pour les différentes possibilités du dialogue, donc finissons la quête et distribuons parcimonieusement les récompenses. Tout est en place pour que le PC revienne après que la quête soit entamée, et qu'il se voit demandé Avez-vous retrouvé le Machinchose de Destruction ?. Partant du principe que e joueur moyen est fondamentalement malhonnête, et essaiera d'obtenir quelque chose sans rien faire, nous devons vérifier qu'il possède réellement le Machinchose de Destruction lorsqu'il choisit Oui. A l'heure actuelle, vous devriez avoir une idée assez précise sur la façon de vérifier cela avec le "Wizard". Il s'agit juste d'une variante du test de iPlotQuest, à la différence près que c'est plus facile. Les instructions complètes sont cachées ci-dessous, sélectionnez le texte avec votre souris pour les faire apparaître.

1. Selectionnez le nœud 'Oh merci, merci, merci...'2. Cliquez sur l'onglet 'Text Appears When...' en bas à droite du "Conversation Editor"3. Cliquez sur le bouton avec un chapeau de magicien pour lancer le "Script Wizard"4. Cochez la case 'Item in Inventory', et cliquez sur 'Next'5. Tapez le Tag du Machinchose de Destruction (itemPlottMachinchose) dans la case du haut6. Cliquez sur 'Add'. Le Tag devrait apparaître dans la case 'Currently required item tags'7. Cliquez sur 'Next'

A nous les récompenses!

Enfin, nous devons définir la quête comme achever pour le PC, et consentir à distribuer quelques récompenses. Toujours à la branche Oh merci, merci, merci..., utilisez le "Script Wizard" de l'onglet 'Action Taken'. Vous devez cocher 'Give Rewards', 'Take From Player' et 'Set Local Variable'. Chacun fournira son propre champ à remplir dans le Wizard. Ceci devrait être, maintenant, un territoire familier, donc je vous laisserai comme exercice de déterminer la récompense. N'oubliez pas d'attribuer

Page 41: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

la valeur représentant que la quête soit achevée à iPlottQuete. Si vous êtes toujours désespérément perdu, il y a une description pas à pas cachée à la fin du tutorial.

Vous avez fini!

C'est vrai... Si vous êtes toujours avec moi, vous avez maintenant une quête miniature à vous, et – avec un peu de chance – une idée de comment faire une entièrement tout seul. Tout ce qu'il vous reste à faire est de sauvegarder votre module, de la charger en mode "single player", et d'aller papoter avec votre NPC. Assurez vous bien de tester toutes les possibilités du dialogue... Un bon test est le secret d'un bon code!

Ceci une quête rudimentaire du style 'Va chercher!', qui nécessite pas une seule ligne de script à écrire. Vous devez comprendre quelques détails sur les variables et les tags, et vous devez être conscient que le "Conversation Editor" et le "Script Wizard" écrivent un tas de petits scripts dans les coulisses (vous verrez qu'ils ont déjà été ajoutés à votre module). Mais vous n'avez pas besoin d'écrire de scripts vous-même. Ce qui est cool.

Exercices pour le lecteur!

Voici quelques variantes, toutes pouvant être réalisables avec les "Wizards" et que vous pouvez essayer:

Vous avez donné de l'or et de l'expérience au PC... Comment améliorer sa réputation auprès de la faction du NPC ?

Donner au PC une chance d'insulter le NPC, et faire que cela diminue sa réputation auprès de la faction du NPC.

Ajouter une branche de dialogue : '<StartHighlight>[ Garder le Machinchose ] </Start>Nan... pas pu le trouver, juré!' au nœud 'Avez-vous trouvé...'. Ne la faites apparaître que lorsque le PC a le Machinchose... et ajoutez quelques conséquences au vol.

Rendre le NPC xénophobe: ne déclencher la quête que si le PC est de la même race. Ajouter une option de Persuasion pour les PCs qui essaient d'obtenir la quête du NPC

xénophobe. Faites en sorte que l'option de Persuasion n'apparaisse pas pour des PCs avec un faible

charisme. Comment feriez-vous une quête de type 'Va tuer!' ? (Coup de pouce: Scalp de bandit)

...et quelques uns qui nécessiteront l'écriture de scripts:

Et si Plott continuait à perdre son Machinchose ? Après sa destruction, faites le réapparaître à un autre endroit.

Créez un "blueprint" du Machinchose et faites le apparaître à un endroit aléatoire quand la quête est déclenchée.

Préparez une chasse aux oeufs de Pâques multi-joueurs.

Quelques astuces au sujet du "Conversation Editor"

Revenir à des noeuds précédents: Pour faire revenir une conversation à un nœud précédent en boucle, utilisez les liaisons (linking). Copiez le nœud auquel vous voulez retournez, et sélectionnez "Paste as a link". Note: Vous ne pouvez pas coller ainsi des liens au même niveau de dialogue que l'original.

Pour couper une longue description d'un NPC en de multiples nœuds, Ajoutez un nœud de dialogue et effacez tout le texte. Ajoutez un nœud à ce nœud vide, et le nœud vide se changera de '[END DIALOGUE] à '[CONTINUE]' dans l'éditeur. Le PC obtiendra ainsi l'option habituelle 'Continue' lors de la conversation.

Donner les récompenses... les secrets révélés!

Page 42: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Sélectionnez la case ci-dessous avec votre souris pour faire apparaître le texte caché.

Séectionnez le noeud 'Oh merci, merci..." Allez dans l'onglet 'Actions Taken' Cochez 'Give Rewards', 'Take From Player' et 'Set Local Variable', puis cliquez sur 'Next' Dans la partie 'Give what rewards?' assignez la récompense et decidez si tout le groupe ou juste le

PC reçoit la récompense, puis cliquez sur 'Next' Dans la partie 'Take what?', tapez "itemPlottMachinchose" (sans les guillemets) dans la case 'Take

item (by Tag)', et laissez 'Destroy' sélectionnez. Cliquez sur 'Next' Enfin, nous devons modifier notre varible de progression de quête une dernière fois. Assignez 200 à

'iPlottQuete', cliquez sur 'Add', puis sur 'Next', sauvegardez le script et c'est fini.

Creer un mercenaireArticle écrit par Anthony Affrunti

traduit par Théranthil

Conversation et scripts basiques pour un mercenaireVous devez être quelque peut familier avec le Conversation Editor du Toolset avant de suivre ce tutorial. Si vous ne l’êtes pas, je vous conseille fortement l’article d’Iskander HowTo qui introduit des concepts qui vous seront utile dans ce tutorial particulièrement dans la section « Starting the conversation »(le lien : Iskander's HowTo Article )

Au mimimum, vous voudrez un PC qui parle avec un NPC mercenaire et que ce NPC se joigne au PC, ou le quitte si le PC le veut. Un paiement est aussi une bonne idée. Vous voudrez aussi (souvent) que le mercenaire soit loyal, et prévienne le PC avant d’être loué par un autre PC et de quitter le premier PC !

Ce qui veut dire que le mercenaire doit avoir une structure de dialoque qui ressemble à ça dans votre Conversation Editor:

La première ligne apparaît uniquement si le PC l’emploi, et offre une branche de conversation qui permet au PC de changer les options avec le mercenaire(comme le renvoyer). Pour ceci, sélectionnez l’onglet Text Appears When puis sélectionnez « nw_ch_tactic2 » comme script pour cette ligne.

La seconde ligne du mercenaire apparaît uniquement si le mercenaire est employé, mais pas nécessairement par le PC. Cela permet au locuteur de savoir si le mercenaire est déjà employé par quelqu’un d’autre, et le préviendra de tout renvoie par le premier maitre. Pour celui ci, sélectionnez « nw_ch_tactics » dans l’onglet Text Appears When.

Si la première ou seconde ligne n’apparaît pas, cela veut dire que le mercenaire est libre, donc la troisième ligne apparaît, permettant au PC de le louer. Les options du PC doivent inclure choisir ou non de l’employer. Si vous voulez que le mercenaire coûte 100 po, vous pouvez créer ce script dans le Text Appears When du « Je veux vous employer » pour vérifier si le PC a assez d’argent: // * script: can_pay100

Page 43: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

// * Est ce que le PC a 100 pièces d’or?// Utilisez dans [Text Appears When] de la ligne adéquatre du dialogue.#include "NW_I0_PLOT"int StartingConditional(){ return (HasGold(100,GetPCSpeaker()));}

Puis pour payer le mercenaire, voici le script qui va dans Action Taken de la même ligne du dialogue: // * script: pay100// *enlève 100 po du PC.// A utiliser dans [Actions Taken] de la ligne adéquate.void main(){ TakeGoldFromCreature(100, GetPCSpeaker(), TRUE);}

Maintenant, pour que le mercenaire se joigne au PC, ajoutez ce script dans [Actions Taken] de la ligne ou le mercenaire accepte: // * script: henchman_joins// * NPC mercenaire rejoint le PC, remplaçant un autre mercenaire si nécessaire.// Utilisez dans [Actions Taken] à la ligne ou le mercenaire rejoint le PC.#include "nw_i0_henchman"void main(){ if (GetIsObjectValid(GetHenchman(GetPCSpeaker())) == TRUE) { SetFormerMaster(GetPCSpeaker(), GetHenchman(GetPCSpeaker())); object oHench = GetHenchman(GetPCSpeaker()); RemoveHenchman(GetPCSpeaker(), GetHenchman(GetPCSpeaker())); AssignCommand(oHench, ClearAllActions()); } SetWorkingForPlayer(GetPCSpeaker()); SetBeenHired(); ExecuteScript("NW_CH_JOIN", OBJECT_SELF);}

Finallement, pour permettre au PC de renvoyer le mercenaire, nous allons ajouter l’option dans la ligne de la branche de dialogue où le mercenaire est renvoyé.

Nous ajoutons ce script dans le Action Taken de la lligne ou le mercenaire dit au revoir: // * script: henchman_leaves// * NPC mercenaire quitte le PC.// * A utiliser dans [Actions Taken] de la ligne ou le mercenaire part#include "nw_i0_henchman"void main(){ SetFormerMaster(GetPCSpeaker(), OBJECT_SELF); RemoveHenchman(GetPCSpeaker()); ClearAllActions();}

Nous savons tout ce que nous avons besoin de savoir pour la conversation avec le mercenaire lui même. Nous allons maintenant créer le mercenaire lui même dans le Creature Wizard (ou copier une créature déjà crée) et ajouter quelques étapes supplémentaires.

Page 44: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Onglet Basic - Conversation: Utilisez le dialogue que nous venons de créer en l’étoffant un peu si nécessaire.

OngletAdvanced - Sound Set: Soyez sur de lui assigner un set de sons qu’il puisse dire en entier. Ca peut être n’importe lequel des mercenaires de la campagne officielle, ou un set de sons commencant par « Male… » ou « Female… »

Inventaire – Quelques bonnes potions de soin sont indispensables. Si vous voulez qu’il ait une arme normalement non accessible pour son niveau (comme un arc avec des flèches illimitées comme ça ils n’en ont pas besoin), créez l’arme comme un objet de créature (creature item), mais quippez le dans l’emplacement normal des armes. Dans la campagne officielle, il y a aussi des objets avec des propriétés cachées qui immunusent les mercenaires contre Charme personne, domination et charme de masse. Personnellement, je préfère que mes mercenaires ne soient pas des sur hommes, c’est pourquoi je ne leur donne pas des objets spéciaux.

Onglet Scripts – mettez les scripts indiquez: OnBlocked: nw_ch_aceOnCombatRoundEnd: nw_ch_ac3OnConversation: nw_ch_ac4OnDamaged: nw_ch_ac6OnDeath: nw_ch_ac7OnDisturbed: nw_ch_ac8OnHeartbeat: nw_ch_ac1OnPerception: nw_ch_ac2OnPhysicalAttacked: nw_ch_ac5OnRested: nw_ch_aca *OnSpawn: nw_ch_ac9OnSpellCastAt: nw_ch_acbOnUserDefined: nw_ch_acd

* Note: Le script OnRested (nw_ch_aca) peut être non existant, donc c’est une bonne idée de laisser l’emplacement vide, spéciallement si vous pensez exporter votre mercenaire.

Il y a une astuce pour remplacer tous les scripts par défaut – surlignez le texte « nw_c2_default » dans chaque emplacement (enlevez la dernière lettre ou le dernier chiffre) et copiez « nw_ch_ac » à la place.

Maintenant, nous avons un mercenaire basic qui suit le PC. Il se joint à votre cause, contribut avec ces compétences, écoute les ordres, vous quitte quand vous lui demandé et peut être réemployé. Il ne monte pas de niveau, et quand il meurt il ne réapparait pass, il reste mort (mais peut être réssucité. Je préfère que les mercenaires soient comme ça, mais si vous êtes un bon scripteur, vous pouvez regarder dans le script nw_i0_henchman et le script OnDeath du mercenaire. Vous pouvez ainsi utiliser des options dans votre propre module. Ainsi, notez que pour que votre mercenaire passe de niveau, vous devez en faire une copie.

Vous pouvez télécharger un fichier de conversation avec le mercenaire en anglais (henchman conversation voici le lien). C’est un fichier .erf que vous pouvez importer dans votre propre module, qui contient les conversations aussi bien que les sscripts utilisés dans ce tutorial, et qui ajoute d’autres options tactiques non décrites dans ce tutorial.

Creer une trappe secrete

Page 45: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

de Robert BabiakTraduit par Kemay

ResumeAssurez vous de jeter un oeil au tutorial Hidden Wall Door (NdT: en cours de traduction) qui utilise un nouveau type de porte!

Aucun donjon n'est vraiment complet sans ces malicieuses portes secrètes qui mènent à des richesses inconnues... ou à une mort atroce. Robert Babiak, programmeur chez Bioware, a créé un système qui permettra aux DMs retors d'inclure des trappes secrètes dans leur campagne.

La trappe restera cachée est invisible jusqu'à ce quelle soit découverte par un PC qui possède la compétence Search.

Avant la Détection

En résumé, une trappe restera invisible jusqu'à ce qu'un PC réussisse un test de compétence. Lorsque le PC réussit son jet, la trappe deviendra visible et utilisable. L'emplacement de la trappe est spécifié par l'utilisation d'un objet invisible. De plus, une instance d'un Blueprint du placeable object Trap Door (Trappe) sera créée lors du déclenchement de l'objet invisible. Après la Détection

Importer la Trappe secrete dans le Toolset.1. Télécharger la Hidden_Door.erf - version 1.3 (13 KB)

(Les Mises à jour sont listées à la fin de ce tutorial)2. Enregistrez la à un emplacement que vous pourrez retrouver.3. Ouvrez le Toolset.4. Dans le menu 'File' sélectionnez l'option 'Import'.5. Naviguez jusqu'à l'emplacement où la "Hidden_Door.erf" est

enregistrée.6. Sélectionnez 'OK' et lisez les commentaires si vous le

souhaitez.7. Cherchez dans la palette 'Custom Placeable' les deux

nouveaux blueprints. Vous les trouverez dans la catégorie 'Miscellaneous Interior' sous les noms 'Hidden Trap Door' et 'Hidden Trap Door Trigger'.

Utiliser la Trappe secrete dans votre moduleL'utilisation de la trappe secrète est basée sur 3 éléments:

La distance à laquelle le PC peut tenter de détecter la trappe.Le DC (difficulty rating, niveau de difficulté) pour localiser la trappe en fonction de la compétence Search du PC.Le TAG du Hidden Door Trigger. Il est utilisé pour localiser le Waypoint où le joueur devra être "envoyé"

8. Ouvrez votre module dans le Toolset.

Page 46: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

9. Dans la palette de placeables, sélectionnez 'custom' et localisez le 'Hidden Trap Door Trigger'.

10. Sélectionnez le, et peignez en une instance dans votre module.

11. Faites un clique droit sur le trigger et sélectionnez 'Properties'.

12. Dans le champ 'Tag', entrez un tag pour cette porte secrète. Nommé la de façon claire, dans cet exemple, je vais l'appeler 'Sous-sol'.

13. Ensuite, sélectionnez le champ 'Reflex Save' qui est utilisé pour contrôler la distance à laquelle le PC peut essayer de repérer cette trappe. Entrez comme valeur la distance à laquelle vous voulez que votre PC soit capable de trouver la trappe. Dans mon exemple, je vais la mettre à 15 mètres. La taille d'un tile est de 10 mètres donc 15 mètres représentera 1 tile et demi.

14. Sélectionnez maintenant le champ 'Will Save', qui est utilisé pour contrôler le DC pour trouver cette trappe. Entrez dans ce champ la valeur que vous souhaitez. Dans mon exemple, je vais faire une trappe moyennement difficile à trouver et mettre le DC à 20. Un porte facile à trouver aurait un DC de 15 et une porte très dure à trouver un DC de 30. Un test de compétence "non entrainée" est basé sur un d20, donc tout DC au-delà de 20 sera TRES difficile à trouver. Il est à noter que les scripts de la trappe sont écrits de façon à ce que le test soit effectué à chaque 'heartbeat' du trigger (approximativement toutes les 2 secondes) donc un joueur restant dans les alentours a des chances de la trouver s'il y passe suffisamment de temps.

15. Cliquez sur 'OK' pour fermer le menu des porpriétés.

16. Dans la palette de Waypoints, sélectionnez 'Generic Waypoint' et placez en un à l'endroit ou se trouve le 'Hidden Trap Door Trigger'. Ce n'est pas nécessaire au fonctionnement mais cela vous permet de le repérer plus facilement. La raiso de ceci est que le trigger est fait à partir d'un objet invisible qui donc ne sera pas visible dans le toolset à moins qu'il ne soit sélectionné.

17. Maintenant placez un waypoint à l'emplacement où vous voulez que votre trappe secrète mène.

18. Faites un clique droit sur ce Waypoint et sélectionnez 'Properties'.

19. Dans le champ 'Tag', tapez DST_ suivi du tag de votre Hidden Trap Door Trigger que vous avez entré à l'étape 13. Dans mon exemple je mets DST_BASEMENT.

Note: Les Tags sont sensibles à la casse (font la différence entre les majuscules et les minuscules).

20. Cliquez sur 'OK' pour fermer cette boîte de dialogue.

21. Sauvegardez votre module et lancez une partie avec votre module.

Page 47: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

22. Prenez votre sympathique voleur et placez vous près de la trappe secrète. Lorsqu'elle sera détectée, elle apparaîtra et vous pourrez l'ouvrir. Elle agira maintenant comme une porte normale.

Voir le code

Si vous souhaitez regarder les 2 scripts utilisés pour créer la fonctionnalité Porte Secrète, vous les trouverez dans la liste de Scripts, dans la partie listant le contenu du modules (à gauche de l'écran). Faites un clique droit sur le script 'detectsecret' ou le script 'trapdoor' et choisissez 'Edit'. les deux scripts sont très commentés et devrait être faciles à comprendre.

Mises à Jour des Scripts – Nouveau das la version 1.3

Correction d'une erreur dans le script 'detectsecret'.

L'orientation du 'Hiiden Trap Door Trigger' déterminera maintenant celle de la trappe. Ceci permet de déterminer une orientation pour la trappe.

Ajout d'une possibilité de "recacher" la porte. Définissez un Local integer sur le 'Hidden Trap Door Trigger', nommez le "Reset" et attribuez lui la valeur 1.

Ajout d'un délai optionnel pour "recacher" la porte. Définissez un local Float sur la trappe, nommez le "ResetDelay" et attribuez lui comme valeur le délai en secondes que vous souhaitez avant la destruction de la porte. Ceci devrait être fait avant de définir le Local Integer "Reset".

Commentaires de Robert B. a propos de la Trappe secrete:"Le développement de cette paire de placeables n'était pas très difficile. J'ai commencé avec un trigger standard qui créait un object. Cette approche fonctionnait, mais j'ai eu deux difficultés. La première était que la trappe apparaissait à l'endroit où le premier point du trigger avait été placé, et la seconde difficulté était que vous deviez entrer dans le trigger pour détecter la porte. Ceci empêchait la découverte fortuite de la trappe secrète car le test de compétence n'était effectué qu'à l'entrée dans le trigger, puis jamais restesté à nouveau.

L'idée suivante était d'utiliser un object invisible pour sur le onHeartBeat si un PC était assez proche de l'object, et si oui faire le test de compétence pour voir si le PC trouvait la porte.

Après avoir créé la trappe, j'ai joué un peu avec le code déplaçant vers un waypoint. Au début je prévoyais de faire un script particulier pour chaque trappe secrète qui déplacerait le PC vers un waypoint, mais j'ai finalement décidé que cela pouvait être fait avec un script générique."

Creer une Porte Secretede Robert Babiaktraduit par Kemay

Page 48: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Ce tutorial est originellement basé sur le tutorial Créer un Trappe Secrète, qui permet de créer une trappe au sol, objet qui existe déjà dans le jeu.

Nous avons reçu de nombreuses demandes pour une version "murale" de la trappe, et les artistes de Bioware Tobyn Manthorpe and Jono Lee ont créé un nouveau placeable object qui peut être ajouté à vos modules. Ce tutorial utilise cette nouvelle porte pour créer une porte secrète.

ResumeAucun donjon n'est vraiment complet sans ces malicieuses portes secrètes qui mènent à des richesses inconnues... ou à une mort atroce. Robert Babiak, programmeur chez Bioware, a créé un système qui permettra aux DMs retors d'inclure des portes secrètes dans leur campagne.

La porte restera cachée est invisible jusqu'à ce quelle soit découverte par un PC qui possède la compétence Search.

Avant la Détection

En résumé, la porte restera invisible jusqu'à ce qu'un PC réussisse un test de compétence. Lorsque le PC réussit son jet, la porte deviendra visible et utilisable. L'emplacement de la trappe est spécifié par l'utilisation d'un objet invisible. De plus, une instance d'un Blueprint du placeable object Wall Door (Porte) sera créée lors du déclenchement de l'objet invisible.

Après la Détection

Importer la porte secrete dans le Toolset.23. Télécharger la Hidden_wall_door.erf (14 KB) et enregistrez la à un emplacement que vous pourrez

retrouver.

24. Télécharger le nwn_plc_doorway.hak (151 KB) et enregistrez le dans le répertoire 'hak' situé là où vous avez installé Neverwinter Nights (l'emplacement par défaut est C: \NeverwinterNights \NWN \hak).

Note: Pour pouvoir jouer à un module utilisant ce Hak Pak, les joueurs devront eux aussi le télécharger et le placer dans leur répertoire 'hak'.

25. Ouvrez le Toolset et ouvrez ou créez un module.

26. Dans le meu 'Edit' sélectionnez 'Module Properties', puis, dans l'onglet 'Advanced', dans liste déroulante 'HAK File', sélectionnez 'nwn_plc_doorway'.

Note: C'est de cette façon que les Hak Paks sont ajoutés à votre module. Souvenez vous bien que si vous utilisez un Hak Pak pour votre module, les joueurs devront placer le même Hak Pak dans leur répertoire 'hak' pour pouvoir jouer à ce module.

Page 49: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

27. Dans le menu 'File' sélectionnez l'option 'Import'.

28. Naviguez jusqu'à l'emplacement où la "Hidden_wall_door.erf" est enregistrée.

29. Sélectionnez 'OK' et lisez les commentaires si vous le souhaitez.

30. Cherchez dans la palette 'Custom Placeable' les deux nouveaux blueprints. Vous les trouverez dans la catégorie 'Miscellaneous Interior' sous les noms 'Hidden Wall Door' et 'Hidden Wall Door Trigger'.

Utiliser la Trappe secrete dans votre moduleL'utilisation de la porte secrète est basée sur 3 éléments:

La distance à laquelle le PC peut tenter de détecter la porte. Le DC (difficulty rating, niveau de difficulté) pour localiser la porte en fonction de la compétence

Search du PC. Le TAG du Hidden Wall Door Trigger. Il est utilisé pour localiser le Waypoint où le joueur devra être

"envoyé"

31. Ouvrez votre module dans le Toolset.

32. Dans la palette de placeables, sélectionnez 'custom' et localisez le 'Hidden Wall Door Trigger'.

33. Sélectionnez le, et peignez en une instance dans votre module.

34. Faites un clique droit sur le trigger et sélectionnez 'Properties'.

35. Dans le champ 'Tag', entrez un tag pour cette porte secrète. Nommé la de façon claire, dans cet exemple, je vais l'appeler 'Sous-sol'.

36. Ensuite, sélectionnez le champ 'Reflex Save' qui est utilisé pour contrôler la distance à laquelle le PC peut essayer de repérer cette porte. Entrez comme valeur la distance à laquelle vous voulez que votre PC soit capable de trouver la porte. Dans mon exemple, je vais la mettre à 15 mètres. La taille d'un tile est de 10 mètres donc 15 mètres représentera 1 tile et demi.

37. Sélectionnez maintenant le champ 'Will Save', qui est utilisé pour contrôler le DC pour trouver cette porte. Entrez dans ce champ la valeur que vous souhaitez. Dans mon exemple, je vais faire une porte moyennement difficile à trouver et mettre le DC à 20. Un porte facile à trouver aurait un DC de 15 et une porte très dure à trouver un DC de 30. Un test de compétence "non entrainée" est basé sur un d20, donc tout DC au-delà de 20 sera TRES difficile à trouver. Il est à noter que les scripts de la porte sont écrits de façon à ce que le test soit effectué à chaque 'heartbeat' du trigger (approximativement toutes les 2 secondes) donc un joueur restant dans les alentours a des chances de la trouver s'il y passe suffisamment de temps.

38. Cliquez sur 'OK' pour fermer le menu des propriétés.

Page 50: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

39. Dans la palette de Waypoints, sélectionnez 'Generic Waypoint' et placez en un à l'endroit ou se trouve le 'Hidden Wall Door Trigger'. Ce n'est pas nécessaire au fonctionnement mais cela vous permet de le repérer plus facilement. La raison de ceci est que le trigger est fait à partir d'un objet invisible qui donc ne sera pas visible dans le toolset à moins qu'il ne soit sélectionné.

40. Maintenant placez un waypoint à l'emplacement où vous voulez que votre trappe secrète mène.

41. Faites un clique droit sur ce Waypoint et sélectionnez 'Properties'.

42. Dans le champ 'Tag', tapez DST_ suivi du tag de votre Hidden Trap Door Trigger que vous avez entré à l'étape 13. Dans mon exemple je mets DST_BASEMENT.

Note: Les Tags sont sensibles à la casse (font la différence entre les majuscules et les minuscules).

43. Cliquez sur 'OK' pour fermer cette boîte de dialogue.

44. Sauvegardez votre module et lancez une partie avec votre module.

45. Prenez votre sympathique voleur et placez vous près de la porte secrète. Lorsqu'elle sera détectée, elle apparaîtra et vous pourrez l'ouvrir. Elle agira maintenant comme une porte normale.

Voir le code

Si vous souhaitez regarder les 2 scripts utilisés pour créer la fonctionnalité Porte Secrète, vous les trouverez dans la liste de Scripts, dans la partie listant le contenu du modules (à gauche de l'écran). Faites un clique droit sur le script 'detectwalldoor' ou le script 'trapdoor' et choisissez 'Edit'. les deux scripts sont très commentés et devrait être faciles à comprendre.

Commentaires de Robert B. a propos de la porte secrete:"Ceci est une extension de la Trappe Secrète. Le principal changement dans cette version est l'utilisation d'un blueprint du placeable de porte ainsi que l'incroporation de quelques uns des retours que j'ai reçu sur les forums.

Il y a trop de personnes pour que je puisse les lister ici, mais j'aimerai remercier tous ceux qui ont posté dans le fil 'Trap Door'. Les commentaires positifs ont montré que l'effort en valait la peine, et les commentaires négatifs et les suggestions d'amélioration ont permis d'améliorer la porte secrète. Ces suggestions ont été incorporées dans cette version.

Les principales différences entre les scripts de la trappe et de la porte sont le nom du blueprint utilisé à la création lors de la détection, ainsi qu'une optimisation stoppant le test du heartbeat lorsque le dernier PC a avoir été testé est hors du rayon de détection.

La porte utilise le même script onUse que la trappe."

Les dialogues

Page 51: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Lumina, dame de la VieAventurière des Mondes Fantastiques

VocabulaireUn dialogue (ou conversation) est un arbre avec des nœud d'où partent plusieurs branches (chaque réponse possible). Chaque niveau de l'arbre de dialogue est alternativement une participation d'un interlocuteur (le pnj) et de l'autre (le pj).

FonctionnementA chaque nœud de l'arbre, on peut mettre une ou plusieurs réponses, chacune avec une pré-condition ou pas. Pour un pnj, la réponse utilisée sera la première qui correspond à un pré-requis valide. Pour un pj, toutes les réponses correspondant à un pré-requis valide seront possibles. Si aucun pré-requis n'est respecté ou si il n'y a plus de branches, le dialogue se termine.

Utilisez la souris pour faire glisser les dialogues dans l'ordre dans lequel vous souhaitez les voir apparaître pour un pj, et dans l'ordre de préférence d'utilisation pour les réponses d'un pnj.

Pour faire dire plusieurs choses à un pj ou à un pnj, il suffit de laisser un blanc dans la réponse de l'autre interlocuteur. Il y aura alors "Continue" qui apparaîtra pour le pj par exemple. Pensez à ne pas mettre de retours à la ligne dans vos dialogues pour divers problèmes d'affichage : utilisez à la place une succession de dialogues.

Pour faire parler plusieurs pnj, il faut que ceux-ci soient proches. Ensuite, il ne reste plus qu'à sélectionner le portrait de celui qui parle dans "Speaker Tag".

Les bouclesPour faire une boucle dans un texte, faites un clic droit vers la destination de votre boucle et copiez la. Puis faites un clic droit à l'origine de votre boucle, et faites une copie par lien : vous aurez alors formé une boucle partant de l'origine vers la destination ! C'est extrêmement utile et recommandé !

Le conditionnement / mettre un pre-requisPour conditionner l'apparition d'un dialogue, aussi bien pour le pj que pour le pnj, c'est avec "Text Appears When ..." et un script de condition. Ce script doit renvoyer un entier qui vaut 0 ou FALSE pour signifier que le dialogue ne doit pas apparaître, et qui vaut 1 (ou plus) ou TRUE pour signifier que le dialogue doit apparaître.

Exemple : l'apparition uniquePour que dans une boucle de dialogue les choix effectués n'apparaissent qu'une seule et unique fois, et plus jamais apres, il faut utiliser une variable d'etat. Pour cela, utilisez ces deux scripts dans les réponses que vous voulez conditionner ainsi :

“Text Appears When .."if (GetLocalInt(GetPCSpeaker(), "checknode_1")) return FALSE; else return TRUE;

"Action Taken"SetLocalInt(GetPCSpeaker(), "checknode_1", TRUE);

Exemple : apres une quetePresque pareil pour faire l'inverse, c'est à dire faire apparaître une réponse uniquement après une certaine action seulement :

"Text Appears When .."if (GetLocalInt(GetPCSpeaker(), "checkquest_1")) return TRUE; else return FALSE;

"OnDeath" (sur le monstre)SetLocalInt(GetLastKiller(), "checkquest_1", TRUE);

Page 52: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Bien entendu, vous donnez le nom que vous voulez à "checknode_1" et "checkquest_1".

Si vous voulez faire dépendre un dialogue ou la mort d'un monstre de tout le module et non pas seulement d'un seul personnage, alors remplacez les GetPCSpeaker() et GetLastKiller() par GetArea().

Texte en couleurPour mettre des couleurs, utilisez les tokens. Les tokens se trouvent en faisant un clic droit sur la fenêtre de dialogue ou en les écrivant directement. Il n'est pas encore possible de faire des tokens personnalisés, mais voici les tokens utiles :<StartAction>Texte en vert</Start><StartCheck>Texte en rouge</Start><StartHighlight>Texte en bleu</Start>

Pour faire des tests particuliers, peu importe lesquels, il faut toujours utiliser "Text Appears When ..". Mettre du texte en couleur ne changera rien, c'est purement décoratif.

Plusieurs langues & compatibilitePour mettre des dialogues en plusieurs langues ou pour être compatible avec la norme des modules francophones, utilisez le bouton "..." au milieu en bas : il vous permet pour chaque texte de préciser deux versions francophones, l'une adressée à un interlocuteur masculin, et l'autre pour un interlocuteur féminin. Toutefois, pour l'instant, ça ne fonctionne pas.

ActionsPour ajouter des actions, des mimiques, ou tout autre évènement comme vous voulez, utilisez toujours "Action Taken" et un script adapté.

Pour ajouter une action spéciale finale, vous pouvez le faire directement avec un script placé dans le dernier onglet en bas à droite : "Current File".

Exemple : ouvrir l'echoppe du marchandUtilisez simplement le script suivant dans "Action Taken" :OpenStore(GetNearestObjectByTag("Tag_de_mon_stock_de_marchandises"), GetPCSpeaker());

[expert]Centralisation des liens depuis la racine pour les dialogues trop longs ou avec bouclesUn soucis qui apparaît parfois, ce sont les dialogues trop longs ou avec des boucles pour lesquelles on ne trouve plus l'original des copies par lien dans toute cette arborescence.Pour éviter ce soucis, créez une branche spéciale depuis la racine de l'arbre appelée "Racine des Liens" et avec comme pré-requis False (traduction : mettez le script return FALSE; dans "Text Appears When"), et ajoutez-y tous vos dialogues "originaux" qui seront destinés à être copiés ensuite un peu partout. Ajoutez-y aussi des portions de branches quand celles-ci sont trop longues. Ceci permet une meilleure lisibilité et diminue les chances du "bug de conversation trop longue" qui existe actuellement en version 1.19 et qui fait planter le module.

Faire une [persuasion] dans un dialogue1. Proposez un choix où apparaît le texte :_ <StartCheck>[persuasion]</Start> Seul le baiser d'une aussi belle demoiselle que vous me redonnera mon sourire !

Page 53: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

2. Ajoutez plusieurs réponses :_ <StartAction>[Miracle !]</Start> Noble Sire .. c'est toujours vous que j'ai regardé depuis votre arrivée .. et depuis toujours je vous aime .. et je ne peux que pleurer de joie .. et .. et .. <StartHighlight>*saute dans vos bras et vous embrasse fougueusement*</Start>

_ <StartAction>[Succes !]</Start> Noble Monsieur, pour votre réconfort, j'accepterais un instant de fermer les yeux à ce que ma déontologie me dicterait en pareille situation. Et par compassion je .. et bien .. <StartHighlight>*s'approche de vous, vous enlace et vous embrasse tendrement*</Start>

_ <StartCheck>[Echec !]</Start> Pauvre Gueux, et l'instant d'après vous deviendrez Beau Prince peut-être ? Allez plutôt cherchez le réconfort dans les porcheries, et voir si les bêtes veulent de votre pitié .. <StartHighlight>*se retourne et s'en va*</Start>

3. Ajoutez des scripts de tests dans "Text Appears When .." pour chacune des réponses :Pour le miracle :if (d20()+GetAbilityModifier(ABILITY_CHARISMA, GetPCSpeaker()) >= 22) return TRUE; return FALSE;Pour le succès :if (GetAbilityScore(GetPCSpeaker(), ABILITY_CHARISMA) >= 11) return TRUE; return FALSE;Pour l'échec :*rien du tout, c'est la réponse par défaut*

4. Sauvez le dialogue, c'est terminé !

Limiter un dialogue aux adeptes d'une certaine religion, d'une certaine race, d'une certaine classe, etc.Tout ce que vous pouvez imaginer, ça se résume à faire des tests qu'on rajoute dans "Text Appears When .." pour l'apparition ou pas d'une branche de dialogue.

Voici un exemple pour faire passer une batterie de tests absurdes :int StartingConditional(){   object oPC = GetPCSpeaker();   int iResult;   if (GetDeity(oPC) == "Lloth") // Test de divinité     iResult = TRUE; else iResult = FALSE;    if (GetRacialType(oPC) == RACIAL_TYPE_ELF) // Test de la race       iResult = iResult; else iResult = FALSE;    if (GetSubRace(oPC) == "Drow") // Test de la sous-race       iResult = iResult; else iResult = FALSE;    if (GetGender(oPC) == GENDER_FEMALE) // Test du sexe       iResult = iResult; else iResult = FALSE;    if (GetAge(oPC) >= 40) // Test de l'age       iResult = iResult; else iResult = FALSE;    if (GetClassByPosition(1, oPC) == CLASS_TYPE_CLERIC) // Test de la classe principale       iResult = iResult; else iResult = FALSE;    return iResult;}

On peut simplifier au moins de deux manières :- remplacer les iResult = iResult; par  ;  seulement, puisque cette instruction ne fait rien.- transformer les iResult = FALSE; en return FALSE; directement.

Mais je laisse comme ça pour des raisons de lisibilité pour les débutants dans l'utilisation des tests

avec if().

Bon, je ne l'ai pas mis, mais vous pouvez faire pareil pour :

Page 54: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

- un test d'xp

- un test d'or transporté

- un test de score dans une caractéristique

- un test de score dans une compétence

- un test variable ou aléatoire avec l'utilisation de d10(), d20(), d100()

- des tests de conditions inverses en remplaçant "==" par "!="

- des tests de conditions additionnelles ou exclusives avec "&&" (signifie ET) et "||" (signifie OU)

Cours de Scripts pour les Quiches. de Celowin

traduit par Amaranthe.

Cours I

IntroductionLe but de cette série de leçons, est d'apprendre a se servir des scripts a n'importe qui. Cette première leçon est très simple, et quiconque ayant déjà codé devrait pouvoir s'en passer. Maintenant, il est toujours possible d'y apprendre un truc ou deux.

Je ne m'étendrais pas en détail sur le fonctionnement du toolset, ceci est supposé comme déjà connu.

Ouvrez le Toolset et créez un nouveau module, que nous appellerons 'Test Module'. Créez une nouvelle zone, que nous appellerons 'Test Area 001'. Utilisez la taille et le tileset qui vous plait, cela n'a aucune incidence sur les scripts. Préférez cependant une taille pas trop grande, il vous sera plus facile de vous y retrouver et cela prendra moins de temps à sauvegarder/charger pour les innombrables tests que vous devrez forcément faire.

Placez un npc sur votre carte. Donnez-lui l'apparence que vous voulez. Puis : Clic droit sur le npc. Choisissez l'option de menu 'Propriétés' ( properties ) Changez le tag du NPC en CHANTEUR Ouvrez l'onglet des scripts. Il y a des scripts par défaut a chaque option. Cliquez sur chacun et supprimez-les. Cliquez sur le bouton 'Edit' a coté du script sur le 'On Heartbeat'. Tapez le script suivant en respectant les minuscules et les majuscules.

void main(){ ClearAllActions();    ActionSpeakString("Ils sont dans les vignes les moineaux...");    ActionWait(1.5);    ActionSpeakString("Ils ont manges les raisins...");    ActionWait(1.5);    ActionSpeakString("Ils ont craches les pépins...");    ActionWait(1.5);}

Page 55: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Je vous conseille de tapez le texte plutôt que de le copier/coller. Vous apprendrez mieux ainsi. Et si vous faites une erreur, vous n'en apprendrez que plus.

Cliquez sur 'Save As' et appelez le tm_chanteur_hb Vérifiez que le résultat ressemble à : "0 Errors. ‘tm_singer_hb’ Compiled successfully"

Sinon c'est que vous avez du faire une erreur quelque part... re-vérifiez ! Fermez l'éditeur de script. Cliquez sur "OK" dans la fenêtre du NPC. Sauvegardez votre module. Relancez le jeu et choisissez 'Other Modules' pour vérifier ce que vous avez fait. Votre npc devrait chanter cette ritournelle... encore et encore...

Analyse.Tentons maintenant d'explique ce que nous venons de faire. Ceci sera fait par le biais de questions / Réponses, en tentant d'imaginer les questions que vous pourriez vous poser.

Pourquoi l'appeler 'Test Module' ?Cela n'a en fait aucune importance. Le seul intérêt est de le distinguer facilement des autres dans la liste des modules proposés. Pour cela, il est préférable que tous vos modules ne commencent pas par 'Module'...

Pourquoi avoir appelé la zone 'Test Area 001' ? Est-ce que le nom par défaut n'était pas suffisant ?Pour ce petit module de test, cela ne devrait effectivement pas prêter à conséquences. Mais c'est une bonne habitude à prendre que de renommer les choses que l'on customise, afin que chacune aie un nom unique et non équivoque. Si tout le monde utilise 'Area 001', alors le transfert de zones d'un module a l'autre risque d'être problématique.

Pourquoi avoir donné au npc le tag CHANTEUR ? Pourquoi l'avoir mis tout en majuscules ?Il est préférable pour des raisons internes au programme, de mettre les tag en majuscules. Vous pourriez très bien ne jamais avoir de problèmes, mais c'est quand même une bonne habitude à prendre.Je recommande de la même manière de donner à chaque créature ou npc un tag clair et non équivoque. CHANTEUR décrit parfaitement le npc. Il est maintenant plus simple de s'y référer dans un script plus compliqué.Les tags doivent également rester court. Evitez les tags de plus de 8 caractères.

Pourquoi avoir supprimer tous les scripts par défaut ? A quoi servent-ils si on doit les détruire ?Les scripts par défaut définissent tout un tas de comportements dont nous n'avons que faire pour le moment. Nous les avons supprimés afin qu'ils n'interfèrent dans notre test. Nous souhaitions que notre npc chante, et rien d'autre.Nous verrons dans de prochaines leçons comment se servir des scripts par défaut.

Pourquoi avoir placé notre script sur le 'OnHeartbeat' ? Pourquoi est ce qu'il y a tant de choix ?Chacun de ces choix, définit un moment ou le script est appelé. Le 'OnHeartbeat' appelle le script a chaque battement de cœur, soit toutes les 6 secondes. C'est pourquoi le chanteur ne s'arrête jamais. Toutes les six secondes, il recommence sa chanson.Chacun des autres choix a son utilisation, en fait, le "OnHeartbeat' est celui qui devrait être le moins utilisé. Trop de scripts lancés toutes les six secondes devraient rapidement mettre votre ordinateur sur les rotules.

Qu'est ce que ce "void main()" ?Ce petit bout de code n'a l'air de rien, mais essayez donc de l'oublier et vous verrez son importance. Je vais essayer de vous l'expliquer, même si cela ne sera sans doutes clair qu'après les autres chapitres.Les scripts sont codés en utilisant des 'fonctions', qui disent au programme ce qu'il doit faire. Certaines fonctions sont déjà écrites, et nous ne faisons que les utiliser. Ecrire un script revient en fait à créer une nouvelle fonction. Cette ligne est en quelque sorte une description de cette fonction.Premièrement le mot "void". Qui peut signifier néant. Cela indique au script la "réponse" qui va revenir de la fonction. Notre chanteur fait des choses, mais il ne calcule rien. Ce "néant" indique que la fonction ne ramènera aucune réponse. Le mot "main" qui signifie principal indique que cette fonction est la principale. Nous pouvons en écrire d'autres, et nous le ferons, mais ce mot indique l'endroit ou le script commencera.Entre les parenthèses se trouvent les arguments, ou paramètres, ou encore informations qui sont donnés et

Page 56: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

nécessaires à la fonction pour qu'elle s'exécute. Dans ce cas, notre script se suffit à lui-même et n'a besoin d'aucunes informations.

Qu'est ce que les { et } ?Ils sont utilisés pour délimiter les sections du script et les fonctions. Cela signifie que tout ce qui est entre nos deux { } fait partie de notre fonction "main".

Pourquoi est ce que chaque ligne se termine par un ; ?Principalement pour indiquer au script que la ligne se termine. Certaines instructions sont parfois trop complexes pour tenir sur une seule ligne. Il est ainsi possible de les écrire sur autant de ligne que l'on veut. Le programme les considérera comme une seule et même ligne tant qu'il ne tombera pas sur un ‘;’

A quoi sert le ClearAllActions() ? En fait dans ce cas, a rien C’est une garantie.Chacune des autres lignes du script est une commande. Le npc va les exécuter une par une, en prenant bien soin de finit la première avant de passer à la suivante.Mais, notre fonction est placée dans le "On Heartbeat" et va donc être appelée toutes les 6 secondes. Mais nous avons 7 actions. Que se passe t'il s’il a seulement le temps d'en faire 3 en 6 secondes ? Il reste encore 4 actions à faire et on lui redemande d'en faire 7... ce qui lui en fait 11 maintenant... Cela va aller en augmentant, et au bout d'un moment, cela risque de poser problème. Il y a de meilleurs moyens de régler ces problèmes. Mais pour l'instant, contentons-nous de dire au npc d'oublier tout ce qu'il lui reste à faire. C'est ce que fait le ClearAllActions().Si vous voulez expérimenter, éditez le script et changez les valeurs a l'intérieur des commandes ActionWait. Remplacez par exemple le 1.5 par 3.0Pendant qu'on y est. Le ClearAllActions est une fonction, comme notre main. Une fois de plus, le fait qu'il n'y ait rien entre les parenthèses signifie qu'on ne passe aucune information a cette fonction. Par contre, la fonction ActionWait, elle a besoin d'informations, en l'occurrence le temps qu'il va falloir attendre. D'où la présence d'un nombre a l'intérieur des parenthèses...

Et pour les autres lignes du main ?Ce sont toutes les instructions expliquant au npc ce qu'il doit faire. Elles sont assez explicites, mais je vais quand même détailler un peu.ActionSpeakString fait dire au npc quelque chose. Ce quelque chose étant le texte passé en paramètre a la fonction. Ce texte est une Chaîne de caractères ( String ), et doit être encadré par des ".ActionWait fait asseoir et attendre le npc, le nombre de secondes précisé. ActionWait(0.5) fait attendre le npc pendant 0.5 secondes entre chaque phrase.

Pourquoi nommer le script tm_chanteur_hb ?Une fois encore, vous pouvez l'appeler comme bon vous semble, du moment que vous vous en souvenez. "tm" signifie ici Test Module. Tous nos scripts pour ce module commenceront ainsi."chanteur" signifie que ce script s'applique au npc chanteur. Il est préférable de mettre les noms de scripts en minuscules, et je vous recommandais de garder les noms de tags sur 8 caractères au plus, de façon justement a ce qu'on puisse les réutiliser dans les noms de scripts sans que cela soit gênant."hb" signifie que le script concerne le "On Heartbeat".

Pourquoi est ce que cette leçon n'est pas plus longue ?Je trouve pour ma part qu'elle est suffisamment longue. Elle le fut à écrire au moins. De plus je ne souhaite pas vous noyer sous des tonnes d'informations. Laissez-moi quelques jours, et vous aurez votre deuxième leçon.

Page 57: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Cours II

IntroductionLe but de cette série de leçons, est d'apprendre a se servir des scripts a n'importe qui. Cette deuxième leçon porte sur les variables.

Cette leçon risque d’être un peu plus longue que la précédente. Les concepts abordés sont également un peu plus complexes. Si ma manière de présenter les choses n’est pas assez claire, n’hésitez pas a posez des questions. Partez toujours du principe que pour une personne qui pose la question, il y en a cinq qui attendent la réponse.

Modifions donc notre module de test. Ouvrez le dans l’éditeur.Cliquez droit sur le npc que nous avions crée. Choisissez propriétés et allez dans l’onglet des scripts.

Nous allons cette fois ci écrire deux petits scripts.

Le premier va dans le « OnSpawn »

void main(){   SetLocalInt(OBJECT_SELF, “CHANTEUR_COUNT”, 0);}

Sauvegardez le en tm_chanteur_os ( "os" pour « OnSpawn » )

Bien, même si ce script ne fait qu’une seule ligne, il est du genre a faire fuir la plupart des gens qui n’ont pas l’expérience de la programmation. Essayons donc d’expliquer un peu avant de s’attaquer au script réel.

Premièrement, remarquez que ce script est placé dans le « OnSpawn ». Ce qui signifie qu’il ne sera exécuté qu’une seule fois, lorsque le npc apparaît pour la première fois dans le jeu. C’est donc l’endroit idéal pour initialiser des choses, et c’est justement ce que nous cherchons a faire.

Cette ligne définit une variable. Souvenez vous de vos cours de math, qu’est ce qu’une variable ? Une lettre qui représente un nombre. C’est a peu près la même chose ici, mis a part qu’au lieu d’utiliser une simple lettre, nous lui donnons un nom.

La commande SetLocalInt est une fonction que sert a définir une variable. Elle nécessite trois paramètres, séparés par des virgules : Le premier est ce a quoi la variable va être attachée. Le second est le nom que nous voulons donner a la variable. Le troisième est la valeur que nous voulons mettre dans la variable.

J’espère que vous avez compris que nous voulions créer une variable, nommée CHANTEUR_COUNT et que nous voulions lui donner la valeur 0. Le premier paramètre nécessite un peu plus d’explications.

Tout ou presque dans un module, est un objet ( object ). Les npcs sont des objets, les Placeables sont des objets. Même les pcs eux mêmes sont des objets. Avec tant et tant d’objets dans un module, il est vital de savoir s’y retrouver et de toujours savoir duquel on parle.

OBJECT_SELF est un des moyens les plus pratique de se référer a un objet. Comme vous pouvez le deviner, il fait référence a l’objet qui l’appelle. Dans notre cas, notre script est attaché a un npc, donc OBJECT_SELF est ce npc. Aussi simple que cela.

Nous avons donc, par le truchement de cette simple ligne, définis une variable nommée CHANTEUR_COUNT, qui a pour valeur 0. Cette variable étant attachée au npc CHANTEUR.

Il est intéressant aussi de noter que le Int de SetLocalInt est pour « Integer » ce qui veut dire Entier. C’est a dire un nombre entier. Nous aurions pu mettre 2, 15 et même –7 mais pas 3,8 par exemple.

Page 58: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Le deuxième script maintenant. Nous allons écraser le "OnHeartbeat"  de notre première leçon.

int nCount=GetLocalInt(OBJECT_SELF, "CHANTEUR_COUNT");void main(){    nCount = nCount+1;    ActionSpeakString("J’ai parle "+IntToString(nCount)+" fois.");    SetLocalInt(OBJECT_SELF, "CHANTEUR_COUNT", nCount);}

Sauvegardez le, gardez le nom tm_singer_hb.

Avant que j’explique, regardez donc ce que fait ce script. Fermez la fenêtre de script. Cliquez sur Ok pour le npc, et sauvegardez le module. Lancez le module de test et regardez comment se comporte votre chanteur.

C’est votre premier script avec quelque chose d’écrit avant le void main() et cela mérite donc d’être signalé. Ceci est appelé la phase d’Initialisation du script. Nous parlons ici des choses auxquelles le script va se référer. Contrairement a la variable locale que nous avons défini précédemment, ce nCount n’aura d’existence que le temps que ce script tourne. Des que ce script sera terminé, nCount n’existera plus. C’est pour cette raison que ces variables sont nommées « Temporaires ».

Remarquez combien de fois nous utilisons nCount dans notre fonction, et imaginez combien cela serait long et déroutant si nous devions a chaque fois réécrire a la place quelque chose comme GetLocalInt(OBJECT_SELF, "CHANTEUR_COUNT").

Pour ce qui est du nCount. A chaque fois que vous déclarez une variable temporaire, la première lettre est un tag qui sert a déterminer le type de valeur que cette variable peut prendre. Ce n’est nullement obligatoire, c’est simplement une convention. N est ici mis pour Integer. Quelque soit le nom que vous donnez a votre variable, vous savez qu’elle va contenir un Integer.

Les « int » signifie donc que nous définissons une variable de type integer, le « = » signifie que nous allons lui donner une valeur et le GetLocalInt récupère la valeur de la variable CHANTEUR_COUNT.

Notez au passage la similarité entre les fonctions SetLocalInt et GetLocalInt.

Cette première ligne crée donc une variable temporaire nCount, que notre script va pouvoir utiliser, et lui assigne la valeur de CHANTEUR_COUNT stockée au niveau de notre npc. Donc la première fois que le script est appelé, nCount vaut 0. Puisque c’est ce que nous avons initialisé dans notre script « OnSpawn ».

Je sais que cela fait beaucoup d’explication pour une simple ligne de code. Et je me doute que beaucoup ne comprendrons pas du premier coup. Relisez et si cela n’est toujours pas clair, attendez de l’avoir utilisé deux ou trois fois et vous verrez alors…

Voyons maintenant le corps du script et décortiquons le.

nCount = nCount+1;

Cela ne fait que prendre notre variable temporaire et lui ajouter 1. Il suffit de lire : Affectez a la variable nCount le contenu de la variable nCount + 1.

Si nCount vaut 9, alors après cette ligne, elle vaudra 10.

( Il est également possible d’écrire cela : nCount++; le ++ est l’incrément de 1. C’est parfait une fois que l’on y est habitué, mais au début c’est généralement assez déroutant. )

Page 59: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

La deuxième ligne est une commande connue : ActionSpeakString. Par contre le paramètre demande peut être explication. Il est composé de trois parties, séparées par des +. Lorsqu’on l’applique a des chaînes de caractères ( String ) le + sert a la concaténation. Par exemple :« Ceci est une String » est équivalent à : « Ceci est » + « une String ».

Cela n’a que peu d’intérêt écrit comme cela, mais prends tout son sens quand on regarde la partie du milieu de l’expression : IntToString(nCount).Ce qui fait exactement ce que ça veut dire. nCount est un integer, et cela transforme sa valeur en une chaîne de caractère de façon a ce qu’elle puisse être concaténée et utilisée par la commande ActionSpeakString.

Vous devriez maintenant facilement comprendre la dernière ligne. Cela ne fait que stocker la nouvelle valeur de nCount dans notre variable locale. Si nous voulons que cette variable soit réutilisée, il faut stocker sa valeur. Rappelez vous que nCount n’existera plus une fois que vous serez sortis de la fonction..

Cours III IntroductionLe but de cette série de leçons, est d'apprendre a se servir des scripts a n'importe qui.

CommençonsCette leçon va tenter de couvrir ce qui est sans doutes l'aspect le plus important de l'art du scripteur. Comment faire en sorte que votre code fasse quelque chose... seulement dans certaines conditions !

Un peu de théorie tout d'abord. Le format de base d'une condition, ou d'un test est :

if ( condition ) {  fait_ceci;  fait_cela;  fait_autre_chose; }

(Ce n'est pas un vrai script, juste un prototype.)

De façon simple, si la condition est remplie, le script va faire ce qu'il y a entre les {}. Sinon, il ne fera rien.

Il est a noter qu'une erreur classique consiste a mettre un ; après la ligne commençant par un " if ". Or il n'en faut pas.

Voilà, vous savez maintenant comment écrire un test. Il ne reste plus qu'a savoir comment écrire la condition. Il y a énormément de types de condition différents, et beaucoup de petites règles qui en découlent. Je vais seulement vous en expliquer les bases de façon a ce que vous soyez capable de chercher la suite par vous mêmes.

La plupart des conditions se résument a une comparaison. Par exemple :

if (nCount == 1)

Comme nous l'avons vu, un " = " correspond a une assignation de valeur, il en faut deux " == " pour tester cette valeur.

if (nCount == 1) correspond a se demander si nCount est égal à 1 ?

Rappelons nous que nCount est une variable, et est en fait équivalent a un nombre. Si nCount contient au moment du test la valeur 1, alors la condition sera réalisée. Si nCount contient 7, alors elle ne le sera pas.

Quand on parle de conditions, il est difficile d'éluder le nom de Boole. Je ne vais pas aller bien loin, qu'il vous suffise de savoir que c'était un mathématicien qui énonça certaines lois, incontournables en informatiques.

Une condition est soit VRAI ( TRUE ) soit FAUSSE ( FALSE ).FALSE vaut 0. TRUE vaut 1.

Page 60: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Regardez donc un interrupteur, celui de votre ordinateur ou celui de votre cafetière électrique... Vous y verrez sûrement d'un coté un 0, de l'autre un 1. 1 pour allumé, 0 pour éteint. Bienvenus dans un monde binaire...

Tout ce qui n'est pas TRUE est FALSE et inversement.

Mais revenons a nos moutons...

L'autre façon d'énoncer une condition, est au travers d'une fonction prédéfinie. Considérons donc l'exemple suivant.

Script d'exemple.Ecrivons donc un script avec une condition simple. Il y aura un certain nombre de nouvelles fonctions que nous expliquerons après.

Ouvrez votre module de Test. Créez une nouvelle Area, forest tileset, dimension 4 par 2. Appelée la " Test Area 002 ". A une extrémité, placez une " Start location ". A l'autre extrémité placez un npc. Juste un " Commoner " pour plus de simplicité. Changez son tag en " GARDE " Allez dans ses scripts. Supprimez les tous. Allez dans le " OnPerceive " et entrez ce script.

object oVu = GetLastPerceived(); void main() {   if (GetIsPC(oVu))    {      ActionSpeakString("Bienvenu mon ami.");   } }

Sauvegardez le avec notre convention de nomage en tm_garde_op ( " op " pour " OnPerceive " ) Validez tout, sauvegardez et allez tester votre module.

Lorsque vous vous approchez du garde, il parle. Mais si vous restez a coté de lui, il ne dit plus rien. Eloignez vous, revenez...

Reprenons notre jeu des Questions/Réponses pour expliquer ce script.

Encore un autre " handle ", a quoi sert donc ce " OnPerceive " ? Ce handle, appelle le script associé des que le npc remarque quelque chose. Si ce quelque chose est invisible, ou caché et que le npc ne le remarque pas, alors le script ne sera pas appelé.Nous voulons que notre garde réagisse en voyant quelqu'un. D'ou l'utilisation du " OnPerceive ".

Ré explique moi donc pourquoi tu met des choses avant le main. Ca ne ressemble pas a ce qu'il y avait dans la leçon deux. Et pourtant, c'est la même chose... ou presque. Il s'agit juste d'un autre type de variables. Nous avions crée une variable pour stocker un integer, maintenant nous voulons une variable pour y stocker un objet.

Je l'ai déjà dit, mais je me répéterai. Quasiment tout dans le jeu est un Objet. Les npc, les pc, les objets, les waypoints... et quasiment toutes les fonctions sont écrites afin de manipuler des objets.

Nous créons donc ici une variable temporaire, que nous appelons oVu ( commençant par o pour se rappeler qu'il s'agit d'un objet ). Et nous stockons une valeur dedans.

Et cette valeur est le résultat de la fonction GetLastPerceived(). Cette fonction, comme toutes celles qui commencent par le mot Get, renvoie une donnée. Le nom de la fonction suffit généralement pour savoir ce qu'elle fait. Ici, la fonction renvoie le dernier objet vu par le npc.

On a passé du temps a apprendre ce que c'était qu'une comparaison et maintenant il n'y a une condition sans comparaison ?

Page 61: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Souvenez vous, je vous avais expliquer que tout était soit VRAI, soit FAUX. Si c'est VRAI, j'exécute mon script, si c'est FAUX je fait rien.

C'est exactement ce qu'on veut faire ici. Si le résultat de GetIsPC(oVu) est VRAI alors j'exécute mon script. Si c'est FAUX, je ne fait rien.

GetIsPC() est une fonction qui prend un objet en paramètre et renvoie un booléen. Un booléen ( d'après le nom de Boole ) est un type de variable qui ne peux prendre que deux valeurs... vous l'aurez deviné... TRUE ou FALSE. GetIsPC renverra donc TRUE si oVu est un Pc, FALSE dans tout les autres cas.

Ce qui est exactement ce que nous voulons. Si l'objet perçu par le garde est un Pc, alors le script sera exécuté, sinon, il ne se passera rien.

Vous pouvez aussi écrire, si vous préférez. if (GetIsPC(oVu)==TRUE) de façon a ce que cela ressemble plus a une comparaison... mais ce n'est pas utile.

A t'on forcement besoin de ce test... n'est on pas sur que ce soit toujours une pc qui soit percu par le garde ? Pour notre petit module de test, il est clair que ce pauvre garde n'a rien d'autre a percevoir. Mais imaginez que ce garde perçoive un gobelin... vous ne voudriez pas qu'il l'appelle mon ami quand même ?

A quoi cela peut il bien me servir de parler a un NPC s'il n'y a personne pour s'en rendre compte ? De toute façon il sont tous amicaux.Ah oui ?Voyons un peu ce que l'on peut faire...

Nous allons modifier notre module de façon a ce que notre garde attaque tout personnage ne portant pas... mettons un anneau spécial. Dans le cas ou cet anneau est porté, alors le personnage a droit a une remarque amicale.

Ouvrez le Toolset. Chargez votre module et choisissez l’ Area002. Commençons par créer l’anneau. Go to « Paint Items », "Miscellaneous", "Jewelry", "Rings", "Copper Ring".

Placez le près de l’entrée du module. Editez les propriétés de l’anneau, changez son tag en "PASSRING". Si vous vous sentez ambitieux, vous pouvez changer le nom de l’anneau, sa description… mais pour les

besoins du script, seul son tag importe.

Choisissez maintenant le garde, et éditez son script « OnPerceive ».

// Amis ou Ennemis : tm_guard_op //// Doit être placé dans le « OnPerceive » du garde. // // Le garde va vérifier si le personnage possède l’anneau « PASSRING » et sinon l’attaque. //

object oSeen = GetLastPerceived(); object oRing = GetItemPossessedBy(oSeen, "PASSRING"); 

void main() {  // Si ce que voit le garde n’est pas un personnage, il ne fait rien.  if (GetIsPC(oSeen))   {    if (oRing == OBJECT_INVALID)     {       // Si le personnage n’a pas l’anneau. Attaque !      ActionSpeakString("Meurt donc Etranger!");       ActionAttack(oSeen);     }     else     {  // Si le personnage a l’anneau, on le salue.    ActionPlayAnimation(ANIMATION_FIREFORGET_GREETING);      ActionSpeakString("Bien le bonjour, messire.");     }   } }

Page 62: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Je commence a enrichir les script, en ajoutant de plus en plus de nouvelles commandes. Cela ne devrait plus trop vous poser de problèmes maintenant.

Si vous avez encore des problèmes, chargez le script et lancez le module pour voir ce qu’il fait. Cela devrait être rapidement plus clair. Regardez comment se comporte le garde, suivant que vous ayez ou non l’anneau sur vous.

Argh ! Tu as ajouté une autre initialisation ! Je hais ça ! Tout ce que je peux dire, c’est que le script serait beaucoup plus compliqué sans cela.

object oRing = GetItemPossessedBy(oSeen, "PASSRING");

Une fois de plus, nous créons une nouvelle variable temporaire, qui contiendra un objet. La commande GetItemPossessedBy prend deux paramètres, le premier est l’objet créature que l’on veut tester, et le second est le tag de l’item que l’on cherche sur cette créature.

On sait déjà que oSeen est la personne qui a déclenché le script en étant « Vue » par le garde. ORing est donc l’objet porté par cette personne qui a le tag « PASSRING ».

Mais que se passe t’il si le personnage n’a pas l’anneau ? que vaut oRing dans ce cas la ?Excellente question. La commande GetItemPossessedBy marche toujours, bien entendu. Mais comme elle ne peut pas trouver l’objet sur la personne, elle renvoi un objet de type OBJECT_INVALID. Une sorte de moyen pour elle de dire qu’elle n’a rien trouvé de ce qu’on lui demandait.

Qu’est ce que toutes ces lignes commençant par des //. Pour une fois elles sont écrites en français ? Tout ce qui est écrit après des // est ignoré par le script. Cela permet de mettre des commentaires afin de rendre les scripts plus lisibles, et plus facilement compréhensibles.

Prenez l’habitude d’en mettre le plus possible. Cela peut vous sembler rébarbatif quand vous écrivez un script, mais vous serez heureux de les retrouver un ou deux mois plus tard quand vous voudrez le modifier.

C’est également plus gentil pour tous ceux a qui vous donnez de ce script, plus vous expliquez ce que vous faites, plus votre script sera facilement compréhensible.

Pensez de la même façon a citer vos sources et a garder le nom de l’auteur.

Ca commence a devenir compliqué avec tous ces { et ces } Comment je sais ou je dois les mettre ? Ca peut effectivement devenir compliqué. Plus le script est compliqué, plus les « imbrications » sont délicates. C’est pour cela qu’il faut utiliser l’indentation… comme je l’ai fait.

On peut aussi mettre des lignes blanches, pour aérer le script. Ou utiliser des commentaires pour séparer le script en blocks.

Comme d’habitude, cela deviendra de plus en plus simple avec l’usage.

Qu’est ce que c’est que ce « Else » ? Vous vous souvenez du format d’un test ?

if ( condition ) { fait_ceci; fait_cela; fait_autre_chose; }

Maintenant, un test un peu plus poussé s’écrit comme cela.

if ( condition ){ fait_ceci; et_cela;}else{ fait_ca_a_la_place; et_encore_ca;}

Page 63: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

De façon simple, si la condition n’est pas réalisée, le script passe au « else » a la place.

Si nous regardons notre script. On test si la variable temporaire oRing est égale a OBJECT_INVALID. C’est a dire, si le personnage ne possède pas l’objet, alors attaque. Sinon ( « else » ) soit gentil.

Pour beaucoup, lire un test est une chose compliquée. N’hésitez pas a faire un petit dessin, ou un diagramme.

Qu’est ce que c’est que ces nouvelles commandes ? Je pense qu’elles sont assez simple a comprendre.ActionAttack fait attaquer l’objet passé en paramètre.ActionPlayAnimation fait faire au npc une animation, dans notre cas, celle nommée ANIMATION_FIREFORGET_GREETING. C’est juste un moyen barbare de demander au npc de faire un coucou.

Une dernière petite chose.Cette leçon est déjà assez grosse, mais j’aimerai ajouter une dernière chose. Bon ok, j’aimerai en ajouter… 251… mais je vais tâcher de ne pas vous assommer. )

Comment changer le comportement de notre garde et lui faire faire exactement l’inverse ? C’est a dire, attaquer si le personnage porte l’anneau ? Disons par exemple que cet anneau est un anneau volé.

Nous pourrions très bien déplacer des blocks de script et les intervertir. Au risque de se tromper. Mais il y a beaucoup plus simple. Il est possible d’obtenir ce résultat en changeant simplement un caractère !

La ou on avait

if (oRing == OBJECT_INVALID)

mettez

if (oRing != OBJECT_INVALID)

« != » est une autre sorte de comparaison. Cela signifie « différent de » ou « non égal à ».

Conclusion.Il y a beaucoup de nouvelles idées dans cette leçon. Mais quand vous l’aurez maîtrisée, vous aurez déverrouillé le vrai pouvoir derrière la programmation. Combiner les tests avec les variables locales, ouvre toutes sortes de possibilités.

Cours IV

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.

Page 64: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

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 booléenne ». 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.

Page 65: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

//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 se demanderont… Et si je veux ajouter plusieurs comportements 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// Appelé 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’ennuie."); 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 ».

Page 66: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

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.

Cours VIntroductionLe but de cette série de leçons, est d'apprendre a se servir des scripts a n'importe qui.

Maintenant vous commencez a en connaître un rayon sur les scripts, je pense que tous ceux qui ont suivi mes leçons jusqu’ici et qui arrivent a les mettre en pratique ne sont plus des quiches en programmation

Il y a bien sur encore beaucoup de choses qui peuvent être dites, mais avec ce que vous avez appris jusqu'à présent vous êtes d’hors et déjà capables de faire de chouettes scripts.

Voici un exemple de script un peu plus compliqué. Il requiert un peu de travail et introduit de nouvelles commandes, mais je pense que le jeu en vaut la chandelle.

Ouvrez le module de Test. Reprenez votre première « Area », on a assez travaillé avec ce garde. Virez moi ce chanteur. Mettez un « start point » a votre module. A l’autre bout de la zone, placez un npc, un « commoner » par exemple, en fait cela n’a que peu

d’importance, on va changer pas mal de choses. Dans l’onglet « Basic » changez son nom en « Cible », son tag en « CIBLE », sa race en "Construct", son

apparence en « Archery Target », son genre en « None » et son portrait en po_PLC_F01_ . Dans l’onglet « Advanced » cochez la case « Plot ». Allez dans l’éditeur de faction. Créez une nouvelle faction « Cible », dont la faction parente est « Hostile ».

Mettez les Cible - Commoner et la Commoner - Cible a 50 Changez la faction de notre cible en « Cible ». Dans l’onglet « Scripts », supprimez tous les scripts. Dans notre cas, nous ne voulons pas que notre cible

se retourne contre son agresseur et l’attaque Mettez le script suivant dans le « OnDamaged ».

// Script de « OnDamaged » : tm_cible_dm// Script de Cible.// Produit un "thunk" lorsqu’elle est touchée //void main(){ if (GetWeaponRanged(GetLastWeaponUsed(GetLastAttacker()))) { SpeakString("**Thunk**"); }}

Vous pouvez d’hors et déjà tester votre cible, mais ce n’est pas le plus intéressant. Placez un « Waypoint » a environ un carré de votre cible. Donnez lui le tag « CibleWp001 ». Placez un autre npc commoner près de votre Waypoint. Changez son tag en « Tireur ». Laissez le soin au programme de choisir son nom au hasard. Dans l’onglet « Feats » ajoutez lui « Weapon Proficiency (simple) ». Dans l’onglet « Inventory », choisissez lui des « Darts ». Click droit sur les fléchettes que vous venez de lui ajoutez, changez la « Stack Size » a 3.

Page 67: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Cliquez sur Ok et équipez le npc avec. Sortez de l’inventaire en validant. Ouvrez l’onglet « Scripts ». Editez le script du « OnSpawn » et enlevez le commentaire devant le « OnHeartbeat ».Il y a une autre ligne

que nous allons décommenter, le :

SetSpawnInCondition (NW_FLAG_SET_WARNINGS);

Ajoutez egalement une ligne au début :

SetLocalInt(OBJECT_SELF, "ETATCIBLE", 1);

Allez dans le « UserDefined » et ajoutez le script suivant.

// Script « OnUserDefined »// tm_flechette_ud// Jeu de fléchette// Appelé par le OnHeartBeat script.//// Le joueur de fléchettes lance les dards de son inventaire ( 3 au départ ) // Va jusqu'à la cible. Récupère ses dards, revient et recommence.// void main(){ int nAppelePar = GetUserDefinedEventNumber(); object oCible = GetNearestObjectByTag("CIBLE"); int nCiblePrete = GetLocalInt(OBJECT_SELF, "ETATCIBLE");

switch(nAppelePar) { case 1001:  // Appelé par OnHeartbeat { // nCiblePrete est a 1 si la cible est prête. if ((GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND))) && (nCiblePrete == 1)) { // Si on a des dards dans la main droite et qu’on est prêt a les lancer, //alors faisons le. ClearAllActions(); ActionAttack(oCible, TRUE); } else { // Sinon, soit nous n’avons plus de dards, //soit nous sommes déjà en train d’aller les chercher. if (nCiblePrete == 1) { SetLocalInt(OBJECT_SELF, "ETATCIBLE", 2); ActionMoveToObject(oCible); ActionWait(0.5); ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 1.0); ActionWait(0.5); ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 1.0); ActionWait(0.5); ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 1.0); object oDestination=GetNearestObjectByTag("CIBLEWP001"); ActionMoveToObject(oDestination); CreateItemOnObject("nw_wthdt001", OBJECT_SELF, 3); ActionEquipMostDamagingRanged(); ActionDoCommand(SetLocalInt(OBJECT_SELF, "ETATCIBLE", 1)); } } break; } }}

Voilà un script un petit peu plus compliqué…

Je ne vais pas le détailler, vous avez maintenant suffisamment d’expérience pour pouvoir comprendre par vous même, je vais quand même expliquer deux ou trois petites choses.

Page 68: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

J’utilise la variable « ETATCIBLE » pour être sur que nous n’attaquons pas avant d’être prêt. Et que nous ne demandons pas plusieurs fois d’aller chercher les dards.

La commande ActionDoCommand est merveilleuse. Elle prend une commande et la place dans la file d’action. Normalement, dès que le script voir une commande SetLocalInt, il initialise la variable, dans ce cas, cela le force a attendre d’avoir fini tout ce qu’on lui a déjà demandé de faire.

La commande CreateItemOnObject est utilisée pour créer de nouvelles fléchettes. "nw_wthdt001" est le blueprint pour un dard, et le 3 est la taille du stack.

Voilà, je pense que vous pouvez comprendre le reste par vous même. Sinon, ne vous génez pas pour poser des questions…

Et… un petit exercice pour vous maintenant…J’aimerai qu’un troisième npc annonce les scores !

A vous de bosser un peu…

Cours VI

IntroductionLe but de cette série de leçons, est d'apprendre a se servir des scripts a n'importe qui.

Les Sources.Je reçois de plus en plus de demandes d'aide ces temps ci. Lorsque j'ai le temps d'aider, je ne demande pas mieux, mais je ne peux pas toujours me permettre le luxe d'expliquer en détail et de commenter chacune de mes réponses comme je le voudrais. Je me propose donc d'investir ici un peu de temps pour vous montrer comment trouver les réponses par vous même. Honnêtement, je n'ai pas la science infuse, et je ne connais pas toutes les fonctions par cœur. De plus, la plupart du temps, les réponses aux questions posées existent déjà ailleurs. Dites vous bien que malgré votre géni, si vous osez poser une question, il y en a douze qui se posent la même et un ou deux qui ont la réponse.

Il y a quatre endroits ou vous devez tout d'abord chercher les réponses, et dans cet ordre. Les " sticky topics " de ce forum. Les différents posts de ce forum. La campagne officielle. Le Toolset en lui même.

Je ne parle volontairement pas des ressources dans la langue de Shakespeare

Détaillons un peu.

La FAQ.Pour rappel, cela veut dire "frequently asked questions" et ce n'est pas pour rien. Les discussions qui ont été compilées regroupent les questions les plus fréquemment posées. Il est généralement utile d'y jeter un coup d'œil. Il n'y a pas forcément la réponse a votre question, mais peut être quelque chose qui s'en rapproche de très près. De plus, même si cela ne répond pas a votre question, cela peut vous donner des idées pour contourner le problème.

Le Forum.Tout le monde y pose ses questions, et certains se spécialisent dans les réponses. Encore une fois, il est de bon ton de faire une petite recherche avant de reposer sa question pour la dixième fois. Le forum est équipé d'outils de recherche perfectionné, n'hésitez pas a en user et en abuser. Lorsque je ne trouve pas ce que je veux par la recherche, je regarde quand même les derniers entêtes de discussions, des fois que ma question ait été posée récemment.

Si je ne trouve rien se rapportant a mon problème alors seulement je fait un nouveau post pour demander de l'aide. Sachez quand même, que plus vous vous investissez sur votre problème, plus les gens auront envie de vous aider.

Prenons un exemple.

Page 69: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

( Toute ressemblance avec un ou plusieurs fils de discussion est voulue ! Par contre, il n'est nullement dans mon intention de tourner les auteurs de ces demandes en ridicule, d'une quelconque manière que ce soit ).

Un nouveau message, et une seule question. " Comment faire un levier qui ferme une porte ? ". Une autre poste le même genre de question mais explique de façon détaillée son script, les tags qu'elle utilise et pourquoi. Elle explique qu'elle a cherché a attacher le script sur le " OnActivate " de levier, explique les variables locales qu'elle utilise...

Je ne sais pas pour vous, mais pour ma part, j'ai beaucoup plus envie de répondre a la seconde personne et de lui montrer la ou elle a pu faire une erreur. Je ne parle même pas ici de ma répulsion vis a vis des orthographes approximatives. Mais on sent au moins que cette personne s'est investie dans son script, peut être qu'elle a déjà passé des dizaines de minutes a essayer de la faire fonctionner. Alors que je ressent la première question comme : " J'ai pas envie de faire des efforts, pouvez vous en faire pour moi ? ".

Et, encore autre chose au sujet de l'aide apportée sur les forums, il est poli, même si cela n'est pas strictement nécessaire, de remercier les gens qui nous ont aidé pour un script. Juste un petit quelque chose comme ça :

// OnUserDefined Script : tm_garde_ud// Fait en sorte que le garde grogne s'il voit quelqu'un avec une arme sortie.// Dernière mise a jour le 11/07/02// Ecris par Gatsby le magnifique.// avec l'aide de Celowin.// Traduit par Amaranthe.

Les gens qui joueront votre module ne verront jamais ces remerciements, mais ceux qui " piqueront " votre code, oui. Même si vous ne connaissez pas le nom de la personne, son pseudonyme fera l'affaire.

La campagne officielle.Je vais le dire et le redire, mais cela m'énerve de voir des gens poser cette question : " Comment je fais pour faire ceci ou cela comme dans la campagne a tel endroit ? "Dans le répertoire NeverWinter Nights, il y a un sous répertoire nommé " nwn ". Vous trouverez dans ce sous répertoire les modules de la campagne officielle.

Copiez les fichiers qui vous intéressent dans le répertoire " modules ". Changez leur extension, de " .nwn " en " .mod ". Click droit, propriétés, enlevez le " Read Only ". Maintenant ce fichier peut être ouvert dans le Toolset.

Vous pouvez apprendre énormément, en regardant comme Bioware a codé telle ou telle chose. Vous cherchez a savoir comment un Npc peut commencer une conversation ? Regardez le script de Pavel dans le prélude ! Vous voulez savoir comment conjurer des créatures qui attaquent les pcs ? Regardez le script de conversation d'Aribeth dans le prélude ! Vous voulez un npc qui vous suive jusqu'à ce qu'il rencontre un autre npc, puis s'en aille ? Regardez donc dans le chapitre 1...

Il y a plein de petits trucs dans la campagne... apprenez a vous en servir. Bien sur, des fois, le code est un peu ardu a lire, surtout pour les choses compliquées, mais vous commencez a vous débrouiller en script non ? Sinon, c'est peut être que vous vous attaquez a un trop gros morceau.

Ce qui m'amène a un point que je voulais aborder depuis longtemps. Il est normal quand on veut faire un module, d'essayer de suite de scripter le truc particulier qui va faire de son module, celui dont on sera fier. Hors, au début, c'est souvent une mauvaise idée. Commencez a vous faire la main sur de petits scripts, qui prêtent moins a conséquence, et qui vous découragerons moins vite surtout. Vous devez apprendre a marcher avant de courir.

Le Toolset.Ne soyez pas étonnés, il y a beaucoup a apprendre du Toolset. C'est la dedans que j'ai appris la plupart de ce que je sais. Une fois que vous connaissez les bases de script, et vous les connaissez n'est ce pas ?, il y a beaucoup a apprendre de la documentation du Toolset, aussi minimale soit elle.

Page 70: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Vous avez sans doutes noté que quand vous éditez un script, toutes les fonctions étaient regroupées dans une fenêtre a votre droite. Vous pouvez cliquer sur chacune d'elle et avoir quelques informations dans l'écran du bas.

De plus le nom des fonctions est souvent assez explicite, utilisez donc la recherche et regardez ce que chaque fonction fait. Vous ne devriez pas tarder a trouver celle qu'il vous faut.

Prenons donc un exemple qui concerne le script écrit plus bas. Je souhaites téléporter un pc d'un endroit a un autre. Je ne sais pas comment faire, donc je commence a regarder les fonctions. Il semblerait que la fonction " ActionMoveToLocation " corresponde plutôt bien. Cependant, j'ai déjà utiliser les commandes " Move " et je sais que cela veut dire marcher. Je continue ma rechercher et je vous " ActionJumpToLocation ". Voyons donc ça de plus près. Je clique dessus et cela me dit.

// The subject will jump to lLocation instantly (even between areas).// If lLocation is invalid, nothing will happen.void ActionJumpToLocation(location lLocation)

Les deux premières lignes sont des commentaires. La première nous apprend que la fonction correspond bien a ce que l'on veut. La deuxième nous explique comment elle se comporte dans certains cas.

La troisième ligne nous explique comment mettre en œuvre la fonction. Si vous ne comprenez pas, alors relisez donc la leçon 1

Reprenons notre recherche dans la liste... Cette commande est une commande de type " Action ". Il va donc probablement que nous placions notre téléportation dans la file des actions. Si nous voulons qu'il opère immédiatement, il va nous falloir trouver quelque chose... Et si on utilisait juste " JumpToLocation " ?

Le problème suivant est, comment récupérer une " Location " a passer en argument a la fonction ? La plupart des fonctions ramenant une réponse commencent par " Get ", regardons donc celles ci. Il y a bien une fonction " GetLocation ".

Hmmmm... la commande " JumpToLocation " ne prend pas en argument ce que vous voulez bouger. C'est un petit peu plus compliqué a trouver, mais je vous laisse chercher par vous même.

Vous voyez qu'avec un peu de persévérance, et un peu d'intuition, on en apprends beaucoup... et vous verrez qu'au fil du temps, cela viendra de plus en plus facilement.

Apprenez a connaître les fonctions, vous en trouverez des usages peut être inventifs.

Continuons.Bon assez parlé méthode, faisons un peu de script.

Tout ce que nous avons appris dans les leçons précédentes concernait les nps, passons a quelque chose de différent.

En règle générale, que l’on scripte un npc, un objet ou un « trigger », la démarche est la même. Il suffit souvent de faire attention a ce a quoi fait référence le OBJECT_SELF, mais la structure et les commandes sont les mêmes.

Dans notre module de test, si vous avez suivi mes instructions, nous avons deux zones qui ne sont en rien connectées entre elles. Nous avons juste placé notre point d’entrée comme nous en avions besoin. Même si c’est utile pour les tests, c’est un peu gênant. On pourrait placer une zone de transition entre les deux mais ce serait… inintéressant. Faisons donc quelque chose de plus sympa.

Voici ce que je vous propose, dans une des zones, nous allons placer deux leviers, tous les deux en position « off » par défaut. Quand les deux leviers sont abaissés, ils provoquent l’apparition d’un portail qui permet la téléportation dans l’autre zone.

Voici comment faire pas a pas:

Page 71: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Ouvrez le Toolset, choisissez votre module, choisissez une des zones. A priori la plus grande des deux.

Placez deux leviers. "Placeable Objects", "Containers and Levers" « Floor Lever ». Donnez au premier le tag « LEVIER1 » et au deuxième le tag « LEVIER2 ». La ou vous voulez faire apparaître le portail de téléportation, placez un « WayPoint », donnez lui le

tag « TM_INWP ». Dessinez un « trigger » autour de ce « WayPoint ». Donnez lui le tag « PORTTRIG ». Mettez ce script dans le « OnUsed » de chacun des leviers. Editez le une fois en tant que

tm_levier_ou et mettez le sur les deux leviers.

// OnUsed script: tm_levier_ou // // Ce script active les leviers nommés LEVIER1 et LEVIER2.// Les deux sont levés par défaut. // Lorsque les deux sont baissés, un portail est activé au WayPoint « TM_INWP »// Et le trigger « PORTTRIG » est activé. // // Ecrit par Celowin // Le 12 Juillet 02 // void main() {  int nUsed1 = GetLocalInt(OBJECT_SELF, "ETAT_LEVIER") ;  int nUsed2 ; 

// nUsed1 et nUsed2 renseignent de manière temporaire l’état des leviers. // 0 pour « Off », 1 pour « On » // Chaque levier a son propre « ETAT_LEVIER ». // if (nUsed1 == 1)  // Si le levier est a « On » alors le placer a « Off » SetLocalInt(OBJECT_SELF, "ETAT_LEVIER", 0);  else  // Si le levier est a « Off » alors le placer a « On » SetLocalInt(OBJECT_SELF, "ETAT_LEVIER", 1);  nUsed1 = GetLocalInt(GetObjectByTag("LEVIER1"), "ETAT_LEVIER");  nUsed2 = GetLocalInt(GetObjectByTag("LEVIER2"), "ETAT_LEVIER");  if ((nUsed1==1) && (nUsed2==1))  // Est ce que les deux leviers sont a « On » ? {  // Alors créer le portail et le trigger. object oPortalSpot=GetWaypointByTag("TM_INWP"); CreateObject(OBJECT_TYPE_PLACEABLE,"plc_portal",GetLocation(oPortalSpot), TRUE); SetLocalInt(GetObjectByTag("PORTTRIG"), "READY", 1);  } }

Il y a quelques petites choses a expliquer dans ce script, mais pour la plupart, j’espère que les commentaires sont suffisants.

Prenez maintenant le trigger que vous avez dessiné. Placez ce script sur le « OnEnter ». Sauvegardez le en « tm_portail_en ».

// « OnEnter » script: tm_portal_en // // Si le portail est « On » et qu’un Pc entre dedans, // alors téléporter le Pc au WayPoint « TM_OUTWP ».// // Ecrit par Celowin // Le 12 Juillet 02.

void main() {  // Initialisation de nos variables object oPC = GetEnteringObject();  object oDest = GetWaypointByTag("TM_OUTWP");  int nReady = GetLocalInt(OBJECT_SELF, "READY"); 

// Vérifie si c’est un Pc et si le portail est « On » ? // Dans ce cas, téléporter le Pc. if ((nReady==1) && (GetIsPC(oPC)))  AssignCommand(oPC, JumpToLocation(GetLocation(oDest))); }

Page 72: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

On a presque terminé, sortez du trigger. Prenez votre zone de destination. Dessinez un « WayPoint ». Donnez lui le tag « TM_OUTWP ». Sauvegardez le tout et sortez de l’éditeur. Testez.

Ces scripts sont relativement linéaires. La seule chose qui mérite d’être précisée a mon sens est le « AssignCommand ». C’est une de ces commandes qui nous font nous demander comment on a pu vivre sans. Elle sert simplement a faire effectuer une action a quelqu’un d’autre. Nous voulons que le joueur se téléporte, donc nous lui demandons de le faire.

Un petit mot encore au sujet des variables renseignant l’état des leviers. J’utilise nUsed1 deux fois. Une fois pour chaque levier. En fait, c’est l ‘état du levier sur lequel on est. Hors plus tard, je dit que nUsed1 est l’état du LEVIER1.

Il y aura sans doutes des programmeurs qui ne trouveront pas ça très propre. Alors pourquoi l’ai je fait ? Par soucis de simplicité. Le script est suffisamment court. Il n’y a pas de besoin de rajouter une autre variable. Sur un script plus long ou plus compliqué, je l’aurai sans doutes fait.

Une autre chose a préciser est la commande « CreateObject » et pour ce faire, il faut expliquer la différence entre un tag et une référence de BluePrint.

Les objets qui sont dans le jeu ont des Tags. Il est donc possible de retrouver tout objet, déjà crée par son tag. Mais un objet qui n’a pas encore été crée n’en a pas… encore. A la place, nous utilisons un « BluePrint », une sorte de schémas de l’objet, avec toutes les instructions permettant de le créer. C’est exactement cela, le « plc_portal », la référence du « BluePrint » de l’objet Portail. Notez que pour trouver la référence du « BluePrint », j’ai juste dessiné un portail. En regardant dans l’ongle propriétés, j’ai noté sa référence.

Exercices complémentaires.Apres le cours, les devoirs a la maison… et j’aimerai beaucoup que vous les fassiez. Je ne peux en aucun cas vous y contraindre, mais je peux vous assurer qu’ils sont nécessaires afin d’assimiler ces leçons.

Essayez donc de faire ceci.A l’heure actuelle, abaisser les deux leviers active le portail. Mais une fois activé, le portail reste en place quelque soit ce qu’on fait aux leviers. Il faudrait que le portail disparaisse des que l’on relève l’un OU l’autre des leviers. Et bien sur, qu’il réapparaisse des que les deux sont baissés.

Une autre idée…Essayez de faire un portail qui marche dans les deux sens…

Je pense que le premier exercice est moyennement difficile, le second étant assez facile.Quoiqu’il en soit, bon courage et a bientôt pour une nouvelle leçon.

Tutorial sur les Scripts de BiowareEcrit par David GaiderTraduit par Théranthil

Sommaire

Page 73: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

I. Stocker des variables.........................................................................................................2II. Definir un objet...................................................................................................................5III. Creation d’objets...............................................................................................................7IV. A propos des animations..................................................................................................8V. Explication des Waypoints et Walkwaypoints..................................................................11VI. Userdefined Event est votre ami....................................................................................12VII. Un script OnSpawn mieux commente...........................................................................14VIII. Recompenser avec de l’or et des XP...........................................................................15IX. Faire des jets de compétence........................................................................................16X. Creer des objets uniques................................................................................................18XI. S'asseoir sur une chaise et Dormir.................................................................................19XII. Comment faire pour qu’un NPC entame un dialogue tout seul ?..................................20XIII. Comment faire pour que mon NPC attaque le PC avec lequel il est en train de parler?

22XIV. Comment puis je ouvrir mon magasin?........................................................................23XV. Utilisation des "Module Events"....................................................................................24XVI. Utilisation des "Area Events".......................................................................................25XVII. Utilisation des "Creature Events"................................................................................26XVIII. Utilisation des "Placeable Object Events".................................................................29XIX. Utilisation des "Trigger Events"...................................................................................31XX. Ajouter et enlever des effets.........................................................................................32XXI. Utilisez les dialogue avec les objets placables et les déclencheurs............................35XXII. Factions, cri et attaquer mes ennemis........................................................................38

Page 74: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Stocker des variables.Une des choses les plus courantes que vous aurez à faire est de stocker des variables et de les retrouver… C’est la seule manière de déterminer comment la plupart des événements vont prendre place ou bien de changer/garder l’état d’une quête.

La commande que vous utiliserez le plus fréquemment pour stocker des variables est celle ci:

void SetLocalInt(object oObject, string sVarName, int nValue)

Cette commande stocke une ‘local integer’ (un entier local). Qu’est ce que local veut bien dire  ? Cela veut dire que l’entier est référencé, ou ‘stocké’, dans "l’ oObject" que vous avez spécifié. (Il n’est pas enregistré la physiquement, mais il est plus facile de penser que c’est le cas.)

Il y a trois choses qui sont importantes à retenir ici :

le "oObject" doit être un objet valide. Vous verrez beaucoup de commandes qui renvoient un objet au début de leur structure (comme il est marqué "void" au début de la commande "SetLocalInt") Cela signifie que ces commandes retournent comme donnée le type de l’objet.

Dans tous les cas, l’objet que vous spécifié est la où "l’integer" est référencé. Si vous êtes dans un dialogue, utiliser GetPCSpeaker() retournera le PC qui est en train de parler au NPC qui est l’objet. Vous pouvez utiliser GetModule() pour enregistrer "l’integer" dans le module lui-même… Vous pouvez utiliser OBJECT_SELF pour nommer l’objet qui est utilisé dans le script actuel, etc.

C’est important parce que la variable que vous choisissez devient unique pour cet objet. Si vous

stockez une variable avec le nom "VARIABLE 1" avec la valeur 1 dans le module, c’est la seule

variable qui peut être appelée par ce nom. Vous pouvez avoir une "VARIABLE 1" enregistrée

dans un autre objet, comme un PC, et il peut avoir des valeurs complètement différentes.

La "string sVarName" est le nom que vous donnez à votre variable. Vérifiez bien qu’il soit unique. Comme toutes les strings (chaînes de caractères), il doit être entouré de guillemets (comme "VARIABLE 1" ci dessus). Les noms de variables ne différencient pas les majuscules des minuscules.

La "int nValue" est l’information que vous voulez stocker dans la variable. Tant que c’est un entier nous utiliserons cette commande, mais ça doit être un entier (sans décimales) (NdT c’est pas moi qui insiste autant, c’est Bioware) comme 1, 15 ou 320. Si vous voulez entrer différentes informations ici, vous avez besoin d’autres commandes :o SetLocalFloat = enregistrer un "float number" (un nombre avec une partie décimale)o SetLocalString = enregistrer une "string" (comme un mot, une phrase ou le nom d’un objet… Elle doit

juste être écrite entre guillemets, comme le nom de la variable.)o SetLocalLocation = enregistrer une localisationo SetLocalObject = enregistrer un objet (comme un "placeable object", un objet d’inventaire ou une

créature.)

NdT : à partir de maintenant, par soucis de clarté, j’utiliserais le terme d’integer (ou int) et non ça traduction

Comment dois-je utiliser les variables ?

Page 75: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Bien, une fois que vous avez enregistré une variable dans quelque chose, elle reste la jusqu’à ce qu’elle soit remplacée ou détruite. N’importe quand, dans un autre script (ou dans le même) vous pouvez rappeler cette variable et l’information qu’elle contient.

Si je veux rappeler le nombre que je viens d’enregistrer dans la variable, je dois utiliser cela :

int GetLocalInt(object oObject, string sVarName)

C’est exactement la même commande que celle que vous avez utilisé pour enregistrer la variable… moins la valeur actuelle de la variable (c’est ce que nous attendons)

Remarquez que ce n’est pas une commande "void"…Elle retourne un entier. Cela veut dire que vous n’utilisez pas seulement toute seule. Utilisez la pour définir tout autre "int" nécessaire dans une autre commande ou variable comme cela :

int nValue = GetLocalInt(OBJECT_SELF, "VARIABLE1")

Cela signifie que vous avez spécifié une nouvelle variable appelée "nValue" qui est égale à l’integer qui était stocké dans l’OBJECT_SELF sous le nom "VARIABLE 1"

C’est encore un peu confus ? voici des exemples.

Un bon exemple pour comprendre comment une variable peut être utilisée est de suivre la progression d’une quête. Je veux avoir une variable qui s’appelle "STORY"… quand le joueur accepte la quête, je veux lui attribuer la valeur 1. Quand il l’a fini, je lui attribue la valeur 2.

Le joueur accepte la quête…Au moment du dialogue ou le joueur accepte, je vais dans "Actions Taken" et fait un script qui entre 1 dans la variable "STORY" du PC.

void main(){ SetLocalInt(GetPCSpeaker(), "STORY", 1);}

Le joueur termine la quête…Une fois que le PC est revenu et a fait ce que le NPC veut, le NPC le félicite et la valeur 2 est stockée dans la variable "STORY" du PC.

void main(){ SetLocalInt(GetPCSpeaker(), "STORY", 2);}

Comment je sais si le joueur a accepté ou terminé la quête ?Au moment voulu dans le dialogue, vous avez juste besoin de créer un nouveau nœud pour chaque condition. L’ordinateur commencera par le haut et vérifiera tous les scripts dans la section "Text Appears When" et regarde si ils sont vrais (TRUE) (si il n’y a pas de scripts, il considérera automatiquement que c’est vrai.)

Dans ce cas, il commence ce nœud. Sinon, il passe au suivant. C’est pourquoi, vous devez lister ces nœuds du dernier au premier.

#1. (quête terminée) "Merci d’avoir accompli cette tache."#2. (quête acceptée) "Avez vous terminé cette quête ?"#3. (ni acceptée, ni terminée) "Bonjour"

Maintenant, vous avez besoin d’un script qui renvoie TRUE pour #1 si la variable "STORY" est égale à 2, n’est ce pas ?Et pour #2, le script doit retourner TRUE si la variable est égale à 1. Aucun script n’est nécessaire pour #3 car si #1 et #2 sont faux (FALSE pour le script), c’est que la quête n’a été ni acceptée, ni terminée.

Page 76: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Est-ce que la quête est terminée ?int StartingConditional(){ int nDone = GetLocalInt(GetPCSpeaker(), "STORY") == 2; return nDone;}

Est-ce que la quête a été acceptée ?int StartingConditional(){ int nAccept = GetLocalInt(GetPCSpeaker(), "STORY") == 1; return nAccept;}

Normalement, vous devriez arriver à ceci:

#1. (1er script dans "Text Appears When") " Merci d’avoir accompli cette tache."#2. (2nd script dans "Text Appears When") " Avez vous terminé cette quête ?"#3. (no script) " Bonjour "

Dans le script ci dessus, je voulais seulement que le NPC donne la quête à 1Au moment ou il fixe la variable "STORY" à 1, pourquoi est ce qu’il n’a pas crée une variable "PLOT_GIVEN" rattachée à OBJECT_SELF (c.a.d le NPC) ?

Dans ce cas, lorsqu’un autre PC qui n’aurait pas de variable "STORY" parle au NPC, vous pourriez avoir à la place du texte par défaut (#3) un dialogue divisé en 2 :||--> (script dans "Text Appears When" qui renvoie TRUE si "PLOT_GIVEN" de "OBJECT_SELF" a pour valeur 1)"Désole, je n’ai pas de travail pour vous aujourd’hui"||--> (pas de script) "Est ce que vous êtes intéressé par un travail ?"

Un exemple très simple de dialogue de quête

La chose à se souvenir est que quand vous créez votre premier nœud, juste en dessous de Root, les propositions doivent être dans l’ordre inverse de l’ordre dans lequel elles seront complétées. (cf. exemple ci dessus)

Admettons maintenant que notre NPC donne 3 boulots. Imaginez la structure suivante sous le "root" :

#1. "Je n’ai plus aucun travail pour vous."#2. "Avez vous fini le travail #3?"#3. " Avez vous fini le travail #2?"#4. " Avez vous fini le travail #1?"#5. "Est-ce que vous cherchez un travail ?"#6. "Salut!"

Il faut se souvenir que lorsqu’on clique sur un NPC, l’ordinateur commence à vérifier le script "Text Appears When" des parties du nœud. Si le script renvoie TRUE (ou si il n’y a pas de script), ce nœud est initialisé. Si il retourne FALSE, il passe à la suite. Voici la liste des scripts qui sont attribué à chaque nœud.

#1 - script dans 'Text Appears When' qui renvoie TRUE si la variable "Job" du PC a pour valeur 4:int StartingConditional(){ int nJob = GetLocalInt(GetPCSpeaker(), "Job") == 4;

Page 77: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

return nJob;}

#2 - script dans 'Text Appears When' qui renvoie TRUE si la variable "Job" du PC a pour valeur 3 (cf. ci dessus). Si le PC a fini le travail, le NPC donne la récompense et fixe la variable "Job" à 4 (plus de travail) dans "Action Taken" comme ceci :void main(){SetLocalInt(GetPCSpeaker(), "Job", 4);}

#3 - script dans 'Text Appears When' qui renvoie TRUE si la variable "Job" du PC a pour valeur 2 (cf. ci dessus). Si le PC a fini le travail, le NPC donne la récompense et le travail #3 et fixe la variable "Job" à 3 dans "Action Taken"

#4 - script dans 'Text Appears When' qui renvoie TRUE si la variable "Job" du PC a pour valeur 1 (cf. ci dessus). Si le PC a fini le travail, le NPC donne la récompense et le travail #2 et fixe la variable "Job" à 2 dans "Action Taken"

#5 - Script dans 'Text Appears When' renvoie TRUE si la variable "TalkedToJoe" du PC est fixée à 1 (cf. ci dessus). Dans le dialogue, si le PC accepte le travail #1, fixe la variable "Job" du PC à 1 dans 'Actions Taken'.

#6 – Pas de script dans 'Text Appears When' (si tous les autres scripts qu dessus sont "FALSE", c’est que le PC a parlé pour la première fois au NPC). Sur la première ligne, placez un script dans "Action Taken" qui fixe la variable "TalkedToJoe" du PC à 1.

Voilà comment stocker et rappeler des variables. Utiliser les "strings", les "object data" et autres données est un peu plus compliqué... mais ça paraîtra plus aisé maintenant que vous êtes habitué à manipuler les "integers". En espérant que ça vous aidera à débuter.

Definir un objetMaintenant, ce sujet est un peu plus compliqué…mais je me suis trouvé plusieurs fois fonçant dans un mur alors que j’essayais de faire quelque chose.

Beaucoup d’action requièrent un objet comme cible. La manière la plus facile de définir un objet est de lui avoir donné un tag particulièrement pratique…c’est génial si l’on sait quel est l’objet qui servira de cible. Mais comment faire si on ne le sait pas ? Comment faire si on veut trouver le PC le plus proche du personnage…où qu’il soit ? Comment faire si on veut cibler la créature la plus proche ? Comment faire si on veut vérifier à quelle distance se trouve quelque chose ?

Il y a de nombreuses manières de vérifier des choses comme ça… Je vais ici me focaliser sir trois :GetNearestCreature, GetNearestObject et GetDistanceBetween.

GetNearestCreature

Cette commande vous permet de trier des créature selon leur proximité par rapport à un objet et cela en suivant 3 paramètres. Notez que la cible ne doit pas être l’objet de ce type le plus proche…Si vous voulez, par exemple, localiser le second non-PC voleur humain le plus proche vous devez utiliser cette commande.La syntaxe est la suivante :

object GetNearestCreature (int nFirstCreatureType, int nFirstParameter, object oTarget=OBJECT_SELF, int nNth =1, int nSecondCreatureType=-1, int nSecondParameter = -1, int nThirdCreatureType = -1, int nThirdParameter = -1 )

Ca peut paraître un peu confus, mais nous allons y aller petit à petit.

Page 78: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

'nFirstCreatureType' et 'nFirstParameter' sont les premières caractéristiques que nous recherchons. Admettons que nous cherchons l’humain le plus proche… "nFirstCreatureType" sera l’attribut CREATURE_TYPE_ RACIAL_TYPE, et 'nFirstParameter' sera RACIAL_TYPE_HUMAN.

Qu’est ce que ça veut dire ? Vous avez jusqu’à trois qualités que vous pouvez utiliser pour affiner la recherche… en utilisant pour chacun un attribut et un paramètre.

L’objet "oTarget" est bien évidemment l’objet qui sert de centre à la recherche. Ca peut être OBJECT_SELF (et c’a l’est par défault) si vous voulez cibler la recherche sur l’objet auquel appartient le script. Vous pouvez aussi faire quelque chose d’autre comme par exemple vérifier la créature la plus proche du PC le plus proche…Mais ça vous trouverez vous même comment le faire.L’integer 'nNth' est ce que vous utilisez pour déterminer si vous voulez le premier objet le plus proche, le second…Par défaut, le script cherche le premier. Mais n’importe quel nombre que vous mettez ici déterminera combien de créature plus proche ne seront pas retenue par la recherche. Notez que n’importe quelle fonction peut être utilisée à la place du moment qu’elle renvoie un entier… Vous pouvez mettre d4() par exemple, si vous voulez chercher aléatoirement du premier au quatrième objet le plus proche.

Ici, vous avez la liste de arguments que vous pouvez utiliser pour la recherche.

CREATURE_TYPE_CLASS = classe de personnage ou de monstre CREATURE_TYPE_DOES_ NOT_HAVE_SPELL_EFFECT = Si vous recherchez une créature qui n’est

pas affectée par un sort (spécifié par la constante SPELL_*) J’imagine qu’elle ne doit pas servir souvent. CREATURE_TYPE_SPELL_EFFECT = Voici l’inverse, si vous recherchez une créature affectée par tels ou

tels sorts. Notez que tous les effets de sorts ne viennent pas de sorts. CREATURE_TYPE_IS_ALIVE = Ca s’explique tout seul ; si vous voulez ne pas tenir compte des créatures

mortes. CREATURE_TYPE_PERCEPTION = C’est un cas particulier, car techniquement ce n’es pas un attribut de

la créature, il dépend de la nature de la perception de l’objet cible…si il a par exemple été vu ou entendu. CREATURE_TYPE_PLAYER_CHAR = Cela détermine si la créature est un PC ou non.. l CREATURE_TYPE_RACIAL_TYPE = race de la créature. CREATURE_TYPE_REPUTATION = classe d’après sa réputation envers la cible.

Je ne citerais pas toutes les classes particulières, les races et les effets qui peuvent être utilisé parce qu’ils sont assez évidents. Quelque autres le sont moins, les voici :

CREATURE_TYPE_IS_ALIVE: TRUE ou FALSE (facile)

CREATURE_TYPE_PERCEPTION: PERCEPTION_HEARD PERCEPTION_HEARD_ AND_NOT_SEEN PERCEPTION_NOT_HEARD PERCEPTION_NOT_SEEN PERCEPTION_NOT_SEEN_ AND_NOT_HEARD PERCEPTION_SEEN PERCEPTION_SEEN_AND_HEARD PERCEPTION_SEEN_ AND_NOT_HEARD

CREATURE_TYPE_PLAYER_CHAR: PLAYER_CHAR_IS_PC PLAYER_CHAR_NOT_PC

CREATURE_TYPE_REPUTATION: REPUTATION_TYPE_ENEMY REPUTATION_TYPE_FRIEND REPUTATION_TYPE_NEUTRAL

(je pense que là, même sans être une bilingue en anglais vous comprenez.)

Bon, et maintenant, si je veux trouver le PC le plus proche de moi ?GetNearestCreature (CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);

Le mage ennemi le plus proche de moi ?

Page 79: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

GetNearestCreature (CREATURE_TYPE_ REPUTATION, REPUTATION_ENEMY, OBJECT_SELF,1, CREATURE_TYPE_CLASS, CLASS_TYPE_WIZARD);

L’ennemi vivant le plus proche du plus proche PC allié ?GetNearestCreature (CREATURE_TYPE_REPUTATION, REPUTATION_ENEMY,GetNearestCreature (CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,OBJECT_SELF,1,CREATURE_TYPE_REPUTATION, REPUTATION_FRIENDLY) , 1, CREATURE_TYPE_IS_ALIVE, TRUE);

Le non-PC que je puisse voir le plus proche ?GetNearestCreature (CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC,OBJECT_SELF,1,CREATURE_TYPE_PERCEPTION, PERCEPTION_TYPE_SEEN);

GetNearestObject

C’est beaucoup moins compliqué parce que vous pouvez seulement trier les objets par leur type…vous n’avez pas les multiples paramètres qu’on les créatures. Mais ça marche de la même manière :

object GetNearestObject (int nObjectType=OBJECT_TYPE_ALL, object oTarget=OBJECT_SELF, intnNth=1)

'nObjectType' est évidemment le type d’objet que vous recherchez. Si vous ne marquez rien, ce sera l’objet le plus proche, quel qu’il soit. L’objet "oTarget" correspond toujours au centre des recherches. Par défault, c’est "OBJECT_SELF".L’integer "nNth" n’a pas changé non plus, il correspond au nième objet par ordre de proximité. (le troisième si nNth=3)

Les types d’objet sont donc :

OBJECT_TYPE_ALL OBJECT_TYPE_AREA_OF_EFFECT OBJECT_TYPE_CREATURE OBJECT_TYPE_DOOR OBJECT_TYPE_INVALID OBJECT_TYPE_ITEM OBJECT_TYPE_PLACEABLE OBJECT_TYPE_STORE OBJECT_TYPE_TRIGGER OBJECT_TYPE_WAYPOINT

La non plus, je pense que la traduction n’est pas nécessaire.

GetDistanceBetween

Ca donne la distance en mètre entre 2 objets valides. Il est important que les 2 objet soient valides, sinon la distance reportée est de 0.

float GetDistanceBetween(object oObjectA, object oObjectB)

Qu’est ce que float ? Un "float" comme un integer est juste un nombre, mais il possède toujours une partie décimale. 50 est un integer, 50.0 est un "float". Si vous avez besoin, vous pouvez utiliser la commandeint FloatToInt(float fFloat) pour convertir un float en integer.

Si vous voulez simplement connaître la distance entre un objet et celui à qui appartient le script, il est actuellement plus facile d’utiliser cette commande :

float GetDistanceToObject(object oObject)

De cette manière, vous n’êtes pas constamment obligé de spécifier OBJECT_SELF dans la commande GetDistanceBetween.

Page 80: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Creation d’objetsobject CreateItemOnObject(string sItemTemplate, object oTarget = OBJECT_SELF, int nStackSize = 1)

Cette commande crée un objet (avec le tag "sItemTemplate") dans l’inventaire de l’objet "oTarget". On l’utilise souvent quand des objets sont "donnez" à un PC…ou si un NPC est supposé avoir un objet seulement pendant un certains temps. Si je suis dans un dialogue et que le NPC récompense le PC avec qui il parle avec une épée longue non magique, je mettrais un script avec la commande ci dessous dans "Action Taken" :CreateItemOnObject ("NW_WSWLS001", GetPCSpeaker());

Si je veux mettre 12 flèches normales dans un coffre qui a le tag "CHEST05":CreateItemOnObject ("NW_WAMAR001", GetObjectByTag ("CHEST05"), 12);

Note: Si vous utilisez ActionGivenItem pour pour qu’un NPC donne à un PC un objet dans son inventaire, cet objet doit déjà exister dans l’inventaire du NPC pour que l’action soit complétée. ActionGivenItem transfert l’objet de l’inventaire du NPC à celui du PC…CreateItemOnObject crée un nouvel objet dans celui ci.Note2: Je rajoute que le "sItemTemplate" utilisé dans cette commande est le tag de l’objet…C’est vrai UNIQUEMENT avec les objet standard inclus dans le jeu. Désolé, c’est tout ce que j’ai l’habitude d’utiliser avec cette commande. Si vous essayez d’utiliser cette commande avec des objets personnalisés (custom items), vous devez utiliser le blueprint resref de l’objet… et non le tag.)

La commande "CreateObject" est un petit peu différente. Elle crée un objet sur la map. Elle est souvent référencée comme "spawning". L’ "objet" peut être une créature ou un objet (inerte). Sa structure est la suivante :

object CreateObject (int nObjectType, string sTemplate, location lLoc, int bUseAppearAnimation = FALSE)

'nObjectType' est une constante qui défini quel type d’objet va être crée. Par exemple, OBJECT_TYPE_CREATURE ou OBJECT_TYPE_ITEM. Elle viens de la liste des constantes "Constants" du script editor.

La string 'sTemplate' est son 'blueprint resref'. Oui, je sais…quasiment toutes les autres commandes utilisent le tag de l’objet. Celle ci se réfère au resref, trouvé habituellement sous l’onglet "Advance" de l’objet.

Note: cette particularité est très souvent source d’erreur ! Si vous utilisez le tag à la place du resref, ça ne marchera pas !

Un emplacement (location) consiste en une zone (area), et des coordonnées xyz sur la carte (qui sont chacune connue en tant que vecteur) et d’une orientation. Il est plus facile d’utiliser la commande GetLocation(object oObject) pour obtenir toutes ces informations à partir d’un waypoint ou d’un autre objet (si vous utilisez un objet comme une créature, l’apparition se fera à l’endroit "valide" le plus proche.) Si nécessaire, vous pouvez aussi construire un emplacement en utilisantlocation Location(object oArea, vector vPosition, float fOrientation)…

Par défault, l’animation standard de l’apparition n’est pas utilisée… si vous voulez qu’elle le soit, spécifiez TRUE après "bUbeAppearAnimation"

Donc…pour créer un hobgobelin sur un waypoint déjà placé et qui a le tag "WAYPOINT1"…location spawn1 = GetLocation (GetWaypointByTag ("WAYPOINT1"));CreateObject (OBJECT_TYPE_CREATURE, "NW_BUGBEARA", spawn1);

Pour faire apparaître un magicien (avec le tag "wizard01") avec l’effet activé, à côté du PC le plus proche…void main(){ object oWay = GetWaypointByTag("WAYPOINT1"); vector vPos = GetPosition(oWay); vector vPC = GetNearestCreatureToLocation(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC, vPos); location lPos = Location(GetArea(oWay), vPos, SetFacingPoint(vPC)); CreateObject(OBJECT_TYPE_CREATURE, "wizard01", lPos, TRUE);}

Page 81: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Une dernière chose à propos des tags: Rappelez vous qu’ils font la différence entre les majuscules et les minuscules ! Si le tag de votre créature est "wizard01", ne l’appelez pas dans votre script "WIZARD01" ou même "Wizard01"…Vous verrez alors apparaître à la place un blaireau (badger). Pourquoi un blaireau ? Par ce que c’est simplement la créature convoquée par défault et donc utilisée quand l’objet qui doit apparaître est invalide.

A propos des animations.Vous avez fondamentalement deux choix quand vous ajoutez des animations aux créatures dans le jeu. Les ajouter directement ou utiliser des fonctions automatiques dans l’IA générique.

Ajouter des animations directement.

La première chose à comprendre quand vous avez affaire à des scripts d’animation est que toutes les créatures n’ont pas toutes les animations. En règle générale, si la créature est une race jouable (humain, elfe, nain, demi-orc, gnome ou halfelin), elle aura toutes les animations. Si la créature est un monstre humanoïde (orc, gobelin…) elle a la plupart des animations, ci ce n’est toutes. Les races non-humanoïdes et spécialement les oiseaux, seront très limités dans leurs animations.

La file des actions (Action Queue)La seconde chose à savoir quand vous scriptez des animations est comment utiliser la file des actions . Il y a certaines commandes de scripts qui commence par le mot "Action"…quand une créature appelle ces commandes sur elle même, elle place l’action dans une file. Le script ne passera pas à la ligne suivante avant que l’action soit terminée…jusqu’à ce qu’il n’y ait plus d’action ou la commande "ClearAllActions()".

La raison pour laquelle c’est important est qu’il y a 2 commandes principales qui sont utilisées avec les animations : ActionPlayAnimation et juste PlayAnimation. ActionPlayAnimation place la commande de l’animation dans la file…PlayAnimation demande à la créature de jouer l’animation immédiatement dès que c’est inscrit dans le script, en étant "prioritaire" sur tout autre commande placée dans la file.

Si je veux dans un script dire à quelqu’un de bouger jusqu’à un waypoint particulier puis de méditer 6 secondes, il ressemblera à ça :void main(){ object oTarget = GetNearestObjectByTag("WAYPOINT1"); ActionMoveToObject(oTarget); ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE, 1.0, 6.0);}

La créature se déplacera jusqu’au waypoint et attendra d’être arriver avant de commencer à jouer l’animation "meditate".

Si je veux fixer une variable quand il aura terminé tout cela, je devrais l’ajouter aussi dans la file. Vous pouvez faire cela avec la commande ActionDoCommand(). Cela place une commande "non-Action" (sans "Action" au début) dans la file.void main(){ object oTarget = GetNearestObjectByTag("WAYPOINT1"); ActionMoveToObject(oTarget); ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE, 1.0, 6.0); ActionDoCommand(SetLocalInt OBJECT_SELF, "Done_Meditation", 1);}

Si j’avais fait la commande SetLocalInt sans la mettre dans la file, il se serait déclenché dès que ce point aurait été atteint dans le script…probablement avant que la créature soit arrivée au waypoint.

Les deux commandes pour les animations sont les suivantes :

void ActionPlayAnimation (int nAnimation, float fSpeed=1.0, float fSeconds=0.0)

'nAnimation' est la constante pour que l’animation soit jouée (c’est l’animation que vous voulez jouer)

Page 82: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

'fSpeed' est la vitesse à laquelle l’animation est jouée…la créature peut, par exemple, tourner la tête très rapidement ou très lentement…1.0 est la vitesse normale.'fSeconds' est uniquement utilisée pour les animations en boucle (comme la méditation)…elle détermine combien de temps vous souhaitez que l’information soit jouée. Si elle est laissée nulle dans une animation en boucle, celle ci sera jouée jusqu’à ce qu’on demande de faire autre chose.

void PlayAnimation (int nAnimation, float fSpeed=1.0, float fSeconds=0.0)

Comme expliqué ci dessus, c’est la même commande que ActionPlayedAnimation, execpté que l’animation n’est pas placée à la suite…elle est jouée immédiatement.

Constantes des Animation (Animation Constants)Vous pouvez trouver une liste de toute les animations (utilisée dans la partie "nAnimation" de la commande) en sélectionnant le bouton "Constants" dans le script editor…toutes les constantes commencent par ANIMATION_*Il y a deux types d’animations : "fire-and-forget" ou FNF (tire et oublie), qui sont jouées une fois et aucune durée n’est nécessaire.

Encore un rappel : TOUS LES MODELES N’ONT PAS TOUTES LES ANIMATIONS.Juste pour mentionner aussi que les animations listées dans "Constants" ne sont pas toutes les animations que le modèle est capable de jouer (il y a une animation de mort, après tout, aussi bien qu’une animation de combat)…C’est juste la liste de toutes celles qui peuvent être jouées par le script.

Utiliser les Animation de l’IA générique.

Pour une solution rapide et facile pour rajouter un peu de vie dans vos créatures placées, l’IA générique a 2 fonctions que vous pouvez utiliser.

Dans le script générique OnSpawn ("nw_c2_default9"), il y a une liste complète des commandes qui sont toutes commentées (les commentaires sont précédés par un "//" double qui les colorie en vert et évite qu’ils soient compilés). Pour utiliser l’animation pré construite, vous n’avez qu’à enlever le "//" devant une des commandes suivantes :SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);

Ne vous tracassez pas à propos des commentaires qui sont sur la même ligne avec ces commandes…ils disent juste ce qu’ils font. Effacez simplement le double slash au début de la ligne. Ensuite vous re-compilez le script et vous le sauvegardez dans un autre fichier. Et…c’est tout ce que vous avez à faire.

Qu’est ce que cela va faire ?Fondamentalement, elles sont appellé par le OnHeartbeat (ce qui veut dire que le script est activé toutes les 6 secondes). Le script vérifie que la créature n’est pas en train de dormir, de combattre, de parler et que aucun ennemi n’est dans la ligne de vue…Si tout est okay, il joue l’animation.

'Ambient animations' signifit que la créature se déplacera aléatoirement, s’arretant de temps en temps pour se tourner vers les amis proches (créatures avec une réputation amicale) et jouer les animations "sociales" qu’il a (et, oui, ca marche avec tous les types de créature…et qu’il fera ce qu’il peut pour les créatures qui n’ont pas toutes les animations.)

'Immobile ambient animation' fait la même chose… sans le mouvement aléatoire. La créature reste sur place.

Vous pouvez donc placer plusieur crétures de ce type, par exemple, et elle se tourneront l’une vers l’autre à un interval aléatoire et sembleront parler, discuter, débattre…et même mélangeront, avec les animation ambiantes (ambient animations)

Est ce que ca marche de la même manière avec les objets placable (placeable objects)?Oui. Vous pouvez demander à un coffre de s’ouvrir en utilisant ANIMATION_PLACEABLE_OPEN, ou éteindre une lampe en utilisant ANIMATION_PLACEABLE_DESACTIVATE. Vous devez juste garder quelques conseils à l’esprit :

Page 83: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Pour les objets placable qui sont source de lumière (comme les lampes), ce n’est suffisant de juste utiliser ANIMATION_PLACEABLE_DEACTIVATE ou ANIMATION_PLACEABLE_ACTIVATE. Cela affecte juste l’apparence de l’objet. Vous devez aussi utiliser la commande SetPlaceableIllumination fixée à TRUE et préciser la zone concernée par RecomputeStaticLighting. Voici un exemple d’utilisation d’une lumière plaçable:// allume ou éteit les objets lumineux quand sélectionné// à placer dans OnUsedvoid main(){ if (GetLocalInt (OBJECT_SELF,"NW_L_AMION") == 0) { SetLocalInt (OBJECT_SELF,"NW_L_AMION",1); PlayAnimation (ANIMATION_PLACEABLE_ACTIVATE); SetPlaceableIllumination (OBJECT_SELF, TRUE); RecomputeStaticLighting (GetArea(OBJECT_SELF)); } else { SetLocalInt (OBJECT_SELF,"NW_L_AMION",0); PlayAnimation (ANIMATION_PLACEABLE_DEACTIVATE); SetPlaceableIllumination (OBJECT_SELF, FALSE); RecomputeStaticLighting (GetArea(OBJECT_SELF)); }}

Les portes ne sont pas des objets placables. La première chose que vous devez savoir à propos de ces dernières est que si une porte est déverrouillée, une créature qui doit aller à un point de l’autre côté de celle ci l’ouvrira automatiquement. A part ça, les commandes pour les portes sont les suivantes :o ActionOpenDoor: Si utilisée dans le script d’une créature, elle se déplacera jusqu’à la porte et l’ouvrira (si

elle est ouverte). Si utilisée dans le script d’une porte (ou si la commande est envoyée à la porte via AssignCommand), la porte s’ouvrira toute seule.

o ActionCloseDoor: Comme ci dessus, seulement la porte est fermée.o ActionLockObject: Si utilié dans le script d’une créature, elle se déplacera jusqu’à l’objet (ca peut être une

porte ou un objet placable.) et tentera d’utiliser sa compétence de crochetage pour l’ouvrir. A utiliser UNIQUEMENT dans le script d’une créature !

o ActionUnlockObject: Comme au dessus, sauf que l’objet est déverrouillé. o SetLocked: C’est la commande à utiliser si vous voulez verrouiller ou déverrouiller une porte ou un objet

sans l’aide d’une créature ou d’une compétence. Si 'bLocked' est fixé sur TRUE, l’objet sera fermé... Si il est fixé sur FALSE, il sera déverrouillé. (exemple: Utilisé dans le propre script d’une porte, SetLocked (OBJECT_SELF, TRUE) la fermera.)

// A mettre dans le OnHeartbeat d’une porte, il la fermera au crépuscule// et l’ouvrira à l’aube.void main(){ if (GetIsDusk() && GetIsOpen (OBJECT_SELF)) { ActionCloseDoor (OBJECT_SELF) // SetLocked est mise dans une ActionDoCommand parce que nous // voulons qu’elle soit dans la file de la porte... Nous voulons // que ActionCloseDoor soit fini avant de fermer la porte. ActionDoCommand (SetLocked (OBJECT_SELF, TRUE)) } else if (GetIsDawn() && GetLocked (OBJECT_SELF)) { SetLocked (OBJECT_SELF, FALSE); }}

Explication des Waypoints et Walkwaypoints.Un waypoint est un objet invisible qui est placé dans une zone (area) pour marquer un emplacement spécifique. Il a son propre tag (que vous pouvez choisir quand vous le créez) et peut optionellement être fait dans une "map note" (Il peut par exemple être nommé "General Store" et dans la mini map une icône apparaîtra à son emplacement…si le joueur déplace son curseur sur cette icône, ce label s’affichera).

Page 84: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

L’IA générique qui vient avec NWN est telle que vous pouvez attribuer un circuit à une créature pour qu’elle marche en suivant ces waypoints automatiquement.

Comment cela se passe t’il ?

Tout ce fait avec le tag du waypoint. Prenez le tag des ou de la créature(s) qui doivent utiliser les waypoints…ajoutez le préfixe "WP_" et le suffixe "_0X"…et la créature commencera automatiquement à les suivre dans l’ordre.

Exemple :Si j’ai un NPC guarde à qui j’ai donné le tag "GUARD". J’ai posé 4 waypoints qui forment son circuit de patrouille.Je leur ai donné les tags "WP_GUARD_01", "WP_GUARD_02", "WP_GUARD_03" et"WP_GUARD_04".D’après l’IA par défaut, quand le jeu commence, il se rendra au waypoint le plus proche (que ce soit "WP_GUARD_01" ou non) puis il se rend au waypoint suivant dans l’ordre numérique. Il continue en suivant l’ordre et en faisant une pause de une seconde à chaque waypoint. Une fois arrivé au waypoint "WP_GUARD_04" il rebroussera chemin jusqu’au "WP_GUARD_01". Si il voit quelque chose d’hostile, il se déplacera pour combattre…Après avoir terminé le combat, il reviendra à sa patrouille.

L’exemple ci dessus montre évidemment un usage simple des waypoints, bien évidemment…il y a beaucoup de manières de l’améliorer. Voici néanmoins quelques questions fréquemment posées qui pourrait vous aider :

Si j’utilise beaucoup de waypoint pour mes NPC, il y aura BEAUCOUP de waypoints à l’écran !Un waypoint ne peut pas uniquement être utilisé par une seule créature… mais un tag de créatures. Plusieurs créatures peuvent avoir le même tag, si vous le voulez. Il y a aussi quatre couleurs différentes que vous pouvez utiliser pour différencier les waypoints. Cependant, il peut arriver que vous ayez un certain nombre dans une zone donnée, selon ce que vous faites. Heureusement, les waypoint n’utilisent pas de scripts et n’utilise pas la puissance graphique. Si ils gênent l’affichage dans le toolset, il y a un bouton qui permet de les masquer (il y a aussi un bouton pour masquer d’autres chose, comme les créatures, les objet…).

Cela doit faire beaucoup de travail de renommer tous cess waypoints. Vous pouvez éditer chaque waypoint et changer son tag si vous voulez. Heureusement, vous pouvez maintenir la touche SHIFT et selectionner les waypoints dans l’ordre dans lequel vous voulez…puis faite un click droit et sélectionnez "CreateSet". Si vous entrez le nom du tag ('WP_GUARD' dans l’exemple ci dessus), le Toolset changera automatiquement leur tag et rajoutera le suffixe numéroté pour vous.

Et si je veux faire un circuit traversant une zone de transition…comme entrer dans une maison ?Ca marche très bien. Je suposse que vous avez une zone de transition normale avec le wizard (avec un suspect you would have to have a regular area transition created by the wizard, ou n’importe comment …du moment que vous ne l’avez pas scriptée vous même.J’ai récemment crée un paysan qui avait quatre waypoints, dont deux dans une autre zone (dans une maison). J’ai posé la maison dans la zone principale et connecté les deux avec une porte. Il laissa la porte ouverte après l’avoir utilisé la première fois, mais autrement ça marche très bien.

Utilisations avancées

Posts: Au lieu de lui attribuer un waypoint, vous pouvez attribuer un "post" à une créature. Créez un seul waypoint avec le préffixe "POST_" suivi du nom de la créature.

La créature restera à son poste. Si elle engage un combat, elle y reviendra dès la fin de celui ci.

Activitées de jour et de nuit: Dans le script OnSpawn par défaut, vous pouvez "décommenter" (enlever le "//")une fonction qui s’appelle 'SetSpawnInCondition (NW_FLAG_DAY_NIGHT_POSTING)'. Cela dit à la créature de différentier le jour et la nuit.

Comment ça affecte les WP?

Page 85: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Et bien, vous pouvez attribuer à la créature différents set de waypoints (ou un post différent) pour le jour et la nuit en changeant leur préfixe:waypoin de jourt: préfixe "WP_"waypoint de nuit: préfixe "WN_"post de jour: préfixe "POST_"post de nuit: préfixe "NIGHT_"Par exemple, vous pouvez dire au garde de suivre ses waypoints le jour. Alors, si le drapeau est décommenté (faudrait quand même que je trouve une autre traduction.) vous pouvez créer un waypoint "NIGHT_GUARD" dans la caserne pour qu’une fois la nuit venue, il rentre dedans.

Une dernière chose à se souvenir : quand vous faites un changement dans le script OnSpawn par défaut, vérifiez bien que vous le sauvegardez sous un nom différent…sinon ça affectera toutes les créatures de votre module.

Userdefined Event est votre ami.Sérieusement. Il n’y a pas du tout de blague la dedans. Il y aura naturellement des utilisateurs qui préfèreront aller plus en profondeur et personnaliser différents scripts pour remplacer l’IA générique…Certain voudront aller plus vite que ça monter leur propre version des fichier de l’IA qui sont inclus. C’est génial, et il n’y a rien de faux à faire ça.

Une des meilleur chose est : vous n’êtes pas obligé de.98% des scripts des créatures de la campagne officielle ont été fait en utilisant UserDefinedEvent. Je me suis assis avec Preston (un de nos scripteurs et un de nos principaux gars derrière l’IA) et j’ai posé une rapide série de choses que je voulais scripter…à propos de ce que chacun était capable de faire en utilisant UserDefinedEvent. Et c’est facile à utiliser.

Faisons une pause une seconde ici et discutons de ce que sont les événements. Fondamentalement une créature a des scripts numérotés (des ensembles d’instructions)…et chaque script est lié à des évènements. Quand un événement a lieu, il dit à la créature de lancer le bon script. Pas d’événement=le script ne marche pas.Il y a un nombre d’évènements qui sont très souvent mentionnés ici. L’évènement "OnHeartbeat" a lieu toutes les 6 secondes…donc le script lié à cet événement se lance aussi souvent. L’évènement "OnPerceived" a lieu à chaque fois que le NPC perçoit quelque chose…le script correspondant se lance. Ces scripts peuvent aussi entraîner d’autre événement qui lanceront eux même d’autres scripts…et c’est ici que l’on place le UserDefinedEvent. Fondamentalement, UserDefinedEvent permet d’accéder aux évènements normaux qu’une créature utilise (OnPerception,OnDeath,etc.) sans déranger l’IA normale ou modifier les scripts déjà existant.

Utiliser UserDefinedEvent

Il y a un script sur chaque créature qui a déjà été souvent mentionné, et c’est un de ceux que vous devriez bien connaître. C’est le script OnSpawn. C’est un événement qui marche seulement quand la créature apparaît la première fois…imaginez que c’est un script d’initialisation.

Le script OnSpawn générique a une série de commandes qui sont inactivées (précédées par "//")…mais en réalité, sans que l’utilisateur change quelque chose, tout ce long script n’exécute en fait que trois commandes : il dit à la créature de suivre les waypoint qui se réfère spécifiquement à son tag, lui donne son comportement (il répondra aux attaque des autres NPC) et génère un faible montant de trésor générique dans l’inventaire (de l’or…)Il est écrit pour permettre à l’utilisateur de définir les condition pour accéder à l’IA générique comme il le veut. Tout ce qu’il y a à faire est de repérer le "state flag" que vous voulez utiliser et d’enlever le "//" au début de la commande pour l’activer Puis sauvez le script OnSpawn sous un nom différent et utilisez le à la place de script normal…voilà, le comportement générique a été modifié.

Les "state flags" auquels nous avons besoin de faire attention sont ceux la :SetSpawnInCondition (NW_FLAG_PERCIEVE_EVENT);//OPTIONAL BEHAVIOR - Fire User Defined Event 1002SetSpawnInCondition (NW_FLAG_ATTACK_EVENT);//OPTIONAL BEHAVIOR - Fire User Defined Event 1005

Page 86: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

SetSpawnInCondition (NW_FLAG_DAMAGED_EVENT);//OPTIONAL BEHAVIOR - Fire User Defined Event 1006SetSpawnInCondition (NW_FLAG_DISTURBED_EVENT);//OPTIONAL BEHAVIOR - Fire User Defined Event 1008SetSpawnInCondition (NW_FLAG_END_COMBAT_ROUND_EVENT);//OPTIONAL BEHAVIOR - Fire User Defined Event 1003SetSpawnInCondition (NW_FLAG_ON_DIALOGUE_EVENT);//OPTIONAL BEHAVIOR - Fire User Defined Event 1004SetSpawnInCondition (NW_FLAG_DEATH_EVENT);//OPTIONAL BEHAVIOR - Fire User Defined Event 1007

Et après?Okay... Vous avez activé les "flags" que vous voulez scriptez et re sauvé la script OnSpawn. Ca vous a pris 2 minutes. Maintenant, comment l’utiliser ?

Chaque créature a une section OnUserDefined dans laquelle vous pouvez mettre un script. Pour toutes les créatures que vous avez faites, elle est complètement vide…c’est la ou nous allons faire notre script. Tout script que vous mettez ici sera lancé à chaque fois qu’un événement que vous avez "activé" (en enlevant le "//" dans le OnSpawn) se produira. Donc, si vous avez activé 'SetSpawnInCondition (NW_FLAG_DISTURBED_EVENT)', alors a chaque fois que l’inventaire de la créature est "perturbé" (quand quelqu’un vole un objet) le script OnUserDefined sera lancé. Le script OnUserDefined basique ressemblerait à ça :void main(){ int nUser = GetUserDefinedEventNumber(); if (nUser == le nombre dans le OnSpawn, de 1001 à 1007) { (faire qqch) }}

Admettons que je veuille qu’une créature fasse signe au premier PC qu’elle voit. Je vais dans OnSpawn, "j’active" 'SetSpawnInCondition (NW_FLAG_PERCIEVE_EVENT)' et je le re sauvegarde comme un nouveau script.Puis je crée un script dans OnUserDefined:// Ce script fera que le NPC salut le PC en l’apercevant// souvenez vous que si le PC commence le module dans la zone de perception du // NPC, le script ne se lancera pas (la perception n’a pas changée)void main(){ int nUser = GetUserDefinedEventNumber(); if (nUser == 1002) // OnPerception event { object oCreature = GetLastPerceived(); int nWave = GetLocalInt(OBJECT_SELF, "Wave_Once"); //vérifie que ce soit bien un PC vu la première fois if (GetLastPerceptionSeen() && GetIsPC(oCreature) && (nWave == 0)) { // salut qu’une fois SetLocalInt(OBJECT_SELF, "Wave_Once", 1); // fixe un temps pour que le NPC puisse re saluer 15 sec plus tard DelayCommand(15.0, SetLocalInt(OBJECT_SELF, "Wave_Once", 0)); // se tourne face au PC ActionDoCommand(SetFacingPoint(GetPosition(oCreature))); // salut ActionPlayAnimation(ANIMATION_FIREFORGET_GREETING); SpeakString("Hello!"); } }}

Et c’est tout. Je peux ajouter d’autres condition comme une distance minimale, voir si le PC est en face de moi…ou lui donner un comportement aussi complexe que je le souhaite…et je n’ai pas à me préoccuper du script qui est déjà dans la case OnPerceive.

Un script OnSpawn mieux commenteToutes les lignes du script onSpawn ("nw_c2_default9") n'espliquent pas comment leurs fonctions sont utilisées en réalité. Ceci est une version mise à jour que vous pouvez utiliser si vous le souhaitez.

//:://///////////////////////////////////////////////:: Custom On Spawn In

Page 87: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

//:: File Name//:: Copyright (c) 2002 Bioware Corp.//::///////////////////////////////////////////////**///::////////////////////////////////////////////////:: Created By://:: Created On://:://////////////////////////////////////////////#include "NW_O2_CONINCLUDE"#include "NW_I0_GENERIC"void main(){ // OPTIONAL BEHAVIORS (Comment In or Out to Activate ) /****************************************************************************/ //SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION); // Cela demande à un NPC de dire une ligne de son dialogue quand il percoit // un joueur. Vérifiez que la ligne que vous voulez qu’il dise est tout en haut // du dialogue du NPC qui démarre les nœuds et que vous avez placé // le script "nw_d2_gen_check" dans la case 'Text Appears When' de ce texte. // N’utilisez pas ce "flag" pour des créatures hostiles. //SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION); // Ce "flag" est similaire à celui ci dessus... ci ce n’est qu’il permet à un NPC // hostile de faire apparaître une ligne avant d’attaquer. Mettez la phrase tout en haut // du dialogue du NPC, mais placez le script "nw_d2_gen_combat" dans 'Text Appears When' //SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET); // Cela dira au NPC que lorsqu’un NPC appartenant à une faction amie est attaqué ou // attaque un ennemi (et utilise l’IA générique), ce NPC attaquera à son tour. //SetSpawnInCondition(NW_FLAG_STEALTH); // Si le NPC possède l’aptitude se cacher dans l’ombre (hide skill), elle sera utilisée // automatiquement, mais seulement quand la commande WalkWayPoints est appelée (ci dessous) //SetSpawnInCondition(NW_FLAG_SEARCH); // Si le NPC possède l’aptitude fouille (search), elle sera utilisée automatiquement, mais seulement // quand la commande WalkWayPoints est appelée (ci dessous) //SetSpawnInCondition(NW_FLAG_SET_WARNINGS); // Le NPC donnera un avertissement aux non ennelis avant d’attaquer. //SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING); // Cela sépare les waypoint du NPC entre le jour et la nuit. Normalement, un waypoint avec le préfixe // "WP" ou "POST" sera utilisé en permanance. Si ce "flag" est activé ces préfixes seront utilisés de // jour et les préfixes "WN" ou "NIGHT" le seront la nuit. //SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION); // Quand la créature est invoquée, il utilise EffectAppear() au lieu de faire un effet de fondue, mais // seulement si SetListeningPatterns est activé (ci dessous) //SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS); // Le NPC utilisera les animations communes qu’il a, et il apparaîtra plus "social" si il est placé // près d’un NPC ami. //SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS); //Pareil qu’au dessus, mais la créature bouge aussi aléatoirement. //NOTE ces animations sont automatiquement jouées pour les créatures des "Encounter". // NOTE: VOUS NE POUVEZ ACTIVER QU’UNE DES DEUX COMMANDES CI DESSUS A LA FOIS. //SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Fuis jusqu’à un waypoint et reviens peu de temps après.) //SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Fuis jusqu’à un waypoint mais ne reviens pas.) //SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (se téléporte en suretée mais ne reviens pas.) //SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (idem, mais reviens peu de temps après.) // Pour utiliser 'escape', vous avez besoin d’un waypoint vers lequel le NPC fuira avec comme tag // "EXIT_"+le tag du NPC // Cette commande peut être utilisée dans un script avec la commande ActivateFleeToExit(), // "NW_IO_GENERIC" doit être inclus // Pour les commandes "escape" qui ont "return", le NPC re spawnera à son lieu de départ. // CUSTOM USER DEFINED EVENTS/*Les paramètres suivant permettent à l’utilisateur d’activer un événement dans le NW_D2_DefaultD. Comme le script OnSpawn, ce script est fait pour être customisé pour permettre des comportements uniques. L’utilisateur défini les événement de 1000 à 1010*/ //SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - FireUser Defined Event 1001 //SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - FireUser Defined Event 1002 //SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - FireUser Defined Event 1005 //SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - FireUser Defined Event 1006

Page 88: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - FireUser Defined Event 1008 //SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - FireUser Defined Event 1003 //SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - FireUser Defined Event 1004 //SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - FireUser Defined Event 1007 // DEFAULT GENERIC BEHAVIOR (NE PAS MODIFIER)/*****************************************************************************************/ SetListeningPatterns(); // détermine quels cris le NPC entendra. WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun =FALSE, float fPause = 1.0) // 1. Regarde si un waypoint possède le tag "WP_" + TAG DU NPC + "_0X", // si c’est le cas, marche jusqu’à eux. // 2. Si le tag du waypoint est "POST_" + NPC TAG la créature y retournera après un combat. // Pour qu’un NPC recommence à suivre les waypoint après une conversation, vous devez // aller dans son fichier dialogue, dans "Other Files", appellez aussi cette commande dans les sections // "End" et "Aborted" du script GenerateNPCTreasure(); //* C’est pour créer un trésor de faible montant sur la créature}

Recompenser avec de l’or et des XPLes deux principales commandes que vous avez à utiliser .void GiveGoldToCreature(object oCreature, int nGP)

void GiveXPToCreature( object oCreature, int nXpAmount)

Il y a aucun problème pour la provenance de l’XP et de l’or. Seule la destination peut changer…c’est pourquoi on peut utiliser ces commandes de n’importe où.

Pour donner 100 po au PC avec lequel je parle (placé dans un script à l’intérieur de "Action Taken") :GiveGoldToCreature (GetPCSpeaker(), 100);

Pour donner 100 XP à chaque membre de la partie, en commençant par le plus proche :object oFirstMember = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC);object oPartyMember = GetFirstFactionMember(oFirstMember, TRUE);while (GetIsObjectValid(oPartyMember) == TRUE){ GiveXPToCreature(oPartyMember,100); oPartyMember = GetNextFactionMember(oFirstMember, TRUE);}

(Personellement, je voulais mettre cela dans une fonction pour ne pas avoir besoin de tout recopier à chaque fois.)

Quelques autres conseil qu’il est pratique de connaître en rapport avec l’expérience et l’or :

Quand vous écrivez le journal dans le "journal editor", vous pouvez assigner une "XP Value" à chaque entrée. Ce nombre peut être rappelé avec la fonction suivante :int GetJournalQuestExperience(string szPlotID)

Dans la campagne, vous avez un PlotID pour chaque quête (qui peut consister en plusieurs entrées de journal jusqu’à 'completion') et chaque PlotID a une valeur d’XP. Et nous donnons l’XP en pourcentage de quête réalisé. 50% du total pour ceci, 25% pour cela,etc.

Combien d’or quelqu’un a?int GetGold( object oTarget = OBJECT_SELF)

Pour trouver combien d’or quelqu’un a, lancez le script en lancant GetGold()…mais il ne peut littéralement cibler personne.

Si vous voulez enlever de l’or à quelqu’un d’autre :void TakeGoldFromCreature( int nAmount, object oCreatureToTakeFrom, int bDestroy = FALSE)

Si vous mettez TRUE après 'bDestroy', l’or reprise sera enlevée du module et plus personne ne pourra l’utiliser.)

Page 89: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Faire des jets de compétence.Tout d’abord, si vous ne savez pas comment un jet de compétence est fait dans D&D 3, voilà une rapide explication :

A chaque fois que vous essayez d’accomplir une action en utilisant vos compétences, vous lancez un d20 (un dé à 20 faces numérotées de 1 à 20) et vous rajoutez à ce résultat votre rang dans cette compétence et votre bonus dans la caractéristique liée à cette compétence. Plus le résultat est élevé mieux c’est, et vous essayez d’égaler ou de dépasser un DC "difficulty class" (en français DD "degré de difficulté") un nombre qui a été décidé par le DM.Admettons qu’un joueur veut utiliser sa compétence de désamorçage (Disable Traps skill) sur un piège qu’il a découvert. Le DM fixe le DC à 25 (une tache moyennement difficile). Le joueur a un rang de 8 dans cette compétence et un modificateur de +3 en dextérité (la caractéristique lié à la compétence de désamorçage). Il lance un d20 et ajoute +11 à ce jet, il a besoin de faire 14 ou plus pour réussir cette tache.Pour des choses tels que le désamorçage et beaucoup d’autres compétences, le jet est pris en main par le moteur du jeu et souvent, la seule chose demandée au DM est le DC.Cependant, Il n’y a pas dans les scripts de NWN une commande automatique qui fait ces jets pour vous si vous utilisez une compétence dans un script (que ce soit pour vérifier le succès d’une persuasion dans un dialogue ou tout autre utilisation de compétence qui n’est pas pris en charge automatiquement). Si vous voulez les utiliser, vous devez soit avoir un script qui le fait, soit utiliser la fonction que nous avons faite dans la campagne officielle.

Les fonctions de la campagne officielle

La chose que certain peuvent ne pas aimer à propos de la commande AutoDC est que le DC est généré automatiquement…il n’est pas spécifié à chaque fois. Quand le scripteur utilise cette commande, il spécifie DC_EASY, DC_MEDIUM ou DC_HARD et le DC est généré en fonction du niveau du PC.

La syntaxe est la suivante:int AutoDC(int DC, int nSkill, object oTarget)

Donc si je veux faire une persuasion difficile avec le NPC avec qui le PC parle, je peux utiliser ceci:AutoDC(DC_HARD, SKILL_PERSUADE, GetPCSpeaker());

Un commentaire ici, le jet de compétence renvoie un integer (the int) parce que la commande doit renvoyer soit TRUE soit FALSE. False (ou un "0" integer) signifie que le jet est un échec. True (ou un '1' integer) signifie qu’il est réussi.

Si vous voulez utiliser un jet de compétence dans le "dialogue editor", vous devez "séparer" la conversation…ca veut dire que pour une même réponse du PC, il doit y avoir plus d’un dialogue du NPC. Quand le dialoque est présenté comme ceci, il regarde le script dans "Text Appears when", en commençant par le nœud du haut et descendant jusqu’en bas. Le premier script qui renvoie TRUE (ou qui n’a pas de script), il l’utilise.Un exemple de script avec un jet de persuasion facile :#include "NW_I0_PLOT"int StartingConditional(){ int iCheck = AutoDC(DC_HARD, SKILL_PERSUADE, GetPCSpeaker()) == TRUE; return iCheck;}

Ainsi, vous pourriez avoir quelquechose de ce style:"Oh,Je ne peux certainement pas vous le dire, c’est confidentiel."A. <Persuade> "Oh, Je suis sur qu’il n’y a aucun mal à me le dire."B. <Threaten> "Dite le moi ou vous en surpoterez les conséquences, jeune fille."C. "Laissez moi vous dire quelque chose d’autre, alors."

Si je sélectionne l’option B, le dialoque se sépare en 2:||

Page 90: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

--> #1. (avec le script de persuasion dans 'Text Appears When') "Je suppose que vous avez raison. Ok, c’est comme ça..."||--> #2. (sans script) "Oubliez ça, je ne vous le dirais pas."#1 si le jet a été réussi, #2 la partie en cas d’échec. Si le script en #1 renvoie TRUE, cette voie est suivie est le joueur aura réussi. L’autre voie n’a pas besoin de script…si la première voie était fause, ca voudrais dire que le PC a manqué son jet.

Ecrire votre propre fonction

Pour écrire votre propre jet de compétence, vous devez suivre la même logique que si vous vouliez faire le jet un JdR sur table. Vous avez besoin du bonus du PC pour le jet de dé, du dé et du DC (choisi par le DM)

Quelques commandes que vous pouvez utiliser :

Renvoie le rang + le bonus de caractéristique de la cible:int GetSkillRank(int nSkill, object oTarget=OBJECT_SELF)

Renvoie le niveau de la créature dans une classe particulière (comme par exemple CLASS_TYPE_FIGHTER):int GetLevelByClass(int nClassType, object oCreature = OBJECT_SELF)

Celle-ci est pratique si vous voulez le niveau du PC sans tenir compte des classes:int GetHitDice(object oCreature)

Donne le modificateur d’une caractéristique particulière, pratique si vous voulez faire un jet de force uniquement, ou quelquechose de similaire..int GetAbilityModifier(int nAbility, object oCreature=OBJECT_SELF)

De toute manière, voici un exemple de jet de premier secour (Heal skill) fait à la main (à placer à l’endroit voulu dans le dialogue):int StartingConditional(){ int iDC = 20; // ou ce que le DM veut mettre int iBonus = GetSkillRank(SKILL_HEAL, GetPCSpeaker()); if ((d20() + iBonus) >= iDC) { return TRUE; } return FALSE;}

Bien évidemment, ce n’est qu’un exemple…il y a une méthode pré construite pour utiliser les soins normalement (avec la commande ActionUseSkill)…ce type de script est fait pour les jets de dé personnalisés, que, je sais, les gens veulent faire.

Creer des objets uniquesNdT: Il est ici difficile de différencier les termes "object" (qui désigne quasiment tous modèles 3D, des chaises aux personnages et aux pièges) et "item" (qui désigne ce qu’on peut avoir dans son inventaire (épée, armure…). Pour les différencier, quand j’utiliserais "objet" (entre guillemets) ça désigne le terme "object", et sans guillemets, il désigne les "items".

Comment un script crée ces propres objets qui vont au dela des objets standarts…Comment par exemple faire un effet conditionnel ? Comment puis je scripter une baguette de souhait ou une épée parlante ?

Bien, la première a réaliser est que, par opposition aux "objets" (chaise, lampe…) et aux créatures, ils n’ont pas de script propre. Vous ne pouvez pas aller dans les propriétés des objets et spécifier quels scripts utiliser…il ne peut en utiliser aucun.

Page 91: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

La seule manière par laquelle vous pouvez affecter des scripts à des objets, c’est dans le "module level". Dans les propriétées du module, vous avez 3 évènements qui affectent les objets. Deux de ces énènements sont OnAquireItem et OnUnAcquireItem. Cela veut dire qu’à chaque fois qu’un objet est pris ou laissé tomber, un événement est lancer qui démarre le script approprié. Si il n’y a pas de script, rien ne se passe.

Donc, si je veux fixer une variable quand une épée particuliaire (qui a le tag "SWORD01") est prise, je peux mettre ce script dans le section OnAcquireItem du module :void main (){ object oItem = GetObjectByTag("SWORD01"); int iVar = GetLocalInt(GetItemPossessor(oItem), "VARIABLENAME"); // ci dessous est spécifié :  "Si le déclenchement est bien celui voulu, et que aucune variable n’a été // spécifiée, fixez la variable sur le possesseur de l’objet. if ((GetModuleItemAcquired() == oItem) && (iVar == 0)) { SetLocalInt(GetItemPossessor(oItem), "VARIABLENAME", 1); }}

Cependant, ce n’est pas très utile pour scripter vos propres objets, n’est ce pas ? Por cela, vous devez tirer avantage du troisième événement du module : OnActivateItem().

Activer un objet requière un événement spécifique. Quand vous créez un objet, vous pouvez lui assigner une propriétée "Cast Spell" (lancer un sort)…et deux des choix peuvent être Unique Power et Unique Power :Self Only. La différence entre eux est que le second est simplement un déclencheur de l’événement "OnActivateItem"…le premier vous demande d’abord la cible du pouvoir unique.

Ce "Unique Power" apparaît dans le menu radial de l’objet comme n’importe quel autre caractéristique. Si vous voulez spécifier à l’utilisateur ce qu’est cette caractéristique, vous devez l’inclure dans la description de l’objet (il y a une description pour l’objet "identifié" et "non identifié", vous pouvez aussi utiliser les 2).

Quand vous écrivez le script à placer dans OnActivateItem(), il y a juste quelques références que vous devez garder à l’esprit :

Renvoie l’objet qui a déclenché l’événement OnActivateItem().object GetItemActivated()

Renvoie la cible du pouvoir unique, si il est ciblé comme un objet spécifique.object GetItemActivatedTarget()

Renvoie la cible du pouvoir unique, si il est ciblé comme un emplacement plutôt qu’un objet spécifique.location GetItemActivatedTargetLocation()

Renvoie la créature qui a activée l’objet... un peu plus pratique que d’utiliser GetItemPossessedBy.object GetItemActivator()

Et c’est tout ce dont vous avez besoin. Avec ça, vous pouvez scriptez autant de propriétées pour autant d’objets que vous le souhaitez. Gardez quand même à l’esprit que ces scripts sont spécifiques au module. Si vous prenez l’objet d’un autre module qui n’aura pas ce script in le OnActivateItem(), alors rien ne se passera.

Note: Il y a actuellement un bug avec OnActivateItem en ce qui concerne les objet à usage unique (et qui arrive aussi aux objet qui n’ont plus qu’une charge). Quand un objet est usé, il disparaît…l’événement se lance, mais toutes les commandes comme GetItemActivate renvoie un objet invalide (car l’objet n’existe plus.)

S'asseoir sur une chaise et Dormir Comment puis je dire à mon PC de s’asseoir sur une chaise ?Il n’y a actuellement pas d’ "emote" pour faire asseoir un PC sur une chaise. Jusqu’à ce qu’un soit ajouté pour les PC, le script pour faire asseoir un PC sur une chaise doit être placé dans l’objet lui même. Si vous mettez

Page 92: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

un objet placable utilisable "chaise" (la chaise doit avoir la case "Useable" cochée, et vérifiez que le PC à la place de s’asseoir), mettez le script dans la partie OnUsed de l’onglet des scripts :void main(){ object oChair = OBJECT_SELF; if(!GetIsObjectValid(GetSittingCreature(oChair))) { AssignCommand(GetLastUsedBy(), ActionSit(oChair)); }}

Quand je place un NPC dans le toolset, il reste debout. Il n’y a aucun moyen de la mettre assise ?Pas dans le toolset,non…la créature doit être debout. Elle doit être scriptée pour que quand le jeu démarre, elle trouve une chaise et s’asseye dessus grâce à la commande ActionSit.Créez un objet placable "chaise" (chair) et donnez lui le tag "CHAIR". Placez le NPC près de la chaise. Copiez et sauvez son script sous un autre nom en rajoutant cette ligne en haut du script :ActionSit (GetNearestObjectByTag ("CHAIR", OBJECT_SELF));

Notez que quand un PC parle au NPC, il se lèvent. Pour qu’il se rasseye, vous devez aller dans l’onglet "Other Files" dans leur dialogue. Vous devez voir des emplacements pour deux scripts ici, qui sont activés quand le dialogue est fini ou interrompu. Faites un script qui appelle la ligne ci dessus et il se rasseira quand le dialogue se terminera.

C’est bien tout ça, mais je veux déjà asseoir le NPC dans le tileset ?Quelques utilisateurs ont remporté du succès un suivant la même processus en l’asseyant sur une chaise…mais en trouvant un objet placable "invisible object" , placez le à la place de la chaise. Donnez lui le tag "CHAIR" et utilisez la même ligne qu’au dessus et il s’asseira la pour vous.

Et si je veux que mon PC dorme su un lit ?Il n’y a actuellement aucun moyen de dire à une créature de l’allonger sur un lit ou un "tileset" lit. Un objet placable peut être placé sur un lit, mais pas une créature.

Une créature peut cependant dormir sur un objet placable "bedroll" (paillasse) ou sur le sol. Si vous voulez qu’une créature commence le jeu en dormant, vous devez faire une copie du script OnSpawn de la créature et le sauvegarder sous un autre nom, et ensuite rajouter en haut du script les lignes suivantes :effect eLieDown = EffectSleep();effect eSnore = EffectVisualEffect (VFX_IMP_SLEEP);effect eSleep = EffectLinkEffects (eLieDown, eSnore);ApplyEffectToObject (DURATION_TYPE_PERMANENT, eSleep, OBJECT_SELF);

Réveiller votre NPCSi vous voulez qu’un NPC se réveille à un certain moment, vous devez utiliser la commande RemoveEffect. Un effet, une fois appliqué, ne peut pas avoir une variable définie comme EffectSleep, et le désactiver par cette commande. Le "pointeur" doit être sur cet effet particulier. Si l’effet est la même variable dans le même script que quand il est utilisé, vous pouvez simplement utiliser ceci :RemoveEffect (OBJECT_SELF, eSleep);

Cependant, vous devez scanner les effets d’un objet et trouver celui que vous cherchez parmi tous les autres. Le script ci dessous est un script simple pour enlever l’effet sleep à un objet. (Il est dans le OnHeartbeat de la créature et la réveille si un hostile approche à moins de 5m.):// script de réveil#include "NW_I0_GENERIC"void main(){ // si je dors if (GetHasEffect(EFFECT_TYPE_SLEEP)) { // donne l’ennemi le plus proche de moi object oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY); // si il y en a un et qu’il est à moins de 5 mètres if ((GetDistanceToObject(oTarget) < 5.0) && (GetIsObjectValid(oTarget))) { effect eSleep = GetFirstEffect(OBJECT_SELF); // regarde les effets actuels while (GetIsEffectValid(eSleep)) { // et si l’un d’eux est sommeil, mais ne viens pas d’un sort de sommeil

Page 93: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

if ((GetEffectType(eSleep) == EFFECT_TYPE_SLEEP) && (GetEffectSpellId(eSleep) != SPELL_SLEEP)) { // enlevez le RemoveEffect(OBJECT_SELF, eSleep); } eSleep = GetNextEffect(OBJECT_SELF); } } }}

Comment faire pour qu’un NPC entame un dialogue tout seul ?OK, avant tout : avant de savoir EXACTEMENT ce que vous allez faire, ne touchez PAS au script qui est normalement dans OnPerception ("nw_c2_default2"). Laissez le tranquille. Si quelqu’un vous demande de changer quelque chose dans les scripts OnSpawn et OnUserDefined de votre NPC et que vous n’êtes pas sur de ce que vous allez faire, ne le faite pas.

Comme mentionné plus haut, l’IA générique est programmée pour permettre grâce à UserDefinedEvent d’utiliser les évènements sans modifier les script par défaut.

Utiliser la méthode "OnPerceive" pour commencer une conversation.

Allez dans votre script OnSpawn. Sauvez le sous un nouveau nom. Puis, allez jusqu’à la ligne où il y a marqué 'SetSpawnInCondition (NW_FLAG_PERCIEVE_EVENT);' et activez la (enlevez le '//' double slashes au début de la ligne). Sauvegardez ce nouveau script.

Dans le fichier dialogue du NPC, allez à la toute première ligne, la où commence le dialogue avec le PC. Si vous voulez juste qu’il commence à parler avec un PC donné, ajoutez le script suivant dans "Action Taken" :void main(){ SetLocalInt(GetPCSpeaker(), "Dlg_Init_" + GetTag(OBJECT_SELF), TRUE);}

Cela fixe la variable qui est utilisé dans le script que nous allons utiliser, pour qu’il ne lance pas le dialogue plus d’une fois.

Maintenant, créez un nouveau script dans OnUserDefined event de votre NPC. Vous pouvez y mettre le script suivant:void main(){ int nEvent = GetUserDefinedEventNumber(); if (nEvent == 1002) // OnPerceive event { object oPC = GetLastPerceived(); if(GetIsPC(oPC) && GetLocalInt(oPC, "Dlg_Init_" + GetTag(OBJECT_SELF)) == FALSE && !IsInConversation(OBJECT_SELF)) { ClearAllActions(); AssignCommand(oPC, ClearAllActions()); ActionMoveToObject(oPC); ActionStartConversation(oPC); } }}

Une erreur possible: Maintenant... une raison pourquoi ca ne marche pas ? Si votre PC commence le jeu dans la ligne de perception du NPC, il n’y aura pas d’événement OnUserDefined. L’événement a lieu uniquement si le PC ‘était pas perçu et arrive à portée.

Utiliser la méthode des déclencheurs pour démarrer une conversation.

Page 94: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

C’est celle que nous avons utilisé dans la campagne officielle. Elle vous permet de déterminer à partir de quel point le NPC va courir vers le PC, et aussi déterminer sur quelle distance le NPC va courir après le PC avant d’abandonner. Pour l’utiliser, voici ce que vous devez faire :

Comment au paragraphe 2 ci dessus, dans le fichier du dialogue du NPC, allez à la toute première ligne la où le dialogue commence avec le PC. Si vous voulez seulement démarrer ce dialogue avec n’importe quel PC donné, ajoutez le script du paragraphe 2 ci dessus dans "Action Taken" :void main(){ SetLocalInt(GetPCSpeaker(), "Dlg_Init_" + GetTag(OBJECT_SELF), TRUE);}

Allez dans votre toolset. Créez un waypoint à l’endroit ou vous voulez que le NPC revienne. Mettez lui le tag "WP_RETURN_"+ le tag du NPC (donc si le NPC s’appelle Fred, le tag sera "WP_RETURN_Fred". Souvenez vous que le tag différencie les majuscules des minuscules !

Pendant ce temps, créez un nouveau déclencheur (trigger) générique et dessinez un polygone autour du NPC. Quand le PC entrera dans cette zone, le NPC courra jusqu’à lui pour lui parler. Si le NPC quitte cette zone, il arretera de lui courir après et retournera au waypoint.

Allez dans l’onglet "Script" du déclencheur et ajoutez le script suivant dans OnEnter :// C’est le script OnEnter du trigger si vous voulez // que le NPC déclenche le dialogue.// remplacez bien "NPC_TALKER" par le script du NPCvoid main(){ object oNPC = GetObjectByTag("NPC_TALKER"); object oPC = GetEnteringObject(); if(GetIsPC(oPC) && GetLocalInt(oPC,"Dlg_Init_" + GetTag(oNPC)) == FALSE && !IsInConversation(oNPC)) { AssignCommand(oPC,ClearAllActions()); AssignCommand(oNPC,ClearAllActions()); AssignCommand(oNPC,ActionMoveToObject(oPC)); AssignCommand(oNPC,ActionStartConversation(oPC)); }}

Maintenant, nous voulons éviter que le NPC poursuive le PC sans arrêt. Entrez le script suivant dans l’emplacement OnExit du déclencheur (trigger):// Cela va demander au NPC d’arrêter de poursuivre le PC// si il quitte la zone du déclencheir (trigger)// emplacez bien "NPC_TALKER" par le script du NPC.// Vous devez aussi avoir un waypoint avec le tag "WP_RETURN_" + tag du NPC.// Il doit être placé à l’endroit de départ du NPC.void main(){ string sTag = "NPC_TALKER"; object oExit = GetExitingObject(); if(GetTag(oExit) == sTag) { AssignCommand(oExit,ClearAllActions()); AssignCommand(oExit,ActionMoveToObject(GetNearestObjectByTag("WP_RETURN_" + sTag))); }}

Cette méthode ne tiens pas en compte si le PC est visible ou pas…traverser la zone du déclencheur activera le NPC. Si vous voulez en tenir compte, ajoutez la ligne suivante juste après "if(GetIsPC(oPC) &&" dans le script OnEnter:

GetObjectSeen(oPC, oNPC) &&

Mais, en multijoueur, le NPC essayera de parler avec chaque PC. Si vous voulez qui courre vers seulement un PC, faites ce qui suit :

Dans le script du dialogue, remplacez 'GetPCSpeaker()' par 'OBJECT_SELF'.

Dans le script OnUserDefined (pour la première méthode) ou le OnEnter (pour la seconde), remplacez "oPC" dans la commande GetLocalInt par "oNPC".

Page 95: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Comment faire pour que mon NPC attaque le PC avec lequel il est en train de parler?

Je voudrais ajouter un script qui fait que le NPC devienne hostile. Placez le script dans la case "Action Taken" en bas à droite de l’éditeur de dialogue…vérifiez que vous avez bien sélectionné le nœud où vous voulez que la battaille commence. Si vous voulez que la faction du NPC devienne hostile contre la cible, utilisez le script générique "nw_d1_attonend"://:://///////////////////////////////////////////////:: Attaque à la fin de la conversation.//:: NW_D1_AttOnEnd//:: Copyright (c) 2001 Bioware Corp.//::///////////////////////////////////////////////*Le script dit au NPC d’attaque le PC avec lequel il est en train de parler.*///::////////////////////////////////////////////////:: Created By: Preston Watamaniuk//:: Created On: Nov 7, 2001//:://////////////////////////////////////////////#include "NW_I0_GENERIC"void main(){ AdjustReputation(GetPCSpeaker(), OBJECT_SELF, -100); DetermineCombatRound();}

Si vous voulez juste que seul le NPC devienne hostile et attaque, utilisez le script générique "nw_d1_attonend02"://:://///////////////////////////////////////////////:: Attaque à la fin de la conversation.//:: NW_D1_AttOnEnd02//:: Copyright (c) 2001 Bioware Corp.//::///////////////////////////////////////////////*Le script dit au NPC d’attaque le PC avec lequel il est en train de parler.Il ne change que l’attitude du NPC, pas de la faction toute entière.*///::////////////////////////////////////////////////:: Created By: Preston Watamaniuk//:: Created On: Nov 7, 2001//:://////////////////////////////////////////////#include "NW_I0_GENERIC"void main(){ SetIsTemporaryEnemy(GetPCSpeaker()); DetermineCombatRound();}

Une chose dont il faut se méfierSi vous appliquez ce script au nœud ou le NPC est en train de parler, il deviendra hostile tout de suite et le nœud ne sera pas affiché. Comme si le NPC n’avait pas le temps de le lire entièrement, si c’est une longue partie du dialogue.

Si vous êtes d’accord avec ça, tant mieux. Sinon, utilisez le bouton Add pour rajouter un nœud après le dernier nœud du NPC. Effacez le texte de la réponse du PC et appuyez sur Enter…Cela affichera un nœud [End Dialogue]. Ajoutez le script dans la zone "Action Taken" de la fin du dialogue à la place de l’autre emplacement. Comme cela, le Pc peut lire ce que le NPC lui dit…et quand il appuie sur "Enter" pour continuer, le NPC attaque.

Problèmes fréquents: Verifiez que la créature qui doit entammer le combat n’a AUCUN niveau en "Commoner". Les roturiers sont définis par l’IA pour prendre la fuite face à quelqu’un hostile, et de former un groupe uniquement si il y a des roturiers de niveau 10 ou plus à proximitée.

Page 96: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Vérifiez aussi que si vous utilisez les "Special Behaviors" (comportements spéciaux) dans le script OnSpawn, vous n’utilisez pas le comportement "Herbivore" (on ne sait jamais ;)). Les herbivores n’engagent jamais le combat et prennent toujours la fuite.

Comment puis je ouvrir mon magasin?Créer des magasin basiques est relativement simple…tout ce que vous avez à faire est d’utiliser le "store wizard" et ça vous crée un "objet" magasin basique avec un inventaire, un pourcentage d’augmentation ou du réduction du prix, un nom et un tag. Mais qu’est ce que vous allez faire avec ?

Etape 1: Placez l’  "objet" magasin dans votre module. Un magasin est juste un blueprint non placé auquel on ne peut accéder par le module. Vous devez maintenant le placer quelque part. Vous noterez que quand vous le placez, il ressemble juste à un waypoint…c’est bien. Les joueurs ne le verront pas et ne pourront pas interagir avec…il a juste besoin d’exister, de préférence près de l’objet qui va l’appeler (le marchant par exemple).

Etape 2: Créez l’objet y accèdent. Habituellement, c’est un NPC marchant... mais ce n’est pas obligé.Tout objet qui peut lancer un script peut ouvrir un magasin. Cependant, avoir un marchant PNC est le moyen le plus facile. Créez simplement votre marchant et allez créer un dialogue pour lui. La méthode la plus simple est de lui faire dire "Bienvenue ! Est ce que vous voulez jeter un œil à mes marchandises ?" Puis d’ajouter deux réponses : "Oui" et "Non"

Etape 3: Ajouter le script qui ouvrira le magasin. Dans le dialogue ci dessus, vous devez entrer ce script dans "Action Taken" pour la réponse "oui" du joueur…donc quand le joueur sélectionnera cette réponse, le magasin est ouvert. Vous n’avez rien besoin d’ajouter dans "No"…cela terminera simplement la conversation.Le script basique pour ouvrir un magasin à la fin du dialogue est celui ci :void main(){ object oStore = GetObjectByTag("STORE_TAG_HERE"); OpenStore(oStore, GetPCSpeaker());}

...et c’est tout. Naturellement, vous devez remplacer "STORE_TAG_HERE" par le tag de votre magasin..Si vous regardez la structure de la commande OpenStore, vous verrez que vous pouvez rajouter marque d’une réduction et une augmentation du prix…c’est juste au cas ou vous voulez en faire une utilisation conditionnelle. Prenez le script qui suit par exemple…le vendeur double les prix pour les elfes (il ne les aime pas) :void main(){ object oStore = GetObjectByTag("STORE_TAG_HERE"); if (GetRacialType(GetPCSpeaker()) == RACIAL_TYPE_ELF) { OpenStore(oStore, GetPCSpeaker(), 100); } else OpenStore(oStore, GetPCSpeaker());}

Un dernier commentaire sur les magasinsLes magasins ne peuvent pour l’instantoffrir que des objets génériques, c’est un peu limité. Peut être que ça changera dans le futur. Sachez que vous ne pouvez pas ajuster le prix des objets individuellement…un marchant applique les même majorations ou réductions à tous les objets…de même vous ne pouvez pas préciser quels types d’objets le marchant pourra acheter ou non. C’est tout ou rien. Une dernière chose, dans tous les scripts, les commande en rapport avec les objets comme CreateItemOnObject, GetFirstItemInInventory et GetNextItemInInventory doit avoir pour cible le magasin lui même. Souvenez vous : c’est lui qui a l’inventaire, pas le marchant.

Utilisation des "Module Events"Quand des évènements sont déclenchés (dans n’importe quel module, que ce soit objet valable, ou quelque chose d’autre.), la part la plus importante de l’utilisation des évènements via les scripts est d’être capable

Page 97: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

d’identifier qui ou qu’est ce qui a déclenché les évènements. Gardez à l’esprit que c’est séparé du UserDefinedEvent…ce sont des événement qui sont "hard codés" dans chaque objet individuel. Vous assignez un script à cet événement et, quand il est déclenché, ce script se sancera.

Liste des "Module Event"

Evenement (event): OnAcquireItemdéclencheur: à chaque fois qu’un objet est ajouté à l’inventaire de quelqu’unQu’est ce qui l’a déclenché ? Utilisez GetModuleItemAcquired().Aussi utilisé dans: GetModuleItemAcquiredFrom() pour retourner l’ "objet" qui a donné l’objet

GetItemPossessor(object oItem) pour retourner celui qui a "gagné" l’objet.

Evenement (event): OnActivateItemdéclencheur: à chaque fois qu’un objet utilise une capacité spétiale de l’objet à fin d’incantation, qu’il soit ciblé

(Unique Power) ou non (Unique Power-Self Only) Qu’est ce qui l’a déclenché ? Utilisez GetItemActivated().Aussi utilisé dans: GetItemActivatedTarget() pour déterminer la cible du sort si il est ciblé,

GetItemActivatedTargetLocation() pour déterminer l’emplacement du sort, si la cible est un point,GetItemActivator() pour déterminer le possesseur de l’objet au moment ou il a été activé.

Evenement (event): OnClientEnterdéclencheur: à chaque fois qu’un jour arrive dans le moduleQu’est ce qui l’a déclenché?Utilisez GetEnteringObject() pour renvoyer l’"objet" joueur (savoir quel est le joueur qui est rentré.)

Evenement (event): OnClientLeavedéclencheur: à chaque fois qu’un joueur quitte le moduleQu’est ce qui l’a déclenché? Utilisez GetExitingObject() renvoie l’"objet" joueur (savoir quel est le joueur qui est sorti).

Evenement (event): OnModuleLoaddéclencheur: quand le module démarre la première foisQu’est ce qui l’a déclenché ? Le module lui même... Il n’y a pas d’objet spécifique qui rentre dans cette case. C’est le script OnSpawn du module, ill est lancé une fois, quand le module est chargé.

Evenement (event): OnPlayerDeathdéclencheur: un PC meurtQu’est ce qui l’a déclenché? Utilisez GetLastPlayerDied() pour renvoyer le PC qui vient de mourir. Utilisation par défaut: le script "nw_o0_death" est généralement utilisé ici, qui annule toute relations avec la faction standard du joueur et détermine quand le panneau "death GUI" qui permet au joueur de quitter ou de respawn.

Evenement (event): OnPlayerDyingdéclencheur: un joueur a été réduit en dessous de 0 point de vieQu’est ce qui l’a déclenché? Utilisez GetLastPlayerDying(). La différence entre celui la et OnPlayerDeath est que la lee PC n’a plus de points de vie, mais n’est pas encore officiellement "mort". Utilisation par défaut: Le script placé ici par défaut est "nw_o0_dying" qui applique les effets de la mort au joueur (EffectDeath) et le tue officiellement pour déclencher l’événement "OnPlayerDeath". Si le script est enlevé, le joueur saignera jusqu’à sa mort à –10 points de vie.

Evenement (event): OnPlayerLevelUpdéclencheur: un joueur monte de niveauQu’est ce qui l’a déclenché? Utilisez l’objet GetPCLevellingUp(). Cela renvoie le joueur qui a monté de niveau... mais il n’y a aucune manière d’empêcher le joueur de terminer le processus, comme de le faire instantanément ainsi que de faire une action comme se reposer.

Page 98: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Utilisation des "Area Events"Gardez à l’esprit que quand vous créez des scripts pour les évènements de la zone (Area events) (ou pour les évènements du modules (Module events)) "l’éxécutant" par défaut de n’importe quelle  "commande action" (toutes les commandes commençants par le mot Action) est la zone (area) elle même.

Si vous référez à OBJECT_SELF, vous vous référez à la zone.. Si vous utilisez une commande commençant par Action comme ActionMoveToObjet sans utiliser AssignCommand pour envoyer cette commande à une créature, vous demandez à la zone de bouger (qui, évidemment, ne le peut pas). Gardez ça simplement à l’esprit quand vous codez, comme ça, vous pouvez faire la différence entre dire à la zone de faire quelque chose et dire à quelque chose de faire quelque chose (pas très précis hein ?).

Liste des évènements de la zone "Area Events"

Evènement: OnEnterdéclenché par: quelque chose (pas forcement un PC) qui est entré dans la zoneQu’est ce qui l’a déclenché? Utilisez GetEnteringObject() pour renvoyer l’objet dans la zone.Un exemple: Disons que vous voulez fixer une variable "PC_Entered" qui était dans la zone à chaque fois qu’un PC entre dans celle ci (avec l’objet qui est égale à "PC")…et cela envoie un événement UserDefined à une créature particulière dans la zone avec le tag "HUNTER"(Je pouvais avoir un événement OnUserDefined pour cette créature qui l’envoie chercher le PC). Vous devez pour cela mettre le script suivant dans le OnEnter de la zone : void main(){ object oEntering = GetEnteringObject(); object oMonster = GetObjectByTag("HUNTER"); // si l’ojet entrant est un PC if (GetIsPC(oEntering)) { // fixer la variable à la valeur du PC SetLocalObject(OBJECT_SELF, "PC_Entered", oEntering); // envoyer un UserDefinedEvent numéro 100 au monstre SignalEvent(oMonster, EventUserDefined(100)); }}

Evenèment: OnExitdéclenché par: quelqu’un qui a quitté la zone actuelleQu’est ce qui l’a déclenché? Utilisez GetExitingObject().Un exemple: Reprennons le script ci dessus et fixons la variable "PC_Entered" à OBJECT_INVALID si le PC qui la zone. Vérifions aussi si l’objet sortant est le monstre ci dessus (chassant le PC, sans doute)…et si c’est le cas, demandons lui de revenir dans la grotte (où il y a un waypoint avec le tag "HUNTER_CAVE")void main(){ object oExiting = GetExitingObject(); object oMonster = GetObjectByTag("HUNTER"); object oCave = GetObjectByTag("HUNTER_CAVE"); // si l’objet sortant est un PC if (GetIsPC(oExiting)) { // fixer la variable de la zone à OBJECT_INVALID SetLocalObject(OBJECT_SELF, "PC_Entered", OBJECT_INVALID); } // Si l’objet sortant est le monstre if (oExiting == oMonster) { //demander lui d’arrêter ce qu’il est en train de faire. AssignCommand(oMonster, ClearAllActions()); // demandez lui de retourner dans sa caverne. AssignCommand(oMonster, ActionMoveToObject(oCave)); }}

Evènement: OnHeartbeat

Page 99: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

déclenché par: Rien n’est requit pour déclencher cet évènement... tout script qui est placé ici se déclenchera toutes les 6 secondes. Comme avec les évènements du module, faite attention en plaçant ici un script qui se lancera constamment.

Evènement: OnUserDefineddéclenché par: Il peut seulement être déclenché par quelqu’un utilisant la commande SendSignal pour envoyer un UserDefined event à l’objet "zone" (Habituellement via la commande GetArea ou GetObjectByTag en utilisant les tags de la zone).

Utilisation des "Creature Events"Comme mentionné précédemment dans le post "UserDefinedEvent est votre ami", tant que vous ne savez pas exactement ce que vous faites, ne modifiez pas l’IA par défaut qui est utilisé pour les créatures (excepté le script OnSpawn qui est fait pour ça). Il est parfaitement possible d’activer tous les "flag" du script OnSpawn et d’écrire un script OnUserDefined associé à chaque numéro d’événement (Tous les exemples ci dessous sont des script OnUserDefined qui le font).

Liste des évènements des créatures. (Creature event)

Evènement: OnPerceptiondéclenché par: quelque chose qui entre dans la zone de perception de la créature. Ca ne veut pas dire que la créature entend ou voit quelque chose…mais juste quand c’est possible pour lui de la percevoir. Qu’est ce qui l’a déclenché? Utilisez GetLastPerceived() pour renvoyer la dernière créature percus. (qu’elle soit encore en vue ou non).Aussi utilisé dans: GetLastPerceptionHeard() renvoie TRUE ou FALSE selon que le dernier objet perçu ai été

entendu ou non, GetLastPerceptionInaudible() renvoie TRUE ou FALSE selon que le dernier objet perçu soit devenu inaudible ou non, , GetLastPerceptionSeen() idem que GetLastPerceptionSeen() pour la vue, GetLastPerceptionVanished() renvoie TRUE ou FALSE selon que l’objet soit encore visible ou non. Une chose dont il faut se servir :

Toutes les commandes ci dessus sont en rapport uniquement avec le OnPerception event. Ne les utilisez pas n’importe où.Qu’est ce que fait le script d’IA par défaut ? L’IA générique de OnPerception dit en priorité à la créature de se mettre en mode recherche si un ennemi disparaît subitement, puis de l’attaquer dès qu’elle réapparaît.

Exemple : Je veux que mon humain se tourne vers tous ceux qu’il voit, mais si c’est une femme, il s’incline devant elle :void main(){ int nEvent = GetUserDefinedEventNumber(); // si l’événement OnPerception est lancé if (nEvent == 1004) // OnPerception event { object oTarget = GetLastPerceived(); // si je peux voir la personne dans la limite de perception if (GetLastPerceptionSeen()) { // mettre la commande pour se tourner dans la file ActionDoCommand(SetFacingPoint(GetPosition(oTarget))); } // si il s’agit d’une femme if (GetGender(oTarget) == GENDER_FEMALE) { // pause de 0,5 seconde ActionWait(0.5); // puis salue ActionPlayAnimation(ANIMATION_FIREFORGET_BOW); } }}

Evènement: OnSpellCastAt

Page 100: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

déclenché par: un sort a été lancé sur la créature... notez que ce n’est pas le sort lui même qui cause cet événement. Vous verrez dans votre liste de commande "EventSpelllCastAt. Le script du sort utilise cette commande sur la cible pour lui spécifié que le sort a été lancé…et la commande lui demande alors si le sort est hostile ou non. Qu’est ce qui l’a déclenché? Utilisez GetLastSpell() renvoie la constante du sort utilisé. (SPELL_*). Aussi utilisé dans : GetLastSpellCaster() pour retourner "l’objet" qui a lancé le sort,

GetLastSpellHarmful() renvoie TRUE ou FALSE selon que l’événement soit ou non marqué hostile.

Que fait le script d’IA par défaut ? Si un sort "nuisible" a été lancé sur la créature et qu’elle n’était pas en combat, elle devient hostile.

Evènement: OnPhysicalAttackeddéclenché par: the creature has been attacked in melee, Qu’est ce qui l’a déclenché?Utilisez GetLastAttacker(). Aussi utilisé dans: GetLastDamager()Qu’est ce que fait le script d’IA par défaut? Si la créature est est attaquée et qu’elle n’est pas encore en combat, elle devient hostile, et émet le cri apprprié pour alerter les alliés à proximité.

Evènement: OnDamageddéclenché par: la créature pert des points de vieQu’est ce qui l’a déclenché? Utilisez GetLastDamager().Aussi utilisé dans: GetTotalDamageDealt(), GetDamageDealtByType(int nDamageType),

GetCurrentHitPoints(object oObject = OBJECT_SELF), GetMaxHitPoints(object oObject = OBJECT_SELF)

Que fait le script d’IA par défaut? Si la créature est attaquée par quelqu’un qu’elle ne peut voir, elle essaye de le trouver. Dans les autres cas, elle trouve une cible appropriée et devient hostile.Exemple : avec cette créature particulière, si elle pert plus de la moitié de ces points de vie, elle crie quelque chose, courre au waypoint appellé "CAVE_EXIT" et disparaît.void main(){ int nEvent = GetUserDefinedEventNumber(); if (nEvent == 1006) // OnDamaged event { int nMaxHP = GetMaxHitPoints(); int nCurHP = GetCurrentHitPoints(); // si elle a moins de la moitié de ses points de vie. if (nCurHP < (nMaxHP / 2)) { // arrête ce que je suis en train de faire ClearAllActions(); // crie ActionSpeakString("Ahhh! Cours!!"); // court vers la sortie ActionMoveToObject(GetObjectByTag("CAVE_EXIT"), TRUE); // et s’autodétruit ActionDoCommand(DestroyObject(OBJECT_SELF)); // n’accepte plus de commande de l’IA à partir de maintenant SetCommandable(FALSE); } }}

Page 101: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Evènement: OnDisturbeddéclenché par: quelque chose a été rajouté ou enlevé de l’inventaire de la créatureQu’est ce qui l’a déclenché? Utilisez GetLastDisturbed() to return the creature object who disturbed the inventory.Aussi utilisé dans: GetInventoryDisturbType() retournera soit INVENTORY_DISTURB_TYPE_ADDED, soit INVENTORY_DISTURB_TYPE_REMOVED, soit INVENTORY_DISTURB_TYPE_STOLEN

GetInventoryDisturbItem() donne l’objet qui a été ajouté, enlevé ou volé de l’inventaire. Que fait le script de l’IA par défaut? Puisqu’une créature ne peut avoir un objet ajouté ou enlevé de son inventaire (ce n’est pas un contenaire), si son inventaire est modifié, il a du être volé…elle deviens hostile si il y a une cible valide.

Evènement: OnCombatRoundEnddéclenché par: A la fin d’un round de combat, l’événement est déclenché automatiquement.. Que fait le script de l’IA par défaut? Si il n’y a pas de comportement spécial spécifié ou que le "flag" du script OnSpawn n’a été modifié, un nouveau round de combat commence.

Evènement: OnConversationdéclenché par: On a cliqué sur la créature pour une conversation OU quelqu’un a parlé audiblementQu’est ce qui l’a déclenché? Utilisez GetLastSpeaker() pour renvoie la créature qui a cliqué dessus ou celle qui vient de crier.Aussi utilisé dans: GetListenPatternNumber() renvoie un numéro de "pattern" si il y en a un qui a été entré.Que fait le script de l’IA par défaut? Si quelqu’un a cliqué sur la créature, elle arrête ce qu’elle faisait et commence le dialogue (si elle le peut). Sinon le script vérifie si la phrase prononcée est reconnaissable, et si la créature a été paramêtrée pour reconnaître un cri de combat.

Evènement: OnResteddéclenché par: la créature se repose via ActionRest(). Les créature du jeu ne se reposent pas, c’est pourquoi il n’y a pas de script d’IA.

Evènement: OnDeathdéclenché par: la créature a été tuéeQu’est ce qui l’a déclenché? Utilisez GetLastKiller() pour renvoyer "l’objet" (au sens large) qui a tué la créature. Notez que tout script lancé par cet événement doit être immédiat…utiliser DelayCommand ne marchera pas car la créature ne peut pas accomplir une commande une fois morte.Que fait le script de l’IA par défaut? Il vérifie si la créature était non mauvaise et avais des niveaux de Commoner (roturier)…et si c’est le cas change le niveau du tueur un peu plus vers mauvais. Il émet aussi un cri "standard" pour demander de l’aide à toutes les créatures à l’intérieur de la zone de perception auditive (toutes les créatures qui peuvent l’entendre)

Evènement : OnBlockeddéclenché par: une porte bloque le mouvement de la créatureQu’est ce qui l’a déclenché? Utilisez GetBlockingDoor() renvoie la porte qui gène.. Notez que seule les portes déclenchent l’évènement OnBlocked event... il ne peut pas être utilisé pour détecter une collision (du moins pas encore)Que fait le script de l’IA par défaut? Si la créature est assez astucieuse pour utiliser la porte (Intelligence de 5 ou plus) elle essayera d’abord de l’ouvrir, et si ce n’est pas possible dela casser.

Evènement: OnHeartbeatdéclenché par: Il ne nécessite pas de déclencheurs... n’importe quel script placé ici se déclenchera toutes les 6 secondes. Il est important que vous n’utilisiez pas des script qui marchent en permanence dans le OnHeartBeat, l’ordinateur serait très vite dépassé (surtout si vous avez un grand nombre de créatures dans la zone.Que fait le script de l’IA par défaut? Il vérifie quelques conditions qui sont précisées dans le OnSpawn et les éxécute si elles sont applicables…comme les poste de jour et de nuit (post) pour la fonction WalkWayPoints et les animation ambientes utilisées par les créatures quand elles restent debout.

Page 102: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Utilisation des "Placeable Object Events"Comme avec les zones, la chose dont il faut se souvenir est que quand vous écrivez des scripts pour les objets placables et que vous utilisez des commandes commançant par "Action" l’éxécutant par défaut est l’objet lui même. Si vous voulez que le script demande à l’objet d’accomplir une autre commande, vous devez utiliser AssignCommand. Donc gardez à l’esprit qui si les objet placables sont capable d’accomplir des actions (comme ActionPlayAnimation avec la référence ANIMATION_PLACEABLE_*…comme Open/close ou activate/desactivate quoique tous les placables ne le peuvent pas), leur demander de faire des choses qui leur sont impossible peut causer des problèmes (ActionLockObject, ActionUnlockObjet, ActionEquipItem, ActionPickUpItem sont des exemple que vous devez pas utiliser pour des objets placables.).

Liste des évènements des objets placables (placeable object)

Evènement: OnClosedéclencheur: l’objet a été fermé (notez que seuls les objet qui peuvent être fermé ou ouvert peuvent lancer cet événement…comme un coffre ou une armoire.)qu’est ce qui l’a déclenché? Utilisez GetLastClosedBy() renvoie "l’objet" qui a fermé l’objet placable.Exemple: Voici un script OnClose qui permet de vérifier si l’inventaire est vide après qu’il soit fermé…et dans ce cas, il crée 100 po à l’intérieur.void main(){ // donner le premier objet dans l’inventaire object oInside = GetFirstItemInInventory(); // et si il n’y en a pas if (!GetIsObjectValid(oInside)) { // créer des pièces d’or au nombre de 100 CreateItemOnObject("NW_IT_GOLD001", OBJECT_SELF, 100); }}

Evènement: OnDamageddéclencheur: l’objet placable a pris des dégatsQu’est ce qui l’a déclenché? Utilisez GetLastDamager() pour renvoyer "l’objet" qui lui a infligé des dommages. Aussi utilisé dans: GetTotalDamageDealt(),

GetDamageDealtByType (int nDamageType),GetCurrentHitPoints(), GetMaxHitPoints().

Evènement: OnDeathdéclencheur: l’objet a été détruit (jouer l’animation "destruction" est automatique)Qu’est ce qui l’a déclenché? GetLastKiller() renvoie "l’objet" qui l’a détruit.

Evènement: OnHeartbeatdéclencheur: Il ne nécessite pas de déclencheurs... n’importe quel script placé ici se déclenchera toutes les 6 secondes. Il est important que vous n’utilisiez pas des script qui marchent en permanence dans le OnHeartBeat, l’ordinateur serait très vite dépassé.

Evènement: OnDisturbeddéclencheur: Un objet a été ajouté ou enlevé de l’inventaire de l’objet placablequ’est ce qui l’a déclenché? Utilisez GetInventoryDisturbType(). Le résultat est une de ces constantes: INVENTORY_DISTURB_TYPE_ADDED,

INVENTORY_DISTURB_TYPE_REMOVED INVENTORY_DISTURB_TYPE_STOLEN.

Aussi utilisé dans: GetLastDisturbed() renvoie "l’bjet" quia enlevé ou rajouté un objet, GetInventoryDisturbItem() renvoie l’objet qui a été ajouté/enlevé.

Page 103: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Exemple: Voici un script OnDisturbed qui envoie un évènement UserDefinedEvent #500 qui signale a un magicien (avec le tag "WIZARD1") si quelqu’un enlève une potion particulière (avec le tag "PRECIOUS_POTION") de l’objet placable.void main(){ object oWizard = GetObjectByTag("WIZARD1"); object oPC = GetLastDisturbed(); object oPotion = GetObjectByTag("PRECIOUS_POTION"); // si l’objet enlevé est valable et a le tag "PRECIOUS_POTION" if (GetIsObjectValid(oPC) && (GetInventoryDisturbType() == INVENTORY_DISTURB_TYPE_REMOVED) && (GetInventoryDisturbItem() == oPotion)) { // envoie le signal au mage SignalEvent(oWizard, EventUserDefined(500)); }}

Evènement: OnLockdéclencheur: L’objet a été fermé (ou refermé)Qu’est ce qui l’a déclenché? Utilisez GetLastLocked() pour renvoyer "l’objet" qui l’a fermé. Aussi utilisé dans: GetLockLockDC() renvoie le DC pour fermer l’objet placable.Note: J’ai eu quelques messages selon lesquel cet événement ne marcherait pas.

Evènement: OnPhysicalAttackeddéclencheur: l’objet a été attaqué physiquement (mais n’a pas forcement reçu de dommage)Qu’est ce qui l’a déclenché? Utilisez GetLastAttacker().

Evènement: OnOpendéclencheur: l’objet a été ouvert (pour les placables qui peuvent être ouvert et ont la case "inventory" cochée)Qu’est ce qui l’a déclenché? Utilisez GetLastOpenedBy().

Evènement: OnSpellCastAtdéclencheur: un sort a été lancé sur l’objet placableQu’est ce qui l’a déclenché? Utilisez GetLastSpellCaster(). Aussi utilisé dans: GetLastSpell() retournera la constante du sort lancé (SPELL_*),

GetLastSpellHarmful() renverra TRUE ou FALSE selon que le dernier sort lancé était hostile.

Evènement: OnUnlockdéclencheur: l’objet placable a été déverouilléQu’est ce qui l’a déclenché? Utilisez GetLastUnlocked() pour renvoyer "l’objet" qui l’a dévérouillé.Note: J’ai eu quelques messages selon lesquel cet événement ne marcherait pas.

Evènement: OnUseddéclencheur: si un objet placable a la case "Useable", alors cliquer sur cette objet lancera cet événementQu’est ce qui l’a déclenché? Utilisez GetLastUsedBy().Exemple : un script pour un objet qui soigne quiconque l’utilise.void main(){ object oUser = GetLastUsedBy(); effect eHeal = EffectHeal(GetMaxHitPoints(oUser)); effect eVis = EffectVisualEffect(VFX_IMP_PULSE_HOLY); // si l’utilisateur de l’objet est valide if (GetIsObjectValid(oUser)) { // applique l’effet usuel ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oUser); // et une seconde plus tard, soigne l’utilisateur DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oUser)); }}

Evènement: OnUserDefineddéclencheur: Cet événement se lancera uniquement si un usage particuliera été défini qui enverra un "UserDefinedEvent" à l’objet placable.

Page 104: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Utilisation des "Trigger Events"Encore une fois, soyez sur que toutes les actions que vous souhaitez que le déclencheur (trigger) mette en place sont envoyées à la cible spécifique via AssignCommand…car sinon vous demandez au déclencheur de faire quelque chose par lui même, et il ne peut pas faire grand chose.

Liste des événement des déclencheurs (Trigger Event)

Evènement: OnClickdéclencheur: Si vous voulez que le déclencheur cause en effet quand le joueur clique dessus, un script doit être entré dans la zone. Beaucoup de sorte de transitions de zones (area transition) utilisent cet événement (bien qu’un déclencheur qui est paramêtré comme une zone de transition peut utiliser le wizard pour faire cela.Qu’est ce qui l’a déclenché? Utilisez GetClickingObject() pour renvoyer "l’objet" joueur qui a cliqué dessus.

Evènement: OnEnterdéclencheur: tout objet traversant la limite de la zone du déclencheurQu’est ce qui l’a déclenché? Utilisez GetEnteringObject().Exemple: Le script OnEnter suivant ferra "sauter" tous les membres de la partie qui sont dans la même zone jusqu’au waypoint avec le tag "JUMP_HERE".void main(){ object oWP = GetObjectByTag("JUMP_HERE"); object oParty = GetFirstFactionMember(GetEnteringObject(), TRUE); // cicle qui passe en revue tous les membres de la partie. while (GetIsObjectValid(oParty)) { // si ils sont dans la même zone if (GetArea(oParty) == GetArea(GetEnteringObject())) { // jump the party member to the waypoint AssignCommand(oParty, JumpToObject(oWP)); } // va jusqu’au prochain membre de la party oParty = GetNextFactionMember(GetEnteringObject(), TRUE); } oParty = GetFirstFactionMember(GetEnteringObject(), FALSE); // maintenant, passe en revu tous les membres non-joueurs de la partie(comme les familiers) while (GetIsObjectValid(oParty)) { // et si ils sont dans la même zone if (GetArea(oParty) == GetArea(GetEnteringObject())) { // faites "sauter" les membres de la partie jusqu’au waypoint AssignCommand(oParty, JumpToObject(oWP)); } // aller au prochain membre de la partie oParty = GetNextFactionMember(GetEnteringObject(), FALSE); } // maintenant, fait sauter le PC entrant jusqu’au Waypoint // cette ligne n’est pas nécessaire…l’inclure // permet juste d’être certain de déplacer aussi le PC qui a activé le déclencheur AssignCommand(GetEnteringObject(), JumpToObject(oWP));}

Evènement: OnExitdéclencheur: à chaque fois qu’un ennemi traverse la limite de la zone du déclencheur pour la quitterQu’est ce qui l’a déclenché? Utilisez GetExitingObject() pour renvoyer l’objet sortant.Exemple: Ce script OnExit pour le déclencheur envoie une commande à n’importe quel géant sortant pour retourner à un waypoint.void main(){ object oWP = GetObjectByTag("RETURN_HERE"); object oCreature = GetExitingObject(); // si la créature sortante est un géant if (GetRacialType(oCreature) == RACIAL_TYPE_GIANT) { // lui demande d’arrêter ce qu’il fait

Page 105: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

AssignCommand(oCreature, ClearAllActions()); // et de bouger au waypoint AssignCommand(oCreature, ActionMoveToObject(oWP)); }}

Evènement: OnHeartbeatdéclencheur: comme les autres heartbeat, Le Heartbeat du déclencheur est activé toutes les 6 secondes. Un déclencheur n’est cependant pas comme tous les autres objets…il est seulement activé quand quelque chose est à l’intérieur de ces limites ou qu’on clique dessus. Vous ne pouvez placer un déclencheur et lui donner un script pour constamment commander un ordre…si vous voulez faire ça, utilisez à la place un objet invisible.

Evènement: OnUserDefineddéclencheur: encore, cet événement se lancera uniquement si un UserDefinedEvent a été spécifiquement envoyé au déclencheur par la commande SignalEvent.

Ajouter et enlever des effetsSi vous faîtes défiler la liste des commandes dans votre "script editor", vous pouvez voir une longue liste de commandes qui commencent par le mot "Effect". Ceux sont les commandes pour faire tous les sorts, les capacilés spétiales et les effets visuels dans le jeu. Il y a deux commandes qui permettent de les utiliser  : ApplyEffectToObject et ApplyEffectAtLocation. Toutes les deux sont très similaires dans leur structure, à l’exception que la cible de la première est un objet spécifique (créature, objets placables, etc) et la cible de la deuxième est un emplacement spécifique (un point dans l’espace)

void ApplyEffectToObject (int nDurationType, effect eEffect, object oTarget, float fDuration=0.0f)

Duration Type: "nDurationType" demande une constante commencant par DURATION_TYPE_*, il n’y en a en fait que trois possibles. DURATION_TYPE_INSTANT s’applique à tous les effets qui sont instantannés, permanents et ne peuvent être annulés. EffectDamage serait un exemple, ainsi que tous les objets "fire-and-forget" (tire et oublie). Si elle n’est pas "instant", la constante doit être soit DURATION_TYPE_PERMANENT…l’effet reste jusqu’à se qu’il soit enlevé ou dissipé. Une durée temporaire signifie que l’effet doit avoir une durée spécifique dans la commande (et c’est le seul moment où c’est le cas)

Effect: C’est l’effet spécifique que vous voulez utiliser Il est courant de définir d’abord une variable qui contient toutes les informations pertinentes, et ensuite de l’utiliser cette variable quand vous le voulez…mais ce n’est pas nécessaire. Chaque effet varie dans ces conditions. Quelques uns sont simplement appellés EffectSleep ou EffectCharmed et n’ont besoin de rien d’autre. D’autres ont besoin de paramêtres additionnels, comme EffectDamage ou EffectPolymorph. Je ne détaillerais pas tous les effets ici, mais il est important que vous fournissiez tous les paramêtres requis par un effet ou il sera non valide.

Target: Cela doit être soit un objet (dans ApplyEffectToObject) ou un emplacement (dans ApplyEffectAtLocation). Il peut être déclaré séparement dans une variable ou défini dans la commande.

Duration: Une durée (en seconds) est uniquement requise pour les effets avec DURATION_TYPE_TEMPORARY. Quand elle est spécifié, ce doit être un "float" (et non un integer). Donc mettez "3.0" pour 3 secondes, ou "10.5" pour 10 secondes et demi.

Quelques exemples d’effets

Dans le OnUsed d’un objet, il transforme l’utilisateur en pixie :void main(){ effect ePixie = EffectPolymorph(POLYMORPH_TYPE_PIXIE); ApplyEffectToObject(DURATION_TYPE_PERMANENT, ePixie, GetLastUsedBy());}

Un objet avec en capacité un sort unique (avec le tag "WONDERFUL_WAND" qui soigne le "hâte" la cible pour 30 secondes:void main(){ object oWand = GetItemActivated(); if (oWand == GetObjectByTag("WONDERFUL_WAND"))

Page 106: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

{ object oTarget = GetItemActivatedTarget(); int nMaxHP = GetMaxHitPoints(oTarget); int nCurHP = GetCurrentHitPoints(oTarget); effect eHeal = EffectHeal(nMaxHP - nCurHP); ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget); ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectHaste(), oTarget, 30.0); }}

Dans le OnUserDefined d’une créature, quand un événement #100 est envoyé, un blaireau générique est convoqué au waypoint avec le tag "SUMMON_POINT":void main(){ int nUser = GetUserDefinedEventNumber(); if(nUser == 100) { effect eSummon = EffectSummonCreature("bugbeara001"); location lWP = GetLocation(GetObjectByTag("SUMMON_POINT")); ApplyEffectAtLocation(DURATION_TYPE_PERMANENT, eSummon, lWP); }}

Effets visuels

Les effets visuels sont très similaires aux effets normaux, vous les appliquez de la même manière. Vous utilisez EffectVisualEffect et fournissez lui fournissez le paramêtre d’une des constantes des effets visuels…elles commencent toutes par VFX_*. Cependant, il y en a un certain nombre, et elles sont différenciées par des mentions différentes.

VFX_BEAM_* = il y a différents types de beam (poutres) visuels, et bien qu’elles soient groupées avec les autres effets visuels, ces constantes sont utilisées avec EffectBeam et non avec EffectVisualEffect.VFX_COM_* = ce sont les effets visuels de combat, presque tous sont utilisés avec une durée instantanée(INSTANT). VFX_DUR_* = beaucoup sont des effets utilisés pour les sorts. Ils doivent tous être applqiés avec une durée soit permanente, soit temporaire (PERMANENT OU TEMPORARY)VFX_FNF_* = Ils sont appellés les effets "fire-and-forget" (tire et oublie) dans le sens ou ils ne sont joués qu’une fois. Ils doivent avoir une durée instantannée (INSTANT)VFX_IMP_* = Ce sont les effets "impact", ils sont habituellement utilisés pour des effets de courte durée quand un sort frappe une cible. Ins ont une durée instantannée (INSTANT).

Voici un exemple d’un puit de sorcière magique, quand il est utilisé, il crée un effet sur lui même et augmente la force avec un effet sur la cible (mais il ne peut seulement être utilisé une fois…si il est utilisé une seconde fois, il attaque avec un éclair de 8d6 de dégats) :void main(){ effect eFirst; effect eSecond; effect eStrength = EffectAbilityIncrease(ABILITY_STRENGTH, (d4() + 1)); object oTarget = GetLastUsedBy(); int nOnce = GetLocalInt(oTarget, "Use_Pool_Once"); // si le PC n’a pas utilisé la fontaine auparavant if (nOnce == FALSE) { eFirst = EffectVisualEffect(VFX_IMP_GOOD_HELP); eSecond = EffectVisualEffect(VFX_IMP_IMPROVE_ABILITY_SCORE); // crée l’effet sur la fontaine ApplyEffectToObject(DURATION_TYPE_INSTANT, eFirst, OBJECT_SELF); // applique l’augmentation de la force avec un effet 3 secondes plus tard DelayCommand(3.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSecond, oTarget)); DelayCommand(3.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eStrength, oTarget, 300.0)); // se fixe la variable pour que le PC ne puisse pas l’utiliser une seconde fois SetLocalInt(oTarget, "Use_Pool_Once", TRUE); } // Si il a utilisé la fontaine else { eFirst = EffectVisualEffect(VFX_IMP_LIGHTNING_M);

Page 107: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

// permet un jet de sauvegarde pour éviter l’éclair int nDamage = GetReflexAdjustedDamage(d6(8), oTarget, 25, SAVING_THROW_TYPE_ELECTRICITY); eSecond = EffectDamage(nDamage, DAMAGE_TYPE_ELECTRICAL); // Puis appliquer l'effet visuel de l'éclair et les dégâts ApplyEffectToObject(DURATION_TYPE_INSTANT, eFirst, oTarget); ApplyEffectToObject(DURATION_TYPE_INSTANT, eSecond, oTarget); }}

Enlever des effets

La chose pour enlever des effets est qu’un effet a un "pointeur" unique qui a été établie quand il a été appliqué. Si vous définissez un nouvel effet de variable plus tard et que vous le définissez comme un effet du même type, RemoveEffect ne le ciblera pas.

La voie la plus facile pour enlever un effet est de parcourir les effets actifs qu’ils sont appliqués à la cible en utilisant GetFirstEffect et GetNextEffect... et ensuite de filtrer l’effet spécifique que vous recherchez. Une fois que vous l’avez trouvé (ou les avez trouvés si vous voulez en enlever plus d’un) le pointeur est fixé sur le bon effet et vous pouvez l’enlever.

Les commandes suivantes sont utile pour filtrer :GetEffectCreator = Si vous voulez spécifier seulement les effets qui ont été appliqués par une créture ou un objet spécifiqueGetEffectDurationType = Cela retournera la constant du type de durée d’un effet (soit "instant", "permanent",  "temporary"). Très générales, mais utile dans certaines circonstances.GetEffectSpellId = Cel retournera la constante du sort qui a appliqué l’effet (SPELL_*). Très utile si vous cherchez tous les effets d’un sort particulier ou si vous voulez les exclure.GetEffectSubType = Cela renverra la constante SUBTYPE_MAGICAL

SUBTYPE_SUPERNATURALSUBTPE_EXTRAORDINARY

Tous les effets par défaut d’un sous type sans les spécifier exactement.GetEffectType = C’est le filtre le plus utilisé quand vous cherchez un objet spécifique. Il renvoie une constante du type EFFECT_TYPE_*, qui est presque la même que la liste de commande des effets. Seul les effets visuels n’ont pas un type d’effet (effect type).

Le script basique pour enlever un effet ressemble à ceci:effect eEffect = GetFirstEffect(oTarget);while (GetIsValidEffect(eEffect)){ if (eEffect == filter used) { RemoveEffect(oTarget, eEffect); } eEffect = GetNextEffect(oTarget);}

Exemple pour enlever une malédiction (curse) lancée par une sorcière (avec le tag "EVIL_WITCH") à la fin d’un dialogue:void main(){ effect eEffect = GetFirstEffect(GetPCSpeaker()); while (GetIsEffectValid(eEffect)) { if ((GetEffectType(eEffect) == EFFECT_TYPE_CURSE) && (GetEffectCreator(eEffect) == GetObjectByTag("EVIL_WITCH"))) { RemoveEffect(GetPCSpeaker(), eEffect); } eEffect = GetNextEffect(GetPCSpeaker()); }}

Quelques choses à retenir EffectKnockdown cause un crasch quand il est appliqué par autrechose que par une créature (ce sera fixé

par le prochain patch) NdT ça devrais être fait. EffectHitPointChangeWhenDying ne marche pas (ce sera fixé par le prochain patch) NdT idem

Page 108: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Tous les effets ne sont pas permanent... Ils ne sont pas sauvé quand le personnage retourne au menu, mais il persiste tant qu’il est sur le module.

Le plus long type d’effet est l’effet extroardinaire, qui résiste à la dissipation de la magie et au repos. Les ExtraordinaryEffect et les SupernaturalEffect sont appliqué quand le commande suivante est dite:

effect eEffect = ExtraordinaryEffect (EffectSilence());

Utilisez les dialogue avec les objets placables et les déclencheurs

Il y a beaucoup d’effets qu’un MD intelligent peut simuler juste en utilisant un petit peu les dialogue en même temps que les objets placables et les déclencheurs.

Vous pouvez avoir une description ambiente d’une zone ou d’un objet, commencer un "dialogue" avec un objet étrange qui permet au joueur d’interagir avec lui, avoir quelqu’un de l’autre côté d’une porte qui parle à travers elle, informer les joueur des événements qui peuvent arriver…il y a beaucoup de possibilitées.

La première chose que vous devez savoir est quelles options vous avez. Ci dessous, vous avez des commandes qui peuvent être utilisées pour initier un dialogue ou afficher un texte :

ActionSpeakString et SpeakStringLa seule différence entre ces deux actions est que ActionSpeakString pousse la commande dans la file des actions (ça veut dire qu’elle ne sera pas effectuée avant que les actions placées au dessus dans la liste, comme ActionWait ou ActionMoveToObject, n’aient été effectuées) et que SpeakString est effectuée immédiatement.Qu’est ce que ca fait: une ligne de texte est affichée au dessus de celui qui a effectué cette commande. Cela est affiché pour le joueur comme un dialogue normal, le texte apparaît derrière le nom du personnage et son portrait (si c’est possible)

Advantages: Un volume peut être appliqué au texte en placant la constante TALKVOLUME_* appliquée dans la commande. TALKVOLUME_TALK est utilisé par défaut et est entendu par tous avec une portée normale. TALKVOLUME_SHOUT est entendu par tout le monde dans le module. TALKVOLUME_WHISPER est entendu par tout la monde dans une zone réduite. TALKVOLUME_SILENT_TALK et TALKVOLUME_SILENT_SHOUT sont des variante du "talk" et du "shout" normal... mais il sera affiché et entendu uniquement par les NPC.La particularité d’avoir un module est que le texte est aussi "entendu" par les objets du jeu. Les créatures sans portée auditive tourneront la tête, et si vous faite un script qui reconnais le texte via SetListenPattern et GetListenPatternNumber (comme les "cris" de combat), SpeakString peut être utilisé pour cela.

ActionStartConversationQu’est ce que ça fait : Ca demande à l’éxécuteur de la commande d’initier le dialogue avec la cible. Ca doit faire partie de l’événement OnDialogue de la cible (si elle en a un, et que le PC n’en pas). Si aucun fichier de dialogue resref est spécifié, celui attaché à la créature ou à l’objet sera utilisé (celui que vous avez spécifié dans le toolset). L’interlocuteur dans la conversation doit toujours être l’objet cible.

Advantages: Vous pouvez démarrer un conversation entière de cette manière, avec des choix de réponse et de multiples conditions de départ et de script. Vous pouvez aussi spécifier dans la commande principale si c’est ou non une conversation privée…Si c’est le cas, seule la cible verra le texte apparaître sur l’écran (c’est bien pour interagir avec les objets sans que les autres joueurs entendent cette conversation).

BeginConversationQu’est ce que ça fait: Cette commande est normallement seulement utilisée dans le "OnDialogue event" de la créature. C’est la commande qui lui demande de débuter la conversation avec le joueur qui vient juste de lui cliquer dessus. L’utiliser sur un objet ne lancera pas son "OnDialgue event". Si la cible de l’action n’est pas spécifiée, l’objet qui a initié le OnDialgue event sera utilisé.

Advantages: Peut être utilisé pour une conversation de NPC à NPC... autrement ActionStartConversation doit toujours être utilisé hors du OnDialogue event.

FloatingTextStringOnCreatureQu’est ce que ça fait: Quand vous accomplissez de nombreuses actions dans le jeu, vous avez remarqué le texte qui apparaît au dessus de la tête du joueur flotte puis disparaît. Cette commande faît la même chose.

Page 109: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Le texte est aussi montré dans la fenêtre du chat du joueur…Mais il n’est pas montré comme originaire d’une créature et ne montrera aucun portrait. Le texte est simplement marqué en jaune, comme la plupart des texts ambiants.

Advantages: C’est bien pour un texte d’ambiance ou simuler un message décrivant une action, puisqu’il n’ajoute pas un préfixe au début du texte et ne ressemble pas au texte des dialogues.

Une chose dont il faut être conscient: Un texte flottant, par défault, ne peut être vu que par la créature au dessus de laquelle il flotte. Si vous sélectionnez la commande "display to faction", alors les membres de la même faction verront aussi le texte s’afficher. Cela veut dire que le texte flottant est utile uniquement pour les PC, puisque aucune créature non PC ne peut être attribuée à la faction PC.

SpeakOneLinerConversationQu’est ce que je fais: Cela marche presque comme ActionStartConversation, mais son usage est plus spécifique. Il est utilisé pour accèder au fichier dialogue, mais seulement pour une ligne de dialogue unique sans réponses ni liens.

Advantages: Vous pouvez encore scripter les conditions de lancement du dialogue , vous pouvez avoir une longue sélection de ligne simple. Le locuteur ne se tourne vers aucune cible avant de parler…et l’objet identifié dans la commande (si il y en a un) devient la référence pour chaque marque utilisée dans le dialogue (seulement si elles ne sont pas présentes).

Faire dire un texte à un objet placable.

Pour l’exemple que je vais utiliser ici, nous allons faire qu’un objet placable "signpost" affiche un texte quand on clique dessus.

Important! Si vous voulez avoir un objet placable qui interagit avec les autres de cette manière, vérifiez que la case "Statique" est décochée !Si un objet placable est statique, il fera partit de l’arrière plan et ne sera pas sélectionnable. La plupart des objets sont marqués statique par défaut !

Donc sélectionnez un "signpost" (une pancarte) dans la liste des objets placables et placez le ou vous voulez. Ensuite allez dans ces propriétés et soyez sur que la case statique est décochée. Comme je veux que le joueur soit capable de cliquer dessus, la case "useable" (elle doit être cochée). Allez dans la section script et mettes le script suivant dans le OnUsed event :void main(){ SpeakString("North: Waterdeep, 20 miles");} Maintenant, quand vous êtes dans le jeu et que vous cliquez sur la pancarte, elle affichera le texte précédé de son portrait (qui est par défault une pancarte) et de son nom. Naturellement vous pouvez toujourzs changer le portrait comme vous voulez, ainsi que le nom, et l’affichage sera différent.

Faire apparaître un texte flottant à un déclencheur (trigger)

Dans cet exemple nous voulons que quand un joueur traverse la zone du déclencheur, un texte ambient apparaît au dessus de sa tête.

Allez dans le menu déclencheur (trigger menu) et sélectionnez "generic trigger". Ca vous permettra de dessiner les limites du trigger. Si je veux afficher une description de quelque chose que le joueur voit dans la zone, par exemple, je peux le mettre juste derrière la porte.

Allez dans la section script du trigger. Comme nous voulons que le texte apparaisse quand le joueur entre dans le déclencheur, nous mettrons le script dans la section OnEnter. Quelques choses à prendre en compte : est ce que nous voulons qu’il l’affiche seulement pour les PC ou pour toutes les créatures entrantes ? Est ce que nous voulons qu’il s’affiche à chaque fois que le PC entre, ou seulement une fois ? Cette fois, nous voulons que le texte apparaisse à tout le monde…mais une fois seulement.void main(){ object oPC = GetEnteringObject(); if (GetLocalInt(oPC, "Saw_Trigger_Text") == FALSE)

Page 110: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

{ FloatingTextStringOnCreature("La pièce est sombre et angoissante.", oPC); SetLocalInt(oPC, "Saw_Trigger_Text", TRUE); }}

Quand le joueur entre dans le trigger pendant le jeu, le texte apparaît au dessus de sa tête et flotte, puis disparaît. Cela l’affichera aussi dans la fenêtre de chat en jaune. Notez que le déclencheur ne peut pas utiliser SpeakString oou ActionSpeakString. Il ne peut tout simplement pas parler. Mais, il peut cependant demander à un autre objet de parler…et cet objet peut aussi être invisible ou non. Si j’ai à proximité un objet placable avec le tag "DISPLAY_HERE" (qui souvenez vous a la case "Static" décochée) et que je veux que le déclencheur le fasse afficher un texte, j’utiliserais le script suivant:

void main(){ object oPC = GetEnteringObject(); object oDisplay = GetObjectByTag("DISPLAY_HERE"); if (GetLocalInt(oPC, "Saw_Trigger_Text") == FALSE) { AssignCommand(oDisplay, SpeakString("La pièce est sombre et angoissante.")); SetLocalInt(oPC, "Saw_Trigger_Text", TRUE); }}

Avoir un objet qui affiche un texte quand un personnage vient à proximité.

Dans cet exemple, je vais poser un objet invisible (que le personnage de peut ni voir ni toucher) qui va afficher un texte quand le joueur approche à moins de 10 mêtres.

Premièrement, sélectionnez l’objet invisible dans le menu des objets placables et placez le. Allez dans ces propriétées et vérifiez que "Static" est décoché. Je ne veux pas que le joueur puisse cliquer dessus, donc laissez "Useable" décoché. Changez le nom de l’objet en "Unknow Person" et laissez le portrait blanc.Allez dans la section des scripts. Mettez le script suivant dans le OnHearbeat event:void main(){ object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC); if (GetIsObjectValid(oPC) && (GetDistanceToObject(oPC) < 10.0)) { SpeakString("Psst! Viens par ici!"); }}

Dans le jeu, quand le player viens à moins de 10 mètres de l’objet, le texte apparaîtra à l’écran…et dans la fenêtre de chat et le PC pourra lire "Unknown Person : Psst ! Viens par ici !". Je pourrais dévelloper un petit peu plus le script…par exemple, vérifier si le personnage s’approche à moins de 3 mètres la personne inconnu apparaîtra au dessus de l’objet placable.

Une chose que vous devez savoir est que l’objet placable est un petit peu petit… et l’affichage du texte est un peu bas sur le sol (ca dépend du zoom de la caméra). Il y a un truc pour l’afficher un peu plus haut : avant de placer cet objet invisible, sélectionnez un autre objet placable qui est aussi haut que vous le souhaitez…Placez le en premier. Puis sélectionnez l’objet invisible dans le menu, placez le curseur directement au dessus du premier objet avant de cliquer pour le poser. Il apparaîtra au sommet du premier objet. Maintenant, effacez le premier objet et l’objet invisible flottera au milieu de la pièce (et y restera).

Avoir un objet placable qui lance un dialogue.

Admettons que je veuille un objet aue le joueur puisse sélectionner et avoir un dialogue interactif…ou peut être avoir un objet qui parle. Premièrement, allez dans la liste des objets placable et sélectionnez un objet. Par exemple un piédestal et placez le dans le module. Allez dans ces propriétés et vérifiez que "Static" est décoché et "Usable" est cochée.

Allez dans l’onglet advance. Ecrivez dans un fichier dialogue ce que nous allons créer et appuyez sur Edit. Vous pouvez commencer par une ligne comme "Il y a quelque chose décrit sur le piédestal dans un language étrange. Est ce que vous essyez de le déchiffrer ?" Vous pouvez ensuite continuer à donner des réponses et

Page 111: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

faire un dialogue aussi long que vous le voulez, comme un dialogue normal. Allez dans l’onglet script et placez le script suivant dans OnUsed:void main(){ object oPC = GetLastUsedBy(); ActionStartConversation(oPC, "", TRUE);}

Dans le jeu, quand le joueur clique sur le piédestal, il s’approche de lui et le dialogue commence normalement. Puisque j’ai spécifié TRUE dans le paramêtre bPrivateConversation de la commande, lui seul verra la commande…un autre joueur étant a proximité ne verra et n’entendera rien. Si je ne me souciais pas du texte affiché, j’aurais pu simplement avoir écrit ActionStartConversation(oPC), puisque les " " signifient que le fichier dialogue attaché est utilisé.

Commencer une conversation avec une porte

Admettons que je veuille simuler ça : le joueur essaie d’ouvrir une porte mais la trouve fermée. Une voie parle de l’autre côté : "Quel est le mot de passe ?"

Premièrement, placez la porte normalement. Allez dans ses propriétées et changez le nom. Une chose pratique dans le nom de la porte : c’est qu’il n’est montré à aucun endroit (même si on l’examine) sauf dans le dialogue…donc changez le en "Le garde de l’autre côté", puisque c’est ce que le joueur verra.

Marquez la porte comme "plot" pour qu’elle ne puisse être cassée (mais vous pouvez aussi la laisser comme tels, et écrire un script avec les évènements OnDamaged ou OnPhysicalAttacked). Allez dans l’onglet lock et cochez la case "Locked". Si vous ne voulez pas qu’elle soit crochetable, cochez "Key required to lock or unlock" (encore une fois, vous pouvez faire comme vous voulez). Allez ensuite dans l’onglet advanced et mettez un nom dans conversation puis appyuez sur Edit. Nous pouvons créer la première ligne "Quel est le mot de passe ?" et continuez comme vous le souhaitez…quand vous avez fini et que vous avez crée une réponse ou le garde accepte d’ouvrir la porte, placez le script suivant dans la section "Action Taken" du nœud ou ce dernier accepte d’ouvrir.void main(){ ActionDoCommand(SetLocked(OBJECT_SELF, FALSE)); ActionOpenDoor(OBJECT_SELF);}

Maintenant, nous devons placer le script qui démarre la conversation. Placez le script suivant dans le OnFailToOpen event:void main(){ object oPC = GetClickingObject(); if (!IsInConversation(OBJECT_SELF)) { ActionStartConversation(oPC); }}

Dans le jeu, lorsque le joueur cliquera sur la porte et s’en approchera, il entendra le son habituel quand une porte refuse de s’ouvrir, et soudain le dialogue apparaît. Le joueur verra le portrait de la porte et "Le garde de l’autre côté" s’afficher au dessus avec le texte "quel est le mot de passe ?" affiché. Quand le moment arrive dans le dialogu ou le guarde doit ouvrir la porte, elle est déverouillée puis s’ouvre d’elle même…le joueur peut maintenant entrer.

Factions, cri et attaquer mes ennemisNdT : important différenciez bien "party" qui est un groupe de joueurs de "partie" qui a le sens habituel

Qu’est ce qu’est au juste une faction?

Page 112: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Une faction est une de ces trois choses : une party de PC & leur associés (mercenaires, familiers…), un joueur seul sans membre dans la partie & ses associés ou un groupe de NPC ou un NPC seul a qui ont été assignés des réactions par défault envers les autres factions. Cela ne doit pas être confondu avec une "organisation" comme une guilde de voleurs ou la garnison d’un ville. Les joueurs de peuvent pas "rejoindre" une factions , et chaque organisation peut contenir plusieurs factions.

Que font donc les factions ?

Juste ce qu’elles sont supposé faire : fixer le comportement par défaut d’un NPC face aux autres factions. L’IA générique donne une position comme amical (Friendly) ou hostile (Hostile) et le NPC réagit conformement au script. Un NPC maintiendra cette position par défaut jusqu’à et à moins qu’il lui soit demandé de faire autre chose.Ce qui est probablement le plus important à comprendre à propos des factions est qu’il y a cependant une différence entre ce que la faction "ressent" et ce que le NPC seul "ressent". Si un NPC individuel sans faction est attaqué, il deviendra hostile et se défencra tout seul. Il restera aussi hostile jusqu’à ce qu’on lui demande autrechose. Cependant, les autres membres de la faction non prészent ne seront pas nécessairement hostile comme lui. La différence de réaction est du à la "réputation", qui est différent de la réputation de quelqu’un avec la faction.

La commande NWscript se réfère, malheureusement, aux deux types de réputation de la même manière, donc faire la distinction entre les deux peut être difficile.

Pour mieux expliquer la différence, considerez ceci :Une party de PC sont dans une taverne. Le voleur de la party décide d’attaquer un roturier à proximité (qui est membre de la faction Commoner). Puisqu’il est attaqué, le roturier devient hostile envers le voleur…ce qui entrainera aussi une attaque de la part de tous les NPC à proximité qui sont amicaux avec cette faction et qui deviendront aussi hostile envers le voleur.Le reste de la party n’a encore rien fait donc personne n’est hostile envers elle. Si le reste de la party est engagée dans le combat, les NPC déjà hostile avec le voleur le seront avec toute la partie. Admettons maintenant que la party entière quitte la taverne tout de suite et échappe à ces poursuivants…ces individus resteront hostile avec le voleur (et les autres membres de la party ayant réagit) jusqu’à ce qu’on leur dise de réagir autrement. Les autres membres de la faction Commoner réagiront normallement.

La seule raison que ce ne soit pas le cas est si la case "Global Effect" est cochée (Elle peut être trouvé dans le Faction Editor). Les individus écartés (dans l’espace) dans une faction maintiendront des relations différentes…mais, si vous en attaqué un et qu’il devient hostile, tous les membres de la faction seront hostiles. Tous les changement dans les relations d’un membre seront appliqués à la faction entière. (Il y a certains moment où c’est pratique dans un module…mais soyez conscient que toute nouvelle faction à cette option activée).

Que fait l’IA standard avec les factions?

Pour mieux comprendre pourquoi quelque chose se passe ou ne se passe pas, voici un résumé détaillé de comment les factions affectent l’IA standart :

Dans l’événement OnPerception (qui se lance rappelez vous uniquement quand la cible entre dans la limite de perception, ou si le type de percepption change),si un NPC perçoit un hostile et qu’il n’est pas encore en combat le lançe le cri "NW_I_WAS_ATTACKED" (regardez ci dessous) et attaque.

Si la créature est attaquée mais pas encore en combat, elle lance les cris "NW_I_WAS_ATTACKED" et "NW_ATTACK_MY_TARGET" puis attaque son attaquant.

Si la créature est tuée ça lance automatiquement les cris "NW_ATTACK_MY_TARGET" et

"NW_I_AM_DEAD".

Et que font ces cris ?

Page 113: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

D’une part, il y a les mots simplements parlés qu’on avait demandé à la créature de dire, les même que ceux que peut taper le PC dans son système de Chat. Ces cris cependant sont silencieux…les joueurs ne les entendent ou ne les voient pas flotter, mais les PC oui, et le script OnSpawn leur demande de les écouter et de réagir. Les cris ne sont pas entendus à travers les murs ou les portes, et ils ont une portée limitée.

Le cri "NW_ATTACK_ MY_TARGET" a seulement un effet sur les NPC qui ont activé (enlevé les "//") de la ligne "SetSpawnInCondition (NW_FLAG_SHOUT_ ATTACK_MY_TARGET) ;" dans leur script OnSpawn. Si il a été entendu par un allié (un membre d’un faction amicale envers celui qui a poussé le cri), il fixe les relations de sa faction en hostile avec celui qui a attaqué le crieur (si ce n’était pas déjà le cas,) arrête ce qu’il fait et attaque tout ennemi à portée.

Le cri "NW_I_WAS_ATTACKED" peut être entendu par n’importe qui. Si celui qui l’entend est un allié du crieur et n’est ni en combat ni a moins de 10 niveaux de roturier, il attaquera le crieur.

Le cri "NW_I_AM_DEAD" peut aussi être entendu par n’importe qui. Son effet est le même que le cri "I was attacked" ci dessuss.

Comment puis-je faire attaquer mes NPC ?

Si est créature démarre hostile et détecte un PC, son événement OnPerception se lancera et elle attaquera immédiatement. Pas de porblème dans ce cas. Cependant, la situation devient souvent plus compliquée si vous avez un NPC qui était neutre face au PC quand l’événement OnPerception se lance et elle deviendra hostile lors du dialogue ou du script.

Pour qu’un NPC devienne hostile face à un PC et l’attaque, vous devez d’abord identifier la cible. Dans le dialoque c’est facile :object oTarget = GetPCSpeaker();

En dehors d’un dialogue, dans un script normal, ça peut varrier :// la cible est le PC le plus proche de celuui à qui appartient le script.object oTarget = GetNearestCreature (CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);// C’est le dernier objet perçu, doit être seulement utilisé dans le OnPerception.object oTarget = GetLastPerceived();

Ci dessous, vous avez deux possibilitées.Sans problèmes, une fois que vous avez identifié votre cible, vous pouvez appeler le reste de la commande normallement. Pour le script suivant, nous nous assurons que nous allons commencer le combat à la fin du dialogue (en plaçant ce script dans la section "Action Taken" de la ligne de dialogue ou nous voulons que le combat commence).

Premièrement, est ce que je veux que l’attaquant change la faction entière en hostile ? Si c’est le cas, j’utilise ça :#include "NW_I0_GENERIC"void main(){ // Baisse la relation de ma faction avec le PC de 100 (jusqu’à hostile) AdjustReputation (GetPCSpeaker(), OBJECT_SELF, -100); // Démarre le combat (Cela nécessite le fichier générique nw_i0_generic ci dessus) DetermineCombatRound();}

Et c’est tout (c’est aussi le script générique "nw_dl_attoned"). Maintenant, je veux juste que l’attaqué soit hostile (et lui seul) :#include "NW_I0_GENERIC"void main(){ // me fixe comme hostile face au PC // Notez que le "temporary" (temporaire) dure 3 minutes sans une valeur de durée précisée dans la // commande. SetIsTemporaryEnemy (GetPCSpeaker()); // démarre le combat (ça nécessite le fichier générique nw_iO_generic, ci dessus) DetermineCombatRound();}

Page 114: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Mais je supose qui j’ai d’autres amis à côté que je voudrais voir prendre part au combat. Si j’utilise AdjustReputation pour rendre leur faction hostile, il n’attaqueront toujours pas. Pourquoi ? Regardez dans le paragraphe à propos de l’IA générique…je n’ai pas attaqué le premier et je suis déjà en combat, c’est pourquoi je ne pousserais pas de cri. Nous avons tous déjà perçut le PC et il n’était pas hostile. Et je ne suis pas mort…donc mes amis resteront la jusqu’à ce qu’ils soient attaqué ou que je meurs. J’ai deux choix.

Soit leur envoyer la commande via AssignCommande comme ceci :#include "NW_I0_GENERIC"void main(){ // Ce script marche bien si vous savez exactement qui enroler dans le combat // et qu’ils ont des resrefs uniques object oGoblin2 = GetObjectByTag ("GOBLIN2"); object oGoblin3 = GetObjectByTag ("GOBLIN3"); // Baisse ma valeur de réaction avec le PC de 100 (jusqu’à hostile) AdjustReputation (GetPCSpeaker(), OBJECT_SELF, -100); // demande à mes amis de débuter le combat AssignCommand (oGoblin2, DetermineCombatRound()); AssignCommand (oGoblin3, DetermineCombatRound()); // démarre le combat (ça nécessite le fichier générique nw_iO_generic, ci dessus) DetermineCombatRound();}

Ou comme cela :#include "NW_I0_GENERIC"void main(){ // Ce script fait que tous les allié dans la zone actuelle attaquent location oHere = GetLocation (OBJECT_SELF); // Baisse ma valeur de réaction avec le PC de 100 (jusqu’à hostile) AdjustReputation (GetPCSpeaker(), OBJECT_SELF, -100); // maintenant, cicle tous les objets dans la zone object oFriend = GetFirstObjectInArea (GetArea(OBJECT_SELF)); while (GetIsObjectValid(oFriend)) { // Si c’est objet fait parti de ma faction et que c’est une créature if (GetFactionEqual(oFriend) && (GetObjectType(oFriend) == OBJECT_TYPE_CREATURE)) { // et qu’ils peuvent voi le PC if (GetObjectSeen (GetPCSpeaker(), oFriend)) { // leur demande de commancer le combat AssignCommand (oFriend, DetermineCombatRound()); } // si il ne peut pas le voir else { // lui demande d’arrêter ce qu’il fait AssignCommand (oFriend, ClearAllActions()); // and come to my location AssignCommand (oFriend, ActionMoveToLocation(oHere, TRUE)); } } oFriend = GetNextObjectInArea (GetArea(OBJECT_SELF)); } // maintenant, je démarre le combat moi même DetermineCombatRound();}

Il y a aussi des variation à faire…ce ne sont que des exemples. Une autre manière de faire commencer un combat à un groupe est de vérifier que tous ont la ligne "SetSpawnInCondition (NW_FLAG_SHOUT_ ATTACK_MY_TARGET);" activée dans leur script OnSpawn. Puis, quand vous commencez à attaquer, vous pouvez juste fare cela:#include "NW_I0_GENERIC"void main(){ // Baisse ma valeur de réaction avec le PC de 100 (jusqu’à hostile) AdjustReputation (GetPCSpeaker(), OBJECT_SELF, -100); // démarre le combat (ça nécessite le fichier générique nw_iO_generic, ci dessus) DetermineCombatRound(); // et cri à tous mes alliés dans le voisinage de se joindre à moi SpeakString ("NW_ATTACK_MY_TARGET", TALKVOLUME_SILENT_TALK);}

Page 115: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Vous ne verrez pas la phrase, mais tous les alliés avec une portée auditive qui peuvent voir la cible coureront à l’attaque.

Comment je fais revenir mes NPC à une attitude neutre?

Si vous voulez rendre un NPC non hostile une fois qu’il est en combat avec les PC (si le PC est mort ou pour d’autres raisons), vous devez être sur que deux choses se sont passées : un, que la faction ait une attitude non hostile face au joueur (soit neutre soit amicale). Deux, si la faction n’a pas "Global Effect" cochée, vous devez changer aussi tous les sentiments personnels des NPC face au PC.

Les factions "standard" dans le jeu (Commoner, Defender, etc) sont les seules pour lequels vous pouvez faire les deux dans une seule commande. Cela est fait à travers la commande SetStandardFaction, et un exemple de celle ci est dans le script par défault de mort ("nw_o0_death"), qui rement toutes les factions standarts à la neutralité à la mort du joueur.

Note: de nombreuses personnes ont rapportées que la faction defender n’est pas remise à "zéro" avec cette commande, mais vous pouvez le faire en la traitant comme une faction personnalisée. Cf. ci dessous

Pour les factions personnalisées (Custom factions), vous aveez besoin de deux commandes : AdjustReputation pour changer les relation de la faction avec la cible et ClearPersonnalReputation pour changer tous les sentiments du NPC. Dans les deux cas, vous devez isoler la cible qui esi un membre d’un faction (ce qui peut être difficile si vous avez beaucoup de membres avec des tags différents ou qui peuvent être mort)…les factions personnalisées ne sont pas identifiées par un nom, vous pouvez seulement dire "la faction a qui appartient un tel et un tel". et si vous voulez effacer les réputations personnelles du PC avec une faction personnalisée entière, vous devez créer un cycle.

Voici un exemple de script qui ajustera la faction à neutre et fera un cycle à l’intérieur de celle ci pour restaurer pour tous les membres une réaction normale avec le PC. Cette faction n’a pas "Global Effect" cochée, et a des membres avec le même tag "GOBLIN01". Le PC est mort et ce script est dans son OnDeath event:

// Je crée ici une commande "ClearAll FactionMembers’" personnalisée// premièrement déclarer les paramêtres de la nouvelle commande, puis ce qu’elle sera// j’aurais pu raisonnablement les membres dans un autre script et utiliser// #include pour le mettre dans ce script (ou dans un autre)void ClearAllFactionMembers (object oMember, object oPlayer){ object oClear = GetFirstFactionMember (oMember, FALSE); while (GetIsObjectValid(oClear) == TRUE) { ClearPersonalReputation (oPlayer, oClear); oClear = GetNextFactionMember (oMember, FALSE); }}

// Voici le corp principal de mon scriptvoid main(){ // identifie le joueur object oPlayer = GetLastPlayerDied(); // identifie une membre de la faction, je m’assure que ces membres sont vivants. // Ceêndant, je pourrais essyer plusieurs choses pour modifier un membre qui est // valid puis d’utiliser la commande if object oGoblin = GetObjectByTag("GOBLIN1"); if (GetIsObjectValid(oGoblin)) { // augmente la relation de la faction de 100 AdjustReputation (oPlayer, oGoblin, 100); // utilise ma commande personnalisée dans la faction ClearAllFactionMembers (oGoblin, oPlayer); }}

Page 116: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Ce qu’il y a de bien avec les cris

Quelques trucs à essayer ou à utiliser en rapport avec les cris.

Le premier: J’ai toujours détesté le fait que un NPC qui entend le cri "NW_ATTACK_ MY_TARGET" mais ne voit pas le crieur ne fait rien. Il devient hostile mais n’attaque pas tant que l’ennemi ne vient pas dans sa ligne de vue. Il yt a un moyen que j’ai utilisé pour qu’il vienne vers l’ondroit d’où provient le cri.Etape 1 – La première chose qui doit être faite est qu tous les membres de la factions qui repondront au cri doivent avoir leur script OnSpawn paramêtré de la même manière. Allez dans leur script OnSpawn et activez les lignes suivantes (enlevez les "//"):SetSpawnInCondition (NW_FLAG_SHOUT_ ATTACK_MY_TARGET);SetSpawnInCondition (NW_FLAG_ ON_DIALOGUE_EVENT);Puis re sauvez le script sous un nom différent.

Etape 2 – Souvenez vous qu’une créature qu’une créature ne criera "attack myt target" uniquement si elle est attaquée en première ou si elle est tuée. Si vous voulez qu’elle crie, elle même, vous devez mettre ceci dans un script. Il y en a un fournit dans l’exemple ci dessous dans lequel la créature devient hostile et pousse le cri à la fin du dialogue.

Etape 3 – Mettez le script suivant dans le OnUserDefined event de chaque créature:// Ce script fait que le récepteur d’un cri"NW_ATTACK_MY_TARGET" vienne// et regarde si il ne voit pas un ennemi. Une fois qu’il s’est approché du crieur,// si il voit un ennemi, son script OnPerception sera activé et il attaquera.// Une modification interessante de ce script serait d’avoir que les récepteur du cri // situé hors de vue pousse un deuxième cri qui porte plus loin que le cri original…// cela nécessiterait cependant un nouveau cri et une nouvelle définition du // comportementvoid main(){ int nEvent = GetUserDefinedEventNumber(); if (nEvent == 1004) // OnDialog event { // Cela regarde si le cri correspont au comportement fixé par le // 'SetListeningPatterns' dans OnSpawn int nMatch = GetListenPatternNumber(); object oShouter = GetLastSpeaker(); object oIntruder; // si je reconnais ce cri et que le crieur est valide et amical avec le NPC if(nMatch != -1 && GetIsObjectValid (oShouter) && !GetIsPC(oShouter) && GetIsFriend (oShouter)) { // et que le cri est "NW_ATTACK_MY_TARGET" if (nMatch == 5) { // essaie de trouver l’ennemi oIntruder = GetLastHostileActor (oShouter); if(!GetIsObjectValid (oIntruder)) { oIntruder = GetAttemptedAttackTarget(); if(!GetIsObjectValid (oIntruder)) { oIntruder = GetAttemptedSpellTarget(); if(!GetIsObjectValid (oIntruder)) { oIntruder = OBJECT_INVALID; } } } // si je ne peux trouver ni le crieur ni son ennemi if (GetIsObjectValid (oShouter) && !GetObjectSeen (oIntruder) && !GetObjectSeen (oShouter)) { // défini l’emeplacement du crieur location lShouter = GetLocation(oShouter); // arrête ce que je suis en train de faire ClearAllActions(); // et bouge jusqu’à cette emplacement ActionMoveToLocation (lShouter, TRUE); } // ou si je peux voir le crieur mais pas l’ennemi else if (GetIsObjectValid (oShouter) && !GetObjectSeen (oIntruder) && GetObjectSeen (oShouter))

Page 117: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

{ // arrête ce que je fais ClearAllActions(); // et bouge plus près du crieur ActionMoveToObject (oShouter, TRUE); } } } }}

La seconde: Voici un exercice iteressant qui démontre comment faire votre propre cri. Dans cet exemple, je veux avoir un dialogue qui lance un cri et entraine que tous ceux qui l’entendent joue l’animation "worship" (ils pensent que le PC est un devin.)

Etape 1 – Nous allons faire le dialogue à la fin duquel le NPC poussera le cri. Faisons le très simple…une ligne seulement "C’e’st un devin !" et puis le script suivant est attaché à la zone "Action Taken" de cette ligne:void main(){ // entre une variable sur moi même éguale au PC qui est en train de me parler SetLocalObject (OBJECT_SELF, "worship", GetPCSpeaker()); // lance le cri "BOWDOWN" SpeakString ("BOWDOWN", TALKVOLUME_SILENT_TALK); // faite l’animation worship pendant 30 secondes ActionPlayAnimation (ANIMATION_LOOPING_WORSHIP, 0.5, 30.0);}

Etape 2 – Maintenant, nous devons paramétrer les autre NPC pour qu’ils entendent le cri. Pour cela, nous devons activer la ligne "SetSpawnInCondition (NW_FLAG_ ON_DIALOGUE_EVENT);" dans leur scriptOnSpawn et ajouter la ligne suivant n’importe où :SetListenPattern (OBJECT_SELF, "BOWDOWN", 100);Cela rend la chaine de caractère "BOWDOWN" égale à 100 (pris au hasard) et reconnaissable par les NPC qui doivent l’entendre (en utilisant la commande SetListening (OBJECT_SELF, TRUE)... qui est lancée par la commande du OnSpawn SetListeningPatterns).

Etape 3 – Maintenat, nous devons juste demander au NPC que faire quand ils entendent cette commande. Toute chaine de caractères dite fait partie de leur OnDialogue event... donc le script suivant peut être placé dans le OnUserDefined event:

void main(){ int nEvent = GetUserDefinedEventNumber(); // si je recois OnDialogue event if (nEvent == 1004) { // regarde ce que j’ai entendu int nMatch = GetListenPatternNumber(); // identifie le locuteur object oShouter = GetLastSpeaker(); // et attrappe la variable du NPC qui s’incline object oWorship = GetLocalObject(oShouter, "worship"); // Si la chaine de caractèreest une que je reconnais et que l’émetteur est un NPC valid et amical if(nMatch != -1 && GetIsObjectValid (oShouter) && !GetIsPC (oShouter) && GetIsFriend (oShouter)) { // et que la chaine de caractère "BOWDOWN" est égale à 100 if(nMatch == 100) { // se tourner face au PC avec lequel le NPC parle ActionDoCommand (SetFacingPoint (GetPosition(oWorship))); // puis joue l’animation worship pendant 30 secondes ActionPlayAnimation (ANIMATION_LOOPING_WORSHIP, 0.5, 30.0); } } }}

Ce n’est évidemmement pas tout ce qu’il faut savoir à propos des factions et des cris, mais ça devrais, je l’espère être utile à un grand nombre de personnes.

Page 118: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Creer et Importer des Portraits Personnalises

de Robin Mayne et Derek French traduit par Kemay

Neverwinter Nights offrent de nombreuses façons de personnaliser son personnage. Ajouter votre propre portrait personnalisé est l'une des façons d'amener la personnalisation de votre personnage à un niveau supérieur.

Ce document décrira de façon simple les quelques étapes nécessaires pour:

1. Créer un portrait personnalisé2. Importer un portrait personnalisé dans le jeu3. Comprendre comment fonctionnent les portraits personnalisés en multi-joueurs.

Creer un portrait personnaliseEtape 1. Avec l'éditeur d'images qui supporte le format Targa (.tga) de votre choix, créez une nouvelle image vide d'une dimension de 256 x 512 pixels. Exemples de logiciel: Photoshop, Paint Shop Pro, et Irfanview.

Seule la partie supérieure de votre image est présentée dans le jeu, ainsi la taille réelle de votre portrait est de 256 x 400 pixels. La partie inférieure de votre image est vide et inutilisée.Zones de l'image:canevas est l'image en entierportrait est la zone utilisée par le jeuvide est la zone inutilisée (mais nécessaire)

Vous pouvez, de plus, télécharger le portrait d'exemple, montré sur la gauche, que j'ai créé (Ce portrait est censé être humoristique et devrait vous donner envie de faire mieux!). Vous aurez besoin de WinZip pour décompresser ce portrait. Si vous regardez mon portrait d'exemple dans votre éditeur d'images, vous verrez qu'il a cette zone vide décrite ci-dessus.

Etape 2. Créez votre portrait personnalisé, quelqu'il soit, dans la zone 'portrait'. Souvenez vous que, même si la taille totale du canevas est de 256 x 512 pixels, seule la partie supérieure de 256 x 400 pixels, comme le montre le schéma ci-dessus, doit être utilisée pour le portrait lui-même.

Etape 3. Maintenant, vous devez créer cinq versions du portrait que le jeu va utiliser. Vous avez déjà créé la version la plus grande, donc vous pouvez simplement la redimensionner pour faire chacune des quatre autres versions plus petites

Les dimensions des cinq versions nécessaires sont:256x400 (sur un canevas de 256x512) – utilisé pour la Biographie du Personnage Joueur (Player Character Bio)128x200 (sur un canevas de 128x256) – utilisé pour la feuille de personnage (character sheet)64x100 (sur un canevas de 64x128) – utilisé pour le portrait en jeu32x50 (sur un canevas de 32x64) – utilisé pour les membres du groupe et le menu contextuel16x25(sur un canevas de 16x32) – utilisé pour la petite image dans la fenêtre de dialogue

Etape 4. Vous devez enregistrer les images en tant que fichiers Targa (.tga) (en sélectionnant les options '24 bits' et 'non compressé' (uncompressed) de votre logiciel). Les noms des cinq fonctions doivent être de la forme suivante:

xxxxxxxxxxxxxxxh.tga (pour le canevas de 256x512)xxxxxxxxxxxxxxxl.tga (pour le canevas de 128x256)xxxxxxxxxxxxxxxm.tga (pour le canevas de 64x128)

Page 119: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

xxxxxxxxxxxxxxxs.tga (pour le canevas de 32x64)xxxxxxxxxxxxxxxt.tga (pour le canevas de 16x32)

Où le préfixe "xxxxxxxxxxxxxxx" est un nom que vous créez de 1 à 15 caractères de longueur. Il doit être le même pour les cinq versions.

Les 'h','l', 'm' ,'s' et 't' qui suivent le préfixe indique la taille de l'image (Immense (Huge), Grand (Large), Moyen (Medium), Petit (Small) et Minuscule (Tiny)).

Ainsi dans mon portrait d'exemple, j'ai créé ces cinq images:

robinsample_h.tgarobinsample_l.tgarobinsample_m.tgarobinsample_s.tgarobinsample_t.tga

Comme vous pouvez le constater, mes ont toutes le même préfixe "robinsample_" (comme cela fait un total de 12 caractères, cela respecte la règle d'être compris entre 1 et 15 caractères); et j'ai, de plus, chacune des cinq versions - 'h', 'l', 'm' ,'s' et 't'.

Une fois que vous avez, soit créer votre portrait, soit téléchargé un, vous pouvez les utilisez en jeu.

Importer un portrait personnaliseEtape 1. Importer votre portrait personnalisé est facile à faire. Copiez simplement les cinq versions du portrait dans le répertoire 'portraits' où vous avez installé Neverwinter Nights.

Etape2. Vous pouvez maintenant sélectionner votre portrait lorsque vous créez un nouveau personnage. Notez que votre portrait sera disponible pour les personnage de sexe masculin ET féminin, à la différence des portraits originaux qui sont spécifique au genre.

Ci dessus vous pouvez voir mon portrait personnalisé en jeuUtiliser des Portraits Personnalises en Multi-joueurs

Lorsque vous jouez en multi-joueurs et que vous utilisez un portrait personnalisé, le portrait que les autres voient pour votre personnage varie selon qu'ils aient ou non le même portrait personnalisé dans leur répertoire 'portraits'. (Le jeu recherchera des portraits avec le même nom de fichier.)

S'ils ont ce portrait dans leur répertoire 'portraits', ils verront votre portrait personnalisé. Sinon, ils verront le portrait par défaut du jeu. (Neverwinter Nights a deux portraits par défaut – un pour les personnages masculins et un pour les personnages féminins.)

Donc, si vous voulez que vos amis voient votre personnage avec votre portrait personnalisé, envoyez leur simplement les cinq versions par e-mail, et demandez leur de les copier dans leur répertoire 'portraits'.

Page 120: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Personnaliser l'apparence du NWUpdaterde Robin Mayne et Todd Grenier

traduit par Kemay

Le programme NWUpdater est le programme que Neverwinter Nights utilise pour installer les mises à jour et les patchs. (Vous pouvez trouver plus de détails en anglais sur la mise à jour ici, et vous devriez lancer la mise à jour maintenant si vous ne l'avez pas fait récemment.) Vous avez de plus la possibilité de changer l'apparence qu'il utilise.

Ce tutorial vous expliquera comment:

Choisir une nouvelle apparence

Installer une nouvelle apparence

Créer une nouvelle apparence

Choisir une apparence1. Lancez le programme NWUpdater (en sélectionnant 'Update' dans le premier menu du jeu Neverwinter Nights).

2. Faites un clique droit dans la partie supérieure du programme NWUpdater – Vous pouvez au choix:

Sélectionner 'Skins' dans le menu, où vous trouverez toutes les apparences que vous pouvez choisir. Sélectionnez celle que vous souhaitez utiliser.

OU

Sélectionner 'Random Skin' (Apparence Aléatoire). A chaque fois que vous lancerez e programme NWUpdate, une apparence sera choisie au hasard.

Page 121: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Installer une apparenceCes instructions vous permettront d'installer l'apparence 'Updater Skin 3', de Todd Grenier de Bioware. Vous pouvez aussi télécharger des apparences depuis d'autres sites, comme NWVault (ils ont une chouette apparence de pingouin!).

1. Téléchargez la Updater Skin 3 (.zip, 395 KB) et sauvegardez la à un emplacement où vous pourrez la retrouver.

2. "Dézippez" le fichier que vous avez téléchargé (en utilisant un outil comme Winzip), et placez le fichier .bmp dans le répertoire 'utils \nwupdateskins' qui se trouve là ou vous avez installé Neverwinter Nights (l'emplacement par défaut est 'C:\ NeverwinterNights \NWN \utils \nwupdateskins').

3. L'apparence est maintenant installée! Pour la sélectionner, suivez les instructions de la section précédente.

Creer une nouvelle apparenceLes étapes suivantes vous montreront comment créer votre propre apparence à partir du 'skin template' (la sorte de patron montré sur la droite)

1. Téléchargez le Updater Skin Template (.zip, 22 KB), et sauvegardez le à un emplacement que vous pourrez retrouver.

2. Avec l'éditeur d'image de votre choix qui supporte le format Bitmap (.bmp), ouvrez et éditez le fichier contenu dans le zip. Quelques exemples de logiciels : Photoshop, Paint Shop Pro, et Irfanview.

3. Vous pouvez maintenant modifiez son aspect visuel à votre guise, mais laissez la "case" centrale telle quelle. Une fois que vous avez fini, sauvegardez votre image au format .bmp 24-bit. Pour installer votre nouvelle apparence, placez le fichier .bmp dans votre répertoire 'utils \nwupdateskins' qui se trouve là ou vous avez installé Neverwinter Nights (l'emplacement par défaut est 'C:\ NeverwinterNights \NWN \utils \nwupdateskins').

Assurez vous de partager vos apparences personnalisées du NWUpdater avec la communauté!

"Re-texturer" les Creaturesde Robin Mayne

Traduit par Jawrill

Ce tutorial va vous apprendre à prendre les textures des créatures de Neverwinter Nights, les modifier, et les utiliser pour créer des créatures modifiées.

IntroductionLes créatures du jeu utilisent des images de texture, images qui sont collées sur la forme de squelette pour donner la peau de la créature. En modifiant ces images avec un utilitaire, vous pouvez changer l’apparence visuelle des créatures. C’est une bonne façon pour créer de nouvelles créatures dans vos aventures.

Page 122: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Texture Originale Troll Original Texture Modifiée Troll Modifiée

Etape pour Re-Skinner une CreatureNous allons suivre ce procédé:

Charger la texture depuis le jeu. Modifiez la graphiquement avec un programme style Photoshop Convertissez le dans un format de compression reconnu par le jeu Ajoutez le dans un Hak Pak pour l’utiliser dans votre module

Charger la TextureLa première chose dont vous avez besoin est la texture originale de la créature du jeu. BioWare va débloquer des textures de créature, disponibles sur le site, vous pouvez télécharger les textures ici. La première contient les Troll, Umberhulk, Bat (Chauve souris), Badger (Blaireau), et Panther (Panthère).

Il existe aussi des outils développés par les communauté de joueurs, mais ce travail et plus fastidieux. Modifier la TextureEn utilisant un éditeur graphique de votre choix qui supportent le format Targa (.tga), ouvrez et éditez la texture. Comme exemple de logiciel, voici Photoshop, Paint Shop Pro, and Irfanview.Vous pouvez modifier la texture de plusieurs manières. Peindre dessus des modèles de tatouages, ou modifier les équilibres de couleur, vous n’êtes limité que par votre imagination!

->Nuancer

ouModifier la Balance des Couleurs

->

Texture Originale   Texture Modifiée

Dès que vous avez fini vos modifications, sauver l’image en fichier Targa (.tga), (sélectionnez '24 bits/pixel' et l’option 'uncompressed' de votre software).

Le nom du fichier de textures est important, comme vous ne pouvez les utiliser dans l’Editeur que s’ils emploient le nom exact des textures dans le jeu. Dans la texture 'c_troll' que vous téléchargez doit maintenir le nom de fichier 'c_troll' pour être reconnu par le jeu comme une texture de Troll.

Convertir la TextureAfin d’employer les textures dans votre module, vous devez convertir l’image en format de compression reconnu par le jeu. BioWare a créé un outil de compression interne pour processus, sans le support de windows

Instructions pour utiliser l’outil de compression DDS

1. Vous devez être inscrit pour télécharger ce fichier.Si vous n’avez pas de compte, inscrivez vous maintenant! C’est libre et vous permet en plus un grand accès a tout les sites BioWare.

Page 123: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

2. Après avoir dézipper l’outil, vous trouverez 2 fichier dans le dossier 'dds' (processtextures.exe et runme.bat) ainsi que 2 autres dossier appelé 'in' et 'out'.

3. Placez le .tga que vous voulez compresser dans le dossier 'in' .4. Double-cliquez sur 'runme.bat' dans le dossier 'dds' . Cela va convertir la texture du .tga format en format compressé .dds requis par le jeu. Vous trouverez la texture convertie dans le dossier 'out'. Elle aura le même nom de fichier que l’original, mais avec l’extension .dds. La texture 'c_troll.tga' s’appelle maintenant 'c_troll.dds'.

Notes sur l’outil de compression DDS: Le DDS est un freeware, sans support de Windows qui ne marchera pas avec toutes les cartes vidéo. Cela dépend de votre carte et si les pilotes supportent la compression. La plupart des DirectX 8 devrait marcher – Je l’ai tester sur une GeForce3 et un Radeon 8500, qui marchent bien, par contre la Matrox G550 que j’ai testée n’a pas marché. Si vous ne pouvez pas exécutez le DDS, je vous suggère de trouvez un ami qui pourra les convertir pour vous, vu que ce n’est qu’une petite étape pour créer vos propres textures!

Creating a Hak PakUne fois que vos textures sont prêtes, vous devrez les ajoutez a un Hak Pak, qui peut alors être employé avec votre module, et distribué à d’autres qui pourront apprécier vos créations.

1. Le Hak Pak Edirtor est le programme 'nwhak.exe' dans le répertoire 'utils' situé dans le répertoire ou vous avez installez NWN (l’emplacement par default est C: \NeverwinterNights \NWN \utils). Double-cliquez sur 'nwhak.exe' pour lancer l’éditeur.

2. Ajoutez la texture .dds texture a l’éditeur Hak Pak en sélectionnant 'Resource' -> 'Add'. Sélectionnez l’emplacement du fichier .dds. Sélectionnez et cliquez sur 'Open'.

3. Vous verrez maintenant le fichier de texture listé comme ressource dans le Hak Pak. Ajoutez un titre et une description a votre Hak Pak, et sauvez le dans votre dossier 'hak' où vous avez installé Neverwinter Nights (l’emplacement par defaut est C: \NeverwinterNights \NWN \hak).

Page 124: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Utiliser un Hak Pak1. Maintenant que votre Hak Pak est dans votre répertoire 'hak' , nous pouvons l’ajouter au module. Ouvrez un module existant ou nouveau dans le Toolset. Dans le menu 'Edit' sélectionnez 'module properties', ensuite l’onglet 'Advanced' . Dans 'HAK File' glissez / déposez votre hak pak.

Note: C’est de cette manière que les Hak Paks sont ajoutés au module. Rappelez vous que si vous employez un Hak Pak dans votre module, les Joueurs doivent avoir le même Hak Pak dans leur répertoire 'hak' pour jouer, donc soyez sûr d’empaqueter le Hak Pak avec votre module quand vous le mettez a télécharger!

2. Maintenant que le Hak Pak avec la nouvelle texture a été ajouté, les créatures qui l’utilisent vont avoir la nouvelle apparence. Dans mon exemple, tous les Trolls de mon module seront mauves. Et maintenant?Si vous aviez juste besoin de "re-skinner" une créature existante du jeu pour lui donner une nouvelle apparence, alors c’est tout ce que vous avez à faire! Cependant, vous pouvez aussi utiliser le Toolset pour créer de nouvelles créatures avec des habilités perso, et le combiner avec la nouvelle texture pour créer une créature réellement unique. Ce procédé est décrit dans le Creating Your Own Creatures tutorial. (en cours de traduction)

Creer ses porpres creaturesde Rob Bartel and Robin Mayne

traduit par Kemay

L'un des aspects importants dans la création de vos propres aventures pour un jeu de rôle est la création de créatures personnalisées que vos joueurs pourront rencontrer.

Ce tutorial décrira comment, grâce au Toolset, vous pouvez créer une créature avec ses propres caractéristiques et capacités que vous pourrez ajouter à votre module, à partir d'une idée de cette créature (inspirée par exemple s'un livre ou d'un film).

Panthere de MalarNous nous inspirerons de la Bête de Malar – qui est une créature spécifique au Royaumes Oubliés, détaillée dans les pages 20-21 du livre Monsters of Faerun, publié par Wizards of the Coast.

Bien que nous ne créerons pas la véritable Bête de Malar (qui est une créature pouvant prendre 3 formes différentes – panthère, chauve-souris et "claw slayer"), nous allons créer une nouvelle créature féline, basée sur la forme de panthère de la Bête de Malar – nous appellerons notre créature une Panthère de Malar.

Utilisateurs avancés: Vous noterez que le Jeu de Textures 1 (Texture Bundle 1 dans la section Textures Downloads) contient les textures de la chauve-souris et du blaireau, au cas où quelqu'un voudrait créer les deux formes de la Bête de Malar restantes.

En suivant les étapes du tutorial "Re-Skinner" une créature, nous créons la texture de la Panthère de Malar. Selon la description, elle a des marques rouges, comme des motifs peint avec du sang.

Page 125: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

->

Peindre la tête en rouge

->

Texture Originale Texture Modifiée

Vous pouvez créer votre propre texture pour la Panthère de Malar, en suivant le tutorial "Re-Skinner" une créature, ou télécharger celle que nous avons créée.

Télécharger le hak pak contenant la Texture de la Panthère de Malar Panther (.hak, 172 KB). Enregistrez la dans le répertoire 'hak' où vous avez installé Neverwinter Nights (son emplacement par défaut est: C:\NeverwinterNights\NWN\hak)

Note: Pour pouvoir jouer à un module utilisant ce Hak Pak, les joueurs aussi devront le télécharger et le placer dans leur répertoire 'hak'.

Maintenant que le Hak Pak est dans votre répertoire 'hak', nous pouvons l'ajouter au module. Ouvre un module existant ou créez en un nouveau avec le Toolset. Dans le meu 'Edit', sélectionnez 'Module Properties' (propriétés du module). Dans le l'onglet 'Advanced', sélectionnez votre hak pak dans le menu déroulant 'HAK File'.

Faire un Blueprint pour la Panthère de MalarNote: Vous pouvez télécharger notre Panthère de Malar finie à la fin du tutorial.

1. Cliquez sur le bouton 'Paint Creatures' dans la barre de menu de droite, et sélectionnez l'onglet 'standard'.

2. Dans l'arborescence, faites un clique droit sur 'Monsters / Animals / Feline / Panther' et sélectionnez 'Edit Copy'.

3. Lorsque le Creature Editor s'ouvre, vous verrez que la panthère aura la nouvelle texture de la Panthère de Malar. Entrez son nouveau nom "Panthère de Malar", dans le champ 'First Name'. Vous pouvez changer le Tag aussi si bous le souhaitez. Appuyez sur le bouton '...' à droite du champ 'Description' et tapez un texte descriptif.

4. Appuyez sur le bouton 'OK' lorsque vous avez fini votre description.

Page 126: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

5. Dans l'onglet 'Classes', changez son 'Alignment' en 'Chaotic Evil' (Chaotique Mauvais). Changez la Classe 'Animal' en 'Shapechanger' (Changeur de forme) et donnez lui 9 niveaux dans cette dernière.

6. Dans l'onglet 'Statistics', donnez lui les caractéristiques suivante dans la partie 'Abilities Score' Str (Force) 15, Dex (Dextérité) 22, Con (Constitution) 20, Int (Intelligence) 10, Wis (Sagesse) 15, Cha (Charisme) 17.Donnez lui +5 dans 'Natural AC' (Classe d'armure naturelle), ce qui aura pour résultat une 'Total Armor Class' (Classe d'Armure Totale) de 21. Donnez lui une 'Base Hit Points' (Base de Points de Vie) de 40, ce qui résultera en 'Total Hit Points' (Points de Vie Totaux) de 85. Mettez son 'Mouvement Rate' (Vitesse de déplacement) à 'Very Fast' (Très Rapide).

7. Dans l'onglet 'Skills' (Compétences), Donnez lui les nieaux de compétence suivants: Hide (se cacher) +17, Listen (écouter) +11, Move Silently (déplacement silencieux) +17, Spot (remarquer) +11.

8. Dans l'onglet 'Feats' (Dons), Vérifiez qu'elle possède bien les dons suivants: Alertness, Knockdown, Nature Sense, Opportunist, Weapon Finesse, Weapon Proficiency (Creature).

9. Cliquez sur le bouton 'Inventory' (Inventaire) en dessous de la fenêtre montrant le modèle 3D. Sélectionnez l'onglet 'Natural Equipment'.

10. Supprimez les items situés dans les emplacements 'Claw1' (Griffe1), 'Claw2'(Griffe2) et 'Special Attack' (Attaque Spéciale) en les glissant vers l'icône en forme de poubelle dans le coin en bas à gauche.

11. Dans la section 'Inventory's Standard Items', faites un clique doit sur l'item 'Creature / Claw / Claw1d4 et sélectionnez 'Edit Copy'.

Page 127: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

12. Dans l'Item Editor, Modifiez l' 'Item Name' en 'Griffe1d4+2'. Vous pouvez changez le Tag et le nom du bleuprint aussi si vous le souhaitez.

13. Dans l'onglet 'Properties', sélectionnez 'Damage Bonus / Slashing' dans l'arborescence de gauche et cliquez sur le bouton '->'.

14. Dans la partie de droite sélectionnez la propriété 'Damage Bonus: Slashing [1 Damage] que vous venez d'ajouter et cliquez sur le bouton 'Edit Properties' au bas de la fenêtre. Sélectionnez '2 Damage' et cliquez sur le bouton 'Select', puis sur 'OK' pour retourner à l'Item Editor.

15. Cliquez sur 'OK' pour ajoutez ces propriétés à l'item.

16. Vous pouvez trouver votre nouvel item Griffe1d4+2 dans l'onglet 'Custom Items'. Déposez le emplacements 'Claws1' et 'Claws2' de l'inventaire de la créature.

17. Dans la partie 'Inventory's Standard Item', faites un clique-droit sur l'item 'Creature Item / Bite / Bite1d6' et sélectionnez 'Edit Copy'.

18. Dans l'Item Editor, changez le champ 'Item Name' en 'Morsure1D6+1'. Vous pouvez changez le Tag et le nom du bleuprint aussi si vous le souhaitez.

19. Dans l'onglet 'Properties', sélectionnez 'Damage Bonus / Piercing' dans l'arborescence de gauche et cliquez sur le bouton '->'. Par defaut, le bonus est '+1', vous n'avez donc pas besoin de le changer.

20. Cliquez sur 'OK' pour ajouter cette propriété à l'item.

21. Vous pouvez maintenant trouver votre nouelle 'Morsure1d6+1' dans la partie 'Custom Item'. Glissez la dans la case 'Special Attacks' de la créature.

22. Cliquez sur le bouton 'New' en dessous de l'arborescence sur la droite et sélectionnez 'Creature Item'.

23. Dans l'Item Wizard, donnez à votre nouvel item le nom 'Fourrure de Panthère de Malar' et cliquez sur 'Next'.

24. Dans la liste de catégories de la palette, sélectionnez 'Creature Items / Skin / Hide' et cliquez sur 'Next'

25. Cochez la case 'Launch Item Porperties' et cliquez sur 'Finish'.

26. Dans l'onglet 'Properties' de l'Item Editor', assignez lui la propriété 'Damage Reduction / +1' Par défaut, cette propriété est 'Soak 5', vous n'avez donc pas besoin de la modifier.

27. Assignez les propriétés 'True Seeing' (Vision veritable) et 'Immunity: Miscellaneous / Fear' (Immunité: Divers: Peur'.

28. Assignez la propriété 'Régénération' deux fois, de façon à ce que deux versions de cette propriété apparaissent dans la fenêtre de droite. Sélectionnez l'une d'elles et cliquez sur le bouton 'Edit Properties'.

29. Changez le 'Cost Item Parameter' en '+5' et clquez sur 'OK'. Ceci fera régénérer la créature d'un total de 6 points de vie par round.

Page 128: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

30. Cliquez sur 'OK' pour fermer l'Item Editor. Vous pouvez trouver votre nouvel item dans la partie 'Custom Items'. Glissez le dans la case 'Skin / Hide' de la créature.

31. Cliquez sur 'OK' pour fermer l'inventaire de la créature, puis à nouveau sur 'OK' pour fermer le Creature Editor. Vous pouvez trouver votre Panthère de Malar dans la catégorie 'Monsters / Animals / Feline' de la palette 'Custom Creature'. Vous pouvez maintenant l'utiliser comme vous l'auriez fait avec n'mporte quelle autre créature.

Exporting Your CreatureMaintenant que vous avez créer votre propre blueprint de créature, vous pouvez l'exporter pour l'utiliser dans vos autres modules, ou la partager avec d'autres développeurs.

Cliquez sur 'Export' dans le menu 'File' et choisissez 'Blueprint for Creatures' comme 'Ressource Type'.

Sélectionnez votre créature et clqiuez sur 'Open'. Sauvegardez votre fichier erf et ajoutez les commentaires que vous souhaitez.

D'autres personnes peuvent maintenant importer votre .erf et ajouter votre créature à leurs modules. Souvenez vous bien que ce .erf contient votre Creature Blueprint, mais pas la texture personnalisée. Les textures doivent être partagées en utilisant les hak paks.

Télécharger Notre Panthère de Malar toute faiteTéléchargez la Panthère de Malar erf ("zippé", 3 KB), et sauvegardez la à un emplacement que vous saurez retrouver.

"Dézippez" la dans un emplacement temporaire (grâce à un outil comme WinZip).

Dans le menu 'File' de votre module, sélectionnez 'Import', et naviguez jusqu'à l'endroit ou vous avez "dézipper" le *.erf. Sélectionnez le .erf à importer et cliquez sur 'Open'. Vous pouvez lire les commentaires si vous le souhaitez, puis cliquez sur 'OK'.

Vous pourrez trouver la Panthère de Malar dans la category 'Monsters / Animals / Feline' de la palette 'Custom Creature'. Vous pouvez maintenant l'utiliser comme vous l'aurez fait avec n'importe quelle autre créature.

Importer un son dans son moduleImporter un son dans son module (traduction du tutorial de Bioware)

Ce tutorial vous montrera comment ajouter un son fait sur commande à votre module en utilisant un hak pack.

Page 129: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Étapes pour ajouter un son :

Le processus que nous emploierons est comme suit:

1. Prenez votre son et ajoutez le au hak pack2. Ajoutez votre hak pack à votre module

3. Ajoutez le son à votre module

 

Ajouter le son à votre Hak Pak

La première chose que vous devrez faire est d'ajouter votre file(s) de wav à un Hak Pak, qui peut alors être employé avec votre module, et distribué pour plusieurs personnes apprécier vos créations.

1. Le compilateur de Hak Pak est le 'nwhak.exe 'programme situé dans dans le répertoire où vous avez installé Neverwinter Nights (l'endroit par défaut est C: \programfiles \NeverwinterNights \nwn). Double-cliquez sur ''nwhak.exe 'pour lancer le compilateur.

2. Ajoutez les sons wav au compilateur de Hak Pak en choisissant l’option 'ressource '- > 'add'. Sélectionnez l'endroit du dossier de wav. Choisissez et l’ouvrez les.

3. Vous verrez maintenant les sons énumérés comme ressource dans le Hak Pak. Mettez un titre et une description de votre Hak Pak, et enregistrer le dans ledossier hak du répertoire du jeu où vous l’avez installé.

 

Ajouter un Hak Pak à un module

1. Maintenant que le Hak Pak est dans votre dossier de 'hak ', nous pouvons l'ajouter à un module. Ouvrez un module existant ou nouveau dans le Toolset. Allez dans 'edit ' - 'modules properties‘ puis choisissez l’étiquette ‘advanced’. Dans l'option hak file choisissez votre hak pack.

Note: Rappelez-vous que si vous employez un Hak Pak dans votre module, des joueurs

Page 130: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

doivent placer le même Hak Pak dans leur dossier de 'hak 'pour jouer le module, soyez ainsi sûr d'empaqueter le Hak Pak avec votre module en l'offrant pour le téléchargement!

 

Ajouter le son à votre module

Maintenant que le Hak Pak avec le nouveau son a été ajouté, nous pouvons ajouter celui ci au module.

1. Dans le menu supérieur du Toolset, choisissez ‘wizards’ - > 'sound wizard'.

2. Assignez la Catégorie de pallette. Choisissez la catégorie que vous voulez que votre modèle son apparaisse. Dans notre exemple, nous l'avons placé dans 'spécial '- > 'custom 1'.

3. Choisissez la synchronisation pour votre son (Seamlessly permet d’effectuer une boucle). Puisque nous créons la musique de fond, choisissez Seamlessly.

4. Choisissez le positionnement pour votre bruit. Encore, puisque nous créons la musique de fond, choisissez area wide.

5. Cliquez le bouton 'add sound... 'pour afficher la liste de wav dans le jeu et dans votre hak de pak. Choisissez le son que vous souhaitez utiliser, et cliquez sur ok.

6. Écrivez le nom pour votre modèle , et décochez la boîte 'launch properties dialogues'. Cliquez sur 'Finish '.

7. Le bruit apparaît maintenant dans la palette - > 'custom'- > 'special'- > 'custom1 '. Choisissez votre son et placez-le dans votre module.

En utilisant les étapes ci-dessus comme directive, vous pouvez ajouter des dossiers de wav à votre module.

faire de nouveaux Placeables a partir des Tilsets

de Skanzo et Tyriael

Voila comme promis , je l'ai fait vite fait (je bosse moi messieurs) alors si y a un souci n'hésitez pas à le signaler

Page 131: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Permiere etapeTout d'abord procurez vous les logiciels suivants :

nwnviewer de zoligato nwnMdlviewer de bioware mdl2ascii.exe

Voila ensuite créez un dossier ou vous fourrez tout ca ; appellons le : Mobilier. Faites dans le même dossier un raccourci du programme mdl2ascii.exe. Créez votre hak avec le nwnviewer de zoligato (File/nwn packer/icone page blanche/new hak/-nom de votre hak-).

Deuxieme etapelancez le nwnviewer. cliquez sur File/BIF/Never WinterNight Puis dans le cadre "BIF list", cliquez sur la ligne 8 : "Data\aurora_tin.bif".

Une liste de trucs apparaîtra en dessous. Dans cette liste, remarquez les lignes de Type MDL , ce sont celles-ci qui nous intéressent , cliquer dessus et voyez a droite apparaître le tileset .

Prenons le premier: tin01_a01_01 , cliquez dessus, à droite un tilset avec au mur une lanterne. Sur la partie de droite vous pouvez voir 2 cadres , animation et node Intéressons nous a "node" cliquer dessus et faite défiler les différents éléments dedans , vous pouvez voir que sur l'image certaines parties correspondant au nom passe en violet .Nous allons nous occuper de la lanterne qui devient violette avec le node : Box2151, et object 863 notez le quelque part ou souvenez vous en.

Bien à présent, faites un clique droit sur "tin01_a01_01" dans la liste et "extract file to _le fichier que l'on a appelle Objet_ "

Troisieme etapeAllons dans ce fichier , vous y voyez donc le fichier que l'on vient d'exporter "tin01_a01_01.mdl". Bien a présent faite sur le raccourcis de mdl2ascii.exe clic droit /propriété. Remplacez la ligne en face "cible" par la ligne suivante :"D:\Mes Documents\nwn\Objet\mdl2ascii.exe" tin01_a01_01.mdl . Vous l'avez compris on rajoute à la fin de la ligne le nom du tilset que l'on a importé (bien entendu remplacez le début de l'adresse par votre hdd et dossier).

Et ensuite validez , fermer les propriété , et double-cliquez sur le raccourci, vous devez obtenir ceci : tin01_a01-01.mdl.ascii

Page 132: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Quatrieme etapeFaites un double que vous renommez objet1 (par exemple) , Ouvrez le avec wordpad, à l'intérieur vous devez voir un truc comme ceci :

#Model converted by mdl2ascii #For updates/comments check out http://nwn-j3d.sf.net filedependancy Unknown newmodel TIN01_A01_01 setsupermodel TIN01_A01_01 NULL classification Character setanimationscale 1.000000 #MAXGEOM ASCII beginmodelgeom TIN01_A01_01 node dummy TIN01_A01_01 parent NULL endnode node dummy TIN01_A01_01sl2 parent TIN01_A01_01 position -0.006734 3.375280 1.761660 orientation 0.000000 0.000000 -1.000000 -1.570800 endnode node light TIN01_A01_01ml2 parent TIN01_A01_01 position -3.036070 -3.140780 4.000000 orientation 0.000000 0.000000 0.000000 0.000000 #this is fake data - real one has to be determined etc...

Effacez tout et mettez ceci :

#Model converted by mdl2ascii #For updates/comments check out http://nwn-j3d.sf.net filedependancy Unknown newmodel TIN01_T01_01 setsupermodel TIN01_T01_01 NULL classification Character setanimationscale 1.000000 #MAXGEOM ASCII beginmodelgeom TIN01_T01_01 node dummy TIN01_T01_01 parent NULL endnode

[ ]

endmodelgeom TIN01_T01_01 donemodel TIN01_T01_01

Ce qui correspond au début et à la fin de ce qu'il y avait...

Sauvegardez sous le nom plc_t27.

Ensuite, ouvrez le fichier original qui était souvenez vous : tin01_a01-01.mdl.ascii, à l'intérieur cherchez les lignes qui corresponde à l'objet qui nous intéresse , soit la lanterne et donc le node :Box2151 et la box2151 (Pensez bien à chaque fois de sélectionner tous les objets violets qui compose le placeable , parfois un seul , parfois plusieurs .)

Page 133: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Faites un copier de tout ce qui est entre node trimesh Box2151 et endnode de la box2151 , (node trimesh Box2151 et endnode y compris)

Collez ensuite ce que vous venez de copier à la place des [ ] du fichier plc_t27 (qui je le rappelle est expliqué juste au dessus). Puis à la suite du endnode de la box2151 Faite un copier de tout ce qui est entre node trimesh object863 et endnode du object863. Puis sauvegardez.

Ensuite selectionnez ceci : TIN01_T01_01 puis Edition/remplacer et remplacer par le nom plc_t27(je vous expliquerai le nom plus tard, mais remarquez que c'est le même nom que le nom du dossier).

Ensuite regardez bien la ligne "parent TIN01_A01_01" , remplacer TIN_A01_01 également par plc_t27 (dans les 2 objets , box2151 et object863).

Ensuite Remplacez la ligne position -0.010000 3.540000 1.950000 de la box2151et par la ligne : position 0.000000 0.000000 0.000000 (faites de même pour l' object863)

Puis sauvegardez.

Renommez votre fichier plc_t27.mdl.asciien supprimant le .ascii vous devez obtenir ceci: plc_t27.mdl.

Ouvrez le programme nwnmdlviewer et regardez avec votre dossier ainsi créé et admirez la lanterne

Cinquieme etapeOuvrir le programme de zoligato File /NWN packer/ puis ouvrez le dossier _le nom de votre hack _.hak

A gauche tous les placeable : Exportez le dossier Placeable.2da dans votre dossier Fourre tout Mobilier, ensuite allez dans ce dossier et ouvrez le Placeable.2da avec wordpad .vous pouvez voir la liste des placeables : d'ou le nom plc= placeable , le numéro qui suit (soit pour nous 27 car j'en suis rendu la mais vous pourriez commencer a plc_t11 qui est le premier "nom libre de la liste ) correspond a un numéro "libre" qui suit la liste des placeable et le t , ben parce que !!! lool , disons que on aurais aussi bien put prendre a27 ou c27 etc.

donc tout en bas on prend a la suite et on copie/colle la ligne 200 soit : 200 BB_pouch 66494 gi_pouch **** **** **** **** 23 etc. et on remplace le par ce qu'il faut soit pour nous : 201 Lanterne_murale 6591 PLC_T27 **** **** **** **** 15 etc.

201: c la ligne suivant 200 Lanterne_murale : c'est le nom de notre objet 6591: correspond dans le toolset à miscellaneous (divers) PLC_T27 : est le nom de save de notre objet Puis on sauvegarde (en gardant le nom placeable.2da)

Sixieme etapeOn réouvre (troisième fois) le viewer de zoligato File /NWN packer/ puis ouvrez le dossier _le nom de votre hack _.hak.

Et a droite, on ouvre notre dossier Mobilier.(vous devez y voir votre plc_t27 et votre dossier placeable.2da.

A gauche dans votre hak , faite glisser de droite à gauche votre plc_t27 et votre dossier placeable.2da.

Sauvegardez sous le nom de votre hak (ainsi que sous celui qui est dans le dossier du jeu Neverwinter nights, le hak appelé par le jeu quoi ....) .

Page 134: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Septieme et derniere etapeOuvrez votre toolset , validez votre hak : edit/module properties/advanced/hak/mobilier (n'oubliez pas de le revalider a chaque nouvel objet ou changement du dossier placeables.2da).

Ensuite une fois celui ci chargé , allez sur votre module, icone placeable/custom.

Faites new , choisissez miscellaneous , tapez le nom de votre objet (ici Lanterne Murale ) et cochez "launch properties dialog".

Dans appareance type cherchez les lignes "placeable objet" et voyez votre lanterne apparaître.Posez la sur un mur , mettez y une flamme ou non et voila le tour est joué

Faites de même pour les autres objets des autres tilesets et vous aurez ainsi pleins de nouveaux objets. Pensez bien à chaque fois à sélectionner tous les objets violets qui compose le placeable , parfois un seul , parfois plusieurs .

ProblemesQuand vous importez un hak de ces placeables et que vous avez deja un de ces hak dans votre dossier , pensez à renommer tous les nouveaux placeables et leurs lignes dans le dossier placeable.2da , sinon vous risquez d'écraser ceux qui sont déjà en place !!!!!

Parfois problème de positionnement des placeables quand ils sont composés de plusieurs éléments (faut jouer avec les numéros de position)

Demandesi quelqu'un saurait programmer toute cette manip afin d'en obtenir un petit programme simple avec juste des clics par ci par la , ben bravo

Mais dans l'immédiat un prog qui permettrait de placer automatiquement le nouveaux placeable a la suite des autres dans le dossier placeables (ligne du nouvel objet = ligne du dernier de la liste+1, et nom de save plc_t(nom du dernier plc+1) etc., ça serait bien pratique aussi , voila Bon courage a tous et n'hésitez pas à demander si vous avez un souci...

Skanzo et Tyriael

Ajouter l'item 'Sac de Dés' . de Rob Barteltraduit par Kemay

 Que ce soit pour se relaxer en jouant aux dé dans une taverne locale, ou pour faire des jets de compétence dans la campagne de votre DM, un sac de dés est souvent le meilleur ami du joueur de jeu de rôle.

Ces sacs de dés, faits à la main par des singes dressés dans lointaines jungles de Chult, contiennent 10 dés de chacune des variétés classiques: d4, d6, d8, d10, d20 et d100. Ils offrent de plus un système sécurisé, protégé contre la triche, qui vous permet d'afficher vos jets en privé,

 

Page 135: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

localement ou même à travers tout le serveur. Pour en commander un, composer le numéro affiché sur votre écran maintenant !

Description

Ce sac de dés est prévu pour être utilisé par les DMs et les joueurs.

Pour l'activer, vous pouvez soit le placer dans l'un des emplacements rapides, ou utiliser le menu du clique droit lorsqu'il est dans votre inventaire. En l'activant, vous lancerez un conversation vous permettant de choisir les options d'affichage du résultat, le type de dés et le nombre de dé que vous voulez lancer.

 

Le résultat apparaîtra dans la fenêtre de chat:

Ajouter le Sac de des a un module

Ajouter les Echecs Neverwinter à un module . de Jonathan Epp et Robin Maynetraduit par Kemay

 

Le module Neverwinter Chess est une façon intéressante de jouer aux échecs en utilisant Neverwinter Nights, mais comment faire si vous souhaitez avoir un jeu d'échecs dans votre propre aventure ?

Ce tutorial vous montrera comment facilement ajouter un ou plusieurs jeux d'échecs à votre propre module. Vous êtes prêts pour un tournoi d'échecs en extérieur dans la forêt ?

Instructions

Page 136: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

1. Dans le Toolset, ouvrez l'area où vous souhaitez placer le jeu d'échec, ou créez une nouvelle area si vous préférez.

2. Téléchargez le fichier Chess game (jeu d'échec) (.zip, 79 KB), et sauvegardez le à un emplacement que vous pourrez retrouver.

3. "Dézippez" le fichier 'NWN_Chess_Import.erf' dans un dossier temporaire (en utilisant un outil comm Winzip).

4. Dans le meu 'File' du Toolset, sélectionnez 'Import' et naviguez jusqu'à l'emplacement où vous avez "dézippé" 'NWN_Chess_Import.erf'. Sélectionnez le et cliquez sur 'Open'. Si vous le souhaitez, vous pouvez lire les commentaires, puis cliquez sur 'OK'.

5. Pour un jeu d'échec normal, placez une zone 2x2 du tile 'Chessboard'. (vous le trouverez dans Paint Terrain / Features / Chessboard ). Nous voulons un jeu d'échec final ayant une dimension de 8 x 8 cases.

 

 

Note: Les tiles 'Chessboard' ne sont pas nécessaires. Les pièces du jeu apparaîtront sur le terrain actuel quel qu'il soit (ce qui rend le jeu très intéressant à jouer).

 

6. Déterminez le centre de la zone de jeu en plaçant un 'Custom Waypoint' "centerpoint"(vous le trouverez dans Paint Waypoint / Custom / Special / Custom 1) là où vous souhaitez que se trouve le centre du jeu d'échec. Si vous utilisez les tiles 'Chessboard', placez le "centerpoint" précisément au milieu des 4 tiles 'Chessboard'. C'est ce waypoint qui contrôle où les pièces seront alignées, et non pas les tiles 'Chessboard'. Vous pouvez faire effectuer des rotations au waypoint pour changer l'orientation du jeu d'échec dans n'importe quelle direction - il pointe vers l'arrière du jeu.

Page 137: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

7. Ensuite placez une instance du blueprint de créature "gamemaster" (Dans Paint Creatures / Custom / Special / Custom 1) près du jeu d'échec.

Ajoutez plusieurs jeux d'echec

8. Vous pouvez placez plusieurs jeux d'échec dans le même module, ou même dans la même area. Placez simplement un "centerpoint" et un "gamemaster" pour chaque jeu. Un mot d'avertissement cependant - Comme les pièces utilisent GetNearestOjectByTag pour trouver leur "gamemaster", ne placez pas deux jeux trop proches l'un de l'autre, ou certaines pièces pourraient intéragir avec le mauvais gamemaster.

 

__________________KemayCinq personnes sur quatre ont des problèmes avec les fractions.

1. Télécharger le fichier Dice Bag (Sac de dés) (.zip, 39 KB) et sauvegardez le à un emplacement où vous pourrez le retrouver.

2. "Dezippez" les 3 fichiers *.erf dans un répertoire temporaire (en utilisant un outil comme Winzip).

3. Dans le menu 'File' du Toolset, sélectionnez 'Import' et naviguez jusqu'à l'emplacement où vous avez "dézippé" les fichiers .erf. Sélectionnez l'un des fichiers .erf du sac de dés et cliquez sur 'Open'. Si vous le souhaitez, vous pouvez lire les commentaires, puis cliquez sur 'OK'. Répétez ce processus jusqu'à ce que les trois fichiers aient été importés.

 

Page 138: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

4. Placez autant de Sacs de dés que vous voulez dans votre module. Vous trouverez le blueprint dans 'Items / Custom / Miscellaneous / Other'. Sélectionnez simplement 'Dice Bag' et cliquez à l'endroit de votre module où vous souhaitez ajouter l'item.

5. Attachez le script 'dicebag_activate' à l'event onActivateItem de votre module. Vous trouverez cet event dans le menu 'Edit / Module Porperties' à l'onglet 'Advanced'.

6. Ne placez pas le 'Dicebag placeable'. Il doit juste être disponible comme blueprint dans votre palette.

Limitations

Le Sac de Dés est dépendant du module. Il ne fonctionnera que dans des modules ayant le script DiceBag_Activate attaché à leur event onActivateItem et le 'Dicebag placeable' disponible comme blueprint dans la palette.

 

__________________KemayCinq personnes sur quatre ont des problèmes avec les fractions.

Tutorial NWScript

Préambule :

Les NWScripts est le nom donné au langage de script développé par Bioware pour Neverwinter Nights. Ce langage diffère très peu du langage C, et est aussi très facile à apprendre. Néanmoins, tout comme il est difficile d’apprendre une langue étrangère sans « bases », il n’est pas facile d’apprendre un langage de script en partant de rien.

Ce tutorial est là pour vous servir de base. Il ne s’agit pas bien sur de la meilleure base que vous pourrez trouver mais il devrait vous aider pour utiliser au mieux les NWScripts et faire des modules « scriptés ». Grâce aux scripts, vous pourrez faire un peu de tout et de n’importe quoi : vous pourrez ajouter des effets spéciaux (par exemple, des éclairs partant d’une sphère pour foudroyer tout ce qui se trouve dans la zone) , vous pourrez ajouter des « pseudo-sorts » à vos aventures : par exemple, vous pourrez créer un sort qui va créer un portail en produisant des perturbations atmosphériques ; en bref : les NWScripts vous permette de faire de votre module un module vivant et qui ne sera pas statique.

Pour ce tutorial, nous utiliserons comme référence le fameux Lexicon (http://www.reapers.org/nwn/reference/ (en anglais)) qui est un des meilleurs (sinon le) glossaires sur les NWScripts. Et nous nous baserons sur la table des matières de la documentation de PHP (http://www.php.net/manual/fr/).

Aussi, vous trouverez à certains endroits une syntaxe assez spécifique : par exemple, lorsque vous verrez ceci :

int var1[, ..., [varN]];

Les crochets indiquent une partie optionnelle : vous pouvez l’omettre. Les « ... » indiquent qu’il s’agit d’une suite d’éléments (par exemple var1, var2, var3 etc). Voici quelques exemples de résultat :

Page 139: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

int var1; int var1, var2; int var1, var2, var3; int var1, var2, var3, var4;

Tables des matières :

1. Généralités 2. Les types 3. Les variables 4. Les opérateurs 5. Les structures de contrôle 6. Les fonctions 7. Les événements 8. La «   norme   » 9. Exercices

1. Généralités

Cette section vous explique des choses bonnes à savoir sur les Nwscript :

Le compilateur prend en compte la casse des caractères : ‘a’ n’est pas la même chose que ‘A’.

Il existe trois types de NWScripts : - les scripts d’inclusion : ils ne doivent pas contenir l’instruction void main() ou int StartingConditionnal().- les scripts conditionnels (réservés aux dialogues) : un script conditionnel contient exclusivement la fonction int

StartingConditionnal().- les scripts ‘divers’ (qui contiennent tout et n’importe quoi) : ce type de script doit contenir la fonction void

main() pour être valide.

Les scripts sont construits sous forme de blocs délimités par des accolades ({ et }) par exemple :

void main(){ if ( condition ) resultat ; else if ( condition2 ) { resultat2 ; } else resultat3; }

Nous avons plusieurs blocs : if ( condition ), else if (condition 2 ), et enfin else . Ces trois blocs sont inclus dans un bloc général void main().

Vous pouvez inclure un autre NWScript afin d’alléger vos scripts et d’éviter de recopier sur chacun de vos scripts nécessitant une fonction ‘x’ le code de la fonction x : pour cela, vous devez utiliser l’instruction #include « nom_du_script ».

Page 140: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Chaque instruction doit être finie par un point-virgule « ; » tel que :if ( condition ){ resultat ; foo() ; }

Vous ne devez pas mettre de « ; » après la parenthèse de fin d’une structure de contrôle (voir section 6). De même, vous ne devez pas mettre de « ; » après la fin d’un appel de fonction (voir exemple sur les blocs).

Vous pouvez ajouter des commentaires (ceux-ci ne seront pas exécuté) : pour cela, vous avez deux façons de faire : - les commentaires sur une ligne : ceux-ci doivent être précédés de // tel que :

// Ceci est un commentaire sur une ligne- les commentaires multi lignes : ceux-ci doivent être ‘entourés’ de /* et de */ tel que :

/* Ceci est un commentaire sur deux lignes Voici la deuxième ligne */Vous n’êtes - bien entendu – pas forcé de sauter une ligne avec le commentaire multi lignes. C’est à vous de choisir.

Une fois que vous avez écrit votre script, celui-ci doit être (bien sûr) sauvegardé, et compilé. La compilation du script se fait par la commande F7 et vous permet de savoir où il y a des erreurs dans votre script. Cependant, sur ce point là, l’éditeur de script de NWN a une lacune : il reconnaît les scripts conditionnels et les scripts « divers » mais pas les scripts d’inclusions. Ce qui fait que celui-ci risque de vous avertir que le script n’est pas valide parce qu’il ne contient pas au choix la fonction void main() ou la fonction int StartingConditional. Pour compiler un script d’inclusion, vous devrez passer par un script incluant votre script d’inclusion.

2. Les types

Les NWScripts vous permettent de définir des variables (voir section 3) : celles-ci sont obligatoirement typées. Voici pour vous aider la définition de chacun des types présents dans les NWScripts.

- action : ceci représente une action. Ce type est beaucoup utilisé par les fonctions Action*.- command : ce type revient au même qu’au type void sauf qu’il est utilisé par les fonctions DelayCommand() et

AssignCommand().- constant : une constante est une variable qui ne change pas (et qui ne peut pas être changée) au cours du

déroulement normal du script une fois qu’elle est déclarée et définie et qui est présente quelque soit le script. Dans les NWScripts, vous ne pourrez pas réellement définir de constantes : vous devrez utiliser les constantes de bases (nous vous renvoyons sur cette page : http://www.reapers.org/nwn/reference/compiled/constant.index.html) ou vous servir de variables globales.

- effect : ce type vous permet de définir un effet pour ensuite pouvoir l’appliquer avec ApplyEffectToObject() ou encore ApplyEffectAtLocation().

- event : un event (ou événement) est le moteur de vos scripts : il vous permet d’activer vos scripts en fonction d’une condition précise (par exemple, le personnage meurt).

- float : ceci correspond au type décimal (aux nombres décimaux). Il s’agit d’un nombre signé sur 32 bits (4 octets) allant de -3.402823e38 à 3.402823e38. Nous reviendrons sur le type décimal dans la section 3.

- int : ce type sera certainement celui que vous utiliserez presque tout le temps avec le type ‘object’. Il s’agit du type entier : c’est un nombre signé sur 32 bits (4 octets) allant de -2147483647 à 2147483647.

- location : une location correspond à un point spécifique sur une zone. Une location se caractérise par : un ID de zone, un vecteur (voir plus bas) et un nombre décimal représentant la position angulaire d’un objet par rapport à l’axe Ouest-Est (par exemple : si vous regardez vers le sud, votre position angulaire par rapport à l’axe Ouest Est sera de 270° ou -90°).

- object : le type objet est un des types les plus importants des NWScripts : il représente chacun des objets présents dans votre module : par exemple, le module sera un objet, une zone sera un objet. Il s’agit en fait d’un entier qui représente un objet particulier dans le module.

- string : ce type vous permet de stocker des chaînes de caractères d’une taille arbitraire (une chaîne de caractères étant par exemple « salut ».)

- struct : le type structure vous permet de combiner plusieurs autres types (entiers, etc). Vous ne pourrez pas combiner d’autres structures à l’intérieur de votre structure.

- talent : ceci représente un talent : par exemple, un don, une aptitude, ou encore des sorts.

Page 141: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

- vector : un vecteur revient au même qu’une structure de trois nombres décimaux. Un vecteur est caractérisé par ses coordonnées x, y, z.

- void : il s’agit du type « nul ». Il ne renvoie rien. Il sert surtout aux fonctions ne devant rien renvoyer (par exemple void main() ; Note : de telles fonctions sont appelées Procédures).

Ceux qui connaissent déjà la programmation remarqueront qu’il manque un type qui pourtant est très utilisé  : il s’agit du type tableau (array) qui n’est pas présent dans le NWScript. Aussi, vous trouverez un deuxième type qui est présent mais sous une autre forme : c’est le type booléen. Celui-ci n’est pas présent en tant que type à part, mais présent en tant que type entier où 0 vaut FALSE et 1 vaut TRUE.

Une fois que vous avez les différents types, il nous faut les déclarer : c’est ce que nous verrons dans la section suivante.

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 ) );

Page 142: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

location lWhereToGo = Location( oArea, vPosition, fOrientation );

- object : object oPlayer1, oPlayer2, ..., oPlayer6 ; object oSelf = OBJECT_SELF ; // constante correspondant à l’objet qui « porte » l’événement. object oInvalid = OBJECT_INVALID ; // constante représentant un objet invalide.

- 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" ; // bon string sFoo1, sFoo2 = "Sal"ut" ; // pas bon string sFoo1, sFoo2 = "Sal\"ut" ; // pas bon non string sFoo1, sFoo2 = "Sal""ut" ; // pas bon non plus. 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 :

struct FX aura, beam;

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();

Page 143: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

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 ; /* ceci est bon car vAutreVecteur est un vecteur et contient 3 coordonnées x, y, z. */

vector vVecteur = 0.0 ; /* ceci est faux car 0.0 n’est pas un vecteur */

vector vVecteur1 ; vVecteur.x = 0.0 ; // N’oubliez pas que 0 est un entier et que vVecteur.y = 0.0 ; // 0.0 est un nombre décimal. vVecteur.z = 0.0 ; /* Vous devrez définir les 3 coordonnées vous-mêmes à moins que vous n’utilisiez un autre vecteur. */

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 );// On répète l’instruction 100 fois par exemple 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" ;

Page 144: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

CreateItemOnObject( sBluePrint, oPlayer );// On répète l’instruction 100 fois par exemple 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 ); // On répète l’instruction 100 fois par exemple 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 »

// Debut du fichier inc_constantesstring 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.

4. Les opérateurs

NWScripts prend en compte divers opérateurs :

a. Opérateurs arithmétiques (et de concaténation) :

+, -, *, /, % : opérateurs d’addition, soustraction, multiplication, division et reste d’une division (Modulo).

Tous ces opérateurs s’appliquent sur les nombres, le ‘+’ (opérateur d’addition) peut s’appliquer sur des chaînes (cet opérateur devient ainsi un opérateur de concaténation).

Page 145: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Par exemple : int a = 1; int b = 2;

a = a + b ; // 1 + 2 = 3 a = a - b ; // 1 - 2 = -1 a = a*b ; // Ca marche 1*2 = 2 a = a/b ; // Note : ceci devrait être un nombre décimal dans ce cas 1/2 = 0.5 a = a % b ; // Le reste de la division entière de a par b est 1.

string s1 = "Une " ; string s2 = "Chaîne" ; string s3 = s1 + s2 ; // s3 = "Une Chaîne"

On peut aussi simplifier ces formes par exemple :

a += b ; // ceci revient au même que a = a + b ; (marche aussi pour les chaînes) a -= b ; // ceci revient au même que a = a - b ; a *= b ; // ceci revient au même que a = a * b ; a /= b ; // ceci revient au même que a = a / b ; a %= b ; // ceci revient au même que a = a % b ;

(Note : vous pouvez appeler =, +=, -=, *=, /= et %= des opérateurs d’affectations puisqu’ils vont affecter à une variable une nouvelle valeur)

b. Opérateurs de comparaisons :

Les opérateurs de comparaisons sont très utiles et sont donc très utilisés dans les structures de contrôles. La plupart des opérateurs de comparaisons ne fonctionnent qu’avec des nombres.

== Egalité!= N’est pas égal>  Supérieur à >= Supérieur ou égal à< Inférieur à<= inférieur ou égal à

Un autre opérateur est l’opérateur ternaire (« ?: ») : nous le verrons plus en détail dans la section sur les structures de contrôle.

Exemples :Avec s = "chaine" ; a = 1, b = 1 et c = 2 (ce sont tous des entiers).

a == a : ceci est vrai. (TRUE)a != a : ceci est faux. (FALSE)a > a, a > b : ceci est faux (FALSE)c > a : ceci est vrai. (TRUE)a < c : ceci est vrai (c’est équivalent à l’exemple précédent) (TRUE)a >= b : ceci est vrai. (TRUE)a <= b : ceci est vrai. (TRUE)

s == "chaîne" : ceci est vrai.s >= "chaîne" : ceci ne veut rien dire !

c. Opérateurs d’incrémentation :

Ces opérateurs s’appliquent qu’aux entiers même si dans d’autres langages (comme PHP) ils peuvent être utilisés sur des chaînes de caractères. Ils vous permettent d’incrémenter (ajouter 1 à une valeur entière) ou de décrémenter (soustraire 1 à une valeur entière).

Page 146: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

--a : Post décrémentation.a-- : Pré décrémentation++a : Post incrémentation.a++ : Pré incrémentation

Vous vous demandez sûrement qu’elle est la différence entre la post et la pré incrémentation : nous vous montrons cette différence par l’exemple :

int a = 1 ;

a-- ; // a est renvoyée puis est décrémentée (donc a = 1)--a ;  // a est décrémentée puis renvoyée (donc a = 0)a++ ; // a est renvoyée puis est incrémentée (donc a = 1)++a ;  // a est incrémentée puis renvoyée (donc a = 2)

Ceci ne vous dit peut-être rien ? Soit : voici un exemple plus appréhendable :

void main(){ int a = 1;

FloatingTextStringOnCreature( "a= " + IntToString( a ) +" --a:" + IntToString( --a ), GetFirstPC() ); FloatingTextStringOnCreature( "a= " + IntToString( a ) +" a--:" + IntToString( a-- ), GetFirstPC() ); FloatingTextStringOnCreature( "a= " + IntToString( a ) +" ++a:" + IntToString( ++a ), GetFirstPC() ); FloatingTextStringOnCreature( "a= " + IntToString( a ) +" a++:" + IntToString( a++ ), GetFirstPC() );}

Si vous placez cet exemple dans un script, par exemple OnHeartBeat (nous verrons dans la section sur les événements qu’il ne faut pas mettre n’importe quoi comme script dans cet événement), ceci affichera successivement :

a=1 --a : 0a=1 a-- : 1a=1 ++a : 2a=1 a++ : 1

Maintenant, vous vous demandez sûrement quel est l’intérêt ? Dans l’utilisation basique qu’on en fait, il n’y a strictement aucun intérêt vu que le plus souvent vous écrirez :

a++ ;

Et a sera incrémentée puis réutilisée (par exemple dans une boucle).

En fait, cela dépend de ce que vous voulez faire de la valeur de a : par exemple, la passer dans une fonction etc !

d. Opérateurs logiques

Les opérateurs logiques sont utilisées dans tout ce qui concerne les conditions.

&& : ET logique. || : OU logique.! : NON logique. (Négation)

Le ET vous permet de lier deux conditions qui devront être VRAIES. (TRUE)

a && b  : renvoie VRAI si a = VRAI et b = VRAI.

Le OU vous permet de lier deux conditions, cependant une des deux conditions peut faire défaut :

Page 147: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

a || b : renvoie VRAI - si a = b = VRAI - si a = VRAI, b = FAUX - si a = FAUX, b = VRAI

Le NON correspond à la négation d’une condition :

!a : si a est VRAI alors !a renvoie FAUX ; si a est FAUX alors !a renvoie VRAI.

Vous remarquerez que par défaut le OU n’est pas exclusif. Si vous connaissez déjà la programmation, vous connaissez sûrement l’opérateur XOR qui n’est pas présent dans les NWScripts. Voici comment faire pour « simuler » le XOR (OU EXCLUSIF)

Normalement :a xor b : renvoie VRAI - si a = VRAI, b = FAUX - si a = FAUX, b = VRAI

De manière textuelle, qu’est ce que le OU exclusif ?( ( a OU b ) ET NON ( a ET b ) )

Si vous voulez simuler le OU EXLUSIF vous devrez employer la forme suivante :

( ( a || b ) && !( a && b) )

Note : dans tous nos exemples a et b sont des conditions. Une condition renvoie automatiquement un booléen dépendant du résultat de la condition : si elle est vraie, ou si elle est fausse. Dans beaucoup de langages il existe un type booléen où dans ce cas une condition renverra TRUE (selon le langage, ça sera True, true, etc) si elle est vérifiée ou FALSE si ce n’est pas le cas.

Assurez vous d’avoir bien compris le fonctionnement (et l’utilité) des opérateurs logiques car ils sont quasiment à la base de la programmation.

Afin de finir cette section, nous vous donnons juste un bon avertissement : n’oubliez jamais le type de vos variables, et n’essayez jamais de faire des opérations entre des variables d’un type « a » et des variables d’un type « b ».

Si vous désirez vraiment faire des opérations entre des variables de types différents, vous pouvez utiliser des fonctions de transtypage présentes :

Conversion d’entiers :IntToFloat (conversion vers un nombre décimal), IntToHexString (représentation en hexadécimal de l’entier sous la forme chaîne de caractères), IntToString (conversion vers une chaîne de caractères).

Conversion de nombres décimaux :FloatToInt (conversion d’un nombre décimal vers un entier), FloatToString (conversion d’un nombre décimal vers une chaîne de caractères).

Conversion de chaînes de caractères :StringToInt (conversion vers un entier), StringToFloat (conversion vers un flottant).

Aussi, si nous n’en parlons pas beaucoup : n’oubliez pas de vous servir des parenthèses surtout si vous utilisez des multiplications / divisions:

int i , j = 2 ;

j = i + j * 2 ; // j = 2 + 2*2 = 6 j = ( i + j ) * 2 ; // j = ( 2 + 2) * 2 = 8

Page 148: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Ces mêmes parenthèses vous sont encore plus utiles avec les opérateurs logiques. En définitive : n’hésitez pas à abuser des parenthèses.

5. Les structures de contrôle

Voir les opérateurs, c’est bien, mais ce n’est pas ça qui va nous permettre par exemple de définir si un script doit forcer le personnage ‘x’ à aller dans une telle zone ! Pour cela, nous devons utiliser des structures de contrôle, qui vont nous permettre de « conditionner » nos scripts, qui pourront aussi les alléger, etc. !

a. Les conditions (if, else)

Les instructions if et else sont les plus importantes instructions de tout langage de programmation : elles vont vous permettre de décider si une partie de votre code devra être exécuté ou non. Basiquement, le code est exécuté si la condition est vérifiée :

if ( condition ) instruction ;

Mettons que la condition soit : a == b et que a = b (a, b deux entiers). Dans ce cas, la condition renvoie VRAI (true) et l’instruction sera exécutée.

Dans ce cas-ci, notre « instruction » tiens sur une ligne : vous pouvez omettre les accolades. Si votre code fait plusieurs lignes, vous devez utiliser les accolades :

if ( condition ){ instruction1 ; instruction2 ;}

Maintenant, nous avons notre condition : néanmoins, il ne se passe rien si celle-ci est fausse. Pour cela, on va utiliser la structure else (sinon) :

if ( condition ) instruction1 ;else instruction2 ;

(On suppose que « instruction1 » et « instruction2 » sont sur une ligne)Ainsi, si on reprend notre exemple : on teste a == b, et dans ce cas a > b. Alors l’ « instruction2 » sera exécutée au lieu de l’«instruction1».

Vous pouvez bien sur combiner les else et les if : reprenons notre exemple :

if ( a == b ) a = b ;else if ( a > b ) a = b + 1 ;else if ( a < b ) a = b - 1 ;else a = a ;

Nous vérifions donc successivement : si a == b alors a = b sinon si a > b alors a = b + 1

Page 149: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

sinon a < b alors a = b - 1 sinon a = a

Nous avons indenté notre exemple pour bien vous montrer une chose importante à savoir  (ça peut être la cause d’erreurs pour des conditions plus compliquées) : dans un premier temps, on vérifie si a = b, et dans ce cas on va effectuer l’instruction a = b, si a != b alors on va vérifier en premier lieu si a > b, puis en second lieu si ce n’est pas le cas si a < b et enfin si aucune des expressions n’est vérifiée on exécute l’instruction ‘a=a’.

Si vous n’avez pas compris, focalisez vous sur les mots ‘premier’ et ‘seconds’ : l’ordre des conditions importe, c'est-à-dire que vous ne pourrez pas avoir de condition ‘a < b’ sans avoir de conditions ‘a == b’ et ‘a > b’.

Au passage, vous noterez l’inutilité totale du else : nous avons vu chacun des cas possibles.

Voici des exemples de conditions plus compliquées (elles proviennent d’un script en PHP) : vous noterez l’utilisation des parenthèses pour bien séparer les différentes parties de la condition.

if ( $iMode != -1 && $this->_s != -1 && ( ( $this->bUserIsModerator == true && ( ( $MB->aUserModerator['SujetOpen'] == 1 && $iMode == 0 ) || ( $MB->aUserModerator['SujetChRestriction'] == 1 && $iMode != 0 ) ) ) || $this->bUserIsAdmin == true ) ) instruction ;

if ( $iType != -1 && $this->_s != -1 && ( ( $this->bUserIsModerator == true && $MB->aUserModerator['SujetChType'] == 1 ) || $this->bUserIsAdmin == true ) ) instruction ;

Il s’agit sûrement d’horreurs pour quelqu’un qui débute, mais ces cas là ne sont pas inexistants. Vous aurez vous aussi peut-être besoin de faire d’aussi longues conditions. Pour éviter les erreurs, vous avez plusieurs méthodes :

Vous pouvez décomposer la condition : (Note : en PHP les variables ne sont pas typées par défaut. Dans le cas des NWScripts vous devrez déclarer des entiers)

$condition1 = $iMode != -1 ;$condition2 = $this->_s != -1 ;$condition3 = $MB->aUserModerator['SujetOpen'] == 1 && $iMode == 0 ;$condition4 = $MB->aUserModerator['SujetChRestriction'] == 1 && $iMode != 0 ;$condition5 = $this->bUserIsModerator == true ;$condition6 = $this->bUserIsAdmin == true ;

Ce qui nous donne : if ( $condition1 && $condition2 && ( ($condition5 && ( $condition3 || $condition4 ) ) || $condition6 ) )

Ce qui, vous l’avouerez est plus lisible, ou plus compréhensible. Néanmoins, vous stockez des variables supplémentaires pour RIEN. C’est tout l’avantage de la deuxième solution :

if ( $iMode != -1 && $this->_s != -1 && ( ( $this->bUserIsModerator == true && ( ( $MB->aUserModerator['SujetOpen'] == 1 && $iMode == 0 ) || ( $MB->aUserModerator['SujetChRestriction'] == 1 && $iMode != 0 ) ) ) || $this->bUserIsAdmin == true

Page 150: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

) )

Tout de suite, cela prend bien plus de place mais cette méthode est plus utile : premièrement, on n’utilise pas de sous variables, deuxièmement en général le compilateur accepte cette forme, et troisièmement on peut plus facilement savoir ce qui se passe exactement à l’intérieur de notre condition : c’est le but de l’indentation.

Enfin, nous vous avions parlé de l’opérateur ternaire ( « ? : ») : celui-ci permet de faire une condition « if ( condition ) { instruction } else {} »  sur une ligne : il a cependant de grandes différences avec le couple if/ else : il ne permet pas d’effectuer toutes les instructions voulues, ça n’est pas son but. Son but ? C’est d’affecter à une variable une valeur en fonction d’une condition. Voilà la syntaxe générale :

a = (condition) ? instruction_si_vrai : instruction_si_faux ;

(On a mis « = » mais ça peut être += , etc.)

Par exemple :

a = ( a < b ) ? b + 1: b - 1 ;

Cet opérateur ternaire est très pratique, mais évitez d’en abuser. Par exemple évitez ceci :

a = ( a < b ) ? b + 1: b - 1 ;b = ( a < b ) ? a + 1: a - 1 ;

La condition étant la même dans les deux cas, préférez plutôt ceci :

if ( a < b ){ a = b + 1 ; b = a + 1 ; // Note : vous remarquerez qu’après cette instruction a est toujours inférieur à < b }else{ a = b - 1 ; b = a - 1 ;}

b. Les boucles (while, for, do ... while)

Un autre aspect pratique de la programmation est la boucle. Si on reprend notre exemple sur les variables globales :

CreateItemOnObject( "item", oPlayer );// On répète l’instruction 100 fois par exemple CreateItemOnObject( "item", oPlayer );

Ici, on a écrit 100 fois CreateItemOnObject( "item", oPlayer ); ! Maintenant, avec les boucles, on va pouvoir réduire ceci et corriger cette erreur. L’avantage étant que vous réduirez ainsi la taille de vos scripts (sachant qu’ils sont limités à 512 Ko avec le patch 1.26).

Pour effectuez 100 fois l’instruction CreateItemOnObject( "item", oPlayer ) ; nous avons trois structures de contrôle qui vont nous permettre de réduire notre code.

La première, c’est l’instruction while, la seconde, l’instruction for et enfin la troisième do ... while.

Voici la syntaxe de while :

while ( condition )

Page 151: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

{ instruction ;}

Ici tant que la condition sera VRAIE alors l’instruction sera effectuée. L’instruction est supposée permettre à la condition d’être fausse à un moment : si tel n’est pas le cas, alors vous créerez une boucle infinie ce qui représente bien entendu un danger.

Voici un exemple de boucle simple : int i = 0 ;

while ( i < 10 ){ i++;}

Et un exemple de boucle infinie :int i = 0 ;

while ( i == i ){ i++;}

Dans d’autres cas, on peut avoir :

int i = 0 ;

while ( i != 10 ){ i++;

if ( i == 9 ) i = 11 ;}Il s’agit d’un autre type de boucle infinie : ici, on teste la condition i différent de 10 et on empêche que i soit égal à 10.

Voici notre exemple réécrit avec la boucle while :

int i = 0 ; /* Assurez vous de savoir bien compter : de 0 a 100 il y a 101 nombres, donc vous devrez utiliser la condition i < 100 et non i <= 100 ( a moins que i = 1 )*/while ( i < 100 ){ CreateItemOnObject( "item", oPlayer );}

Vous voyez ? Notre exemple est tout de suite plus propre. Mais ... nous avons oublié de mettre i++ pour que la boucle puisse se fermer...

int i = 0 ; while ( i < 100 ){ CreateItemOnObject( "item", oPlayer ); i++ ;}

(Note : on peut mettre i++ avant CreateItemOnObject)

Page 152: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

L’instruction while permet de créer des boucles simplement, sans trop s’embêter. Néanmoins, il faudra penser à chaque fois à mettre une instruction permettant d’arrêter la boucle.

L’autre façon de créer des boucles, c’est avec l’instruction for : celle-ci est plus « sécuritaire » puisque dans sa déclaration vous devez indiquez l’état de départ, la condition à vérifier et une instruction qui sera évaluée à chaque itération (une itération = un passage dans la boucle).

Voici la syntaxe :

for ( expression_depart ; condition ; instruction1 ){ instruction2 ;}

expression_depart : correspond à l’état initial : cette expression est exécutée lors de la première itération. Le plus souvent, il s’agit de définir la valeur initiale d’un entier : i = 0.condition : tout comme l’instruction while il vous faut une condition pour que la boucle puisse tourner. Le plus souvent on teste la valeur d’un entier (si celle-ci est inférieure à x par exemple) : i < x ;

instruction1 : il s’agit d’une instruction qui est exécutée quoiqu’il arrive. Cette instruction doit permettre de fermer la boucle : par exemple, i++.

instruction2 : instruction à exécuter.

Voici notre exemple réécrit avec la boucle for :

int i; for ( i = 1 ; i <= 100 ; i++ ){ CreateItemOnObject( "item", oPlayer );}

Note : on commence à 1 et on va jusqu’à 100 inclus, ce qui nous fait bien 100 objets de créés.

C’est à peu près tout ce qu’il y a à savoir sur les fonctions. Nous verrons plus loin dans cette section deux autres instructions qui sont très utiles avec les boucles.

Dans notre exemple avec la boucle For nous ne sommes pas forcés de mettre les accolades car notre instruction ne tient que sur une seule ligne. int i; for ( i = 1 ; i <= 100 ; i++ ) CreateItemOnObject( "item", oPlayer );

De même, avec la boucle while :

int i = 0 ; while (i++ < 100 ) CreateItemOnObject( "item", oPlayer );

Ce qui peut s’écrire :int i = 0 ; while ( ++i <= 100 ) CreateItemOnObject( "item", oPlayer );

Ici on pré incrémente i : ce qui veut dire que lors de la première itération de la boucle, i vaut 1 et pas 0 : c’est pour cela que l’on doit utiliser l’opérateur « inférieur ou égal à ».

Il existe aussi un troisième type de boucle : do ... while. Voici sa syntaxe :

Page 153: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

do instructions while ( condition ) ;

Dans ce type de boucle, le code est d’abord exécuté (même si la condition est fausse) et la condition est ensuite vérifiée.

Voici notre exemple :

int i = 0 ; do CreateItemOnObject( "item", oPlayer ) ;while (i++ < 100 ) ;

ou

int i = 0 ; do{ CreateItemOnObject( "item", oPlayer ) ;}while (i++ < 100 ) ;

c. l’instruction switch.

L’instruction switch est en fait une sorte de if mais imbriqué : vous allez tester la valeur d’un entier (généralement) et en fonction des différents cas, vous utiliserez une instruction switch.

Voici un exemple :int i = Rand( 3 ) ; // on donne une valeur aléatoire entre 0 et 2.

if ( i == 0 ) instruction1 ;else if ( i == 1 ) instruction2 ;else instruction3 ;

Avec switch ceci donnerait : int i = Rand( 3 ) ;switch ( i ){ case 0 : instruction1 ; break ; case 1 : instruction1 ; break ; default : instruction3 ; break ;}

Rien de bien compliqué dans cet exemple : cependant, vous remarquerez l’instruction break, dont nous reparlerons plus tard : celle-ci permet de sortir du bloc switch.

Voici un exemple sans ce break :int i = Rand( 3 ) ;

Page 154: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

int j = 0 :switch ( i ){ case 0 : j++ ; case 1 : j++ ; default : j++ ;}

Au sortir du bloc switch j aura la valeur suivante : 1 si i = 2, 2 si i = 1, et 3 si i = 0.

d. les instructions break et continue.

Les instructions break (que nous avons entrevue au paragraphe précédent) et continue sont surtout utilisées pour les boucles (sauf pour break, qui est aussi utilisée dans switch) : break va comme son nom le suppose arrêter l’exécution de la boucle (ou de l’instruction switch le cas échéant) tandis que continue va elle passer à l’itération suivante en ignorant le code située après continue.

Reprenons notre exemple de boucle infinie : même si c’est déconseillé, une boucle infinie est parfois souhaitable, il faut juste prévoir une condition inévitable afin que la boucle puisse être interrompue. 

int i = 0 ;

while ( i != 10 ){ i++;

if ( i == 9 ) i = 11 ;}

Dans cet exemple, on ne passait jamais par 10 causant ainsi une boucle infinie. On pourrait bien sûr utiliser la forme suivante :

int i = 0 ;

while ( i != 10 ){ i++; // Instruction}

Mais pour bien montrer l’utilisation de break, nous ne ferons que corriger notre exemple :

int i = 0 ;

while ( i != 10 ){ i++;

if ( i <= 9 ) // i <= 9 ou !( i > 9 ) i = 11 ; else break ;}

Page 155: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Ici, nous avons l’assurance que la boucle ne sera pas infinie : quand i sera supérieur à 9, alors la boucle sera interrompue ainsi que le code qui suit l’instruction break. Par exemple :

int i = 0 ;

while ( i != 10 ){ i++;

if ( i <= 9 ) // i <= 9 ou !( i > 9 ) i = 11 ; else { break ; i = 100 ; }}

Lorsqu’on testera la valeur de i, i vaudra 10 mais pas 100 comme le laisse supposer l’exemple. Si vous voulez que i prenne la valeur de 100 : vous devrez placer l’instruction i = 100 ; avant le break.

L’utilisation de break est strictement la même avec les boucles for, et do while (ainsi que le bloc switch, bien que dans le bloc switch il y ait largement moins de chances d’obtenir une boucle infinie... et pour cause !)

La seconde instruction, continue, va vous permettre de passer à l’itération suivante en ignorant le code suivant « continue ».

Par exemple : vous voulez construire un script qui fait varier la variable i de 1 à 25. Et tout les 5, vous voulez ajouter ‘+1’ à la variable j.

int i, j = 0 ;

for (i = 1; i <= 25 ; i++ ){ if ( (i % 5) != 0 ) continue ;

j++ ;}

L’exemple est très simple : si le reste de la division entière de i par 5 ne vaut pas 0, on continue la boucle jusqu’à atteindre une valeur de i telle que i % 5 = 0 (i Modulo 5). Quand on atteint cette valeur de i alors on incrémente j.

Ceci vous montre aussi qu’avec l’instruction continue on « part » directement à l’itération suivante sans se soucier du reste.

L’instruction continue fonctionne aussi avec les boucles while et do ... while.

C’est à peu près tout ce qu’il y a savoir pour les structures de contrôle. Sachez juste vous en servir avec parcimonie et préférez la boucle for lorsque vous désirez faire varier un entier d’une valeur de départ x vers une valeur de fin y. Il existe un autre moyen plus rudimentaire de faire des boucles qui consiste à se servir de fonctions : c’est justement ce que nous verrons dans la section suivante.

6. Les fonctions

Une fonction vous permet de faire plusieurs choses : - premièrement, elle vous permet d’éviter les répétitions dans votre code : en créant une fonction, vous pouvez

par exemple éviter de réécrire 5000 fois le même code.

Page 156: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

- deuxièmement : une fonction vous permet de généraliser vos codes sources. Si par exemple votre bout de code crée automatiquement un objet qui a un blueprint commençant par « nws_ » vous pourrez tout à fait définir une fonction qui va ajouter « nws_ » à vos blueprint.

- troisièmement une fonction vous permet de conserver des routines (un bloc de code) dans des fichiers d’inclusions ce qui évidemment vous rend la vie plus facile lorsqu’il s’agit de les modifier.

Il existe deux types généraux de fonctions : les fonctions qui renvoient une valeur, et les fonctions qui n’en renvoient pas (c’est le cas des procédures en Delphi par exemple). Avec les NWScripts, il n’y a pas de réelles différences entre une fonction qui renvoie quelque chose et une autre qui ne renvoie rien.

Voici la définition d’une fonction :

type FunctionName( [[type Argument1 [= ValeurArg1][ , ..., type ArgumentN [= ValeurArgN ]]] ){

return Variable ;}

Oui, ce n’est pas très clair, décomposons :- type FunctionName : ici vous devez indiquer le type de la fonction, c'est-à-dire le type de contenu qu’elle va

renvoyer. Par exemple, un entier (int). Si celle-ci ne renvoie rien, vous devrez mettre void FunctionName (par exemple), si elle renvoie quelque chose alors Variable devra être du même type que la fonction (par exemple, int). FunctionName correspond à un nom de fonction, tout comme les variables le nom de fonction ne peut pas être n’importe quoi : il ne doit contenir que des lettres, des chiffres et le tiret « _ » et doit commencer par une lettre. Aussi, le nom de la fonction ne doit jamais être celui d’une fonction déjà existante, il ne doit pas être égal à « main » ou à « StartingConditionnal ».

- entre parenthèses, vous devez indiquer les différents paramètres. Exemple avec une fonction « officielle » :

talent GetCreatureTalentRandom(int nCategory, object oCreature=OBJECT_SELF) ;

Vous devez aussi indiquer le type des paramètres et une valeur optionnelle : par exemple OBJECT_SELF. Néanmoins, vous n’êtes absolument pas forcé d’utiliser des arguments : ceci est possible :

string RandomName() ;

- l’instruction return vous permet de renvoyer une valeur qui devra être du type de la fonction, sauf si la fonction est de type void (elle ne renvoie rien donc). Return fonctionne comme les instructions break et continue : c’est à dire que le code placé après return n’est pas exécuté. Le mieux est de stocker la valeur qui va être renvoyée dans une variable temporaire et la renvoyer en fin de fonction. (note : vous pouvez quand même utiliser l’instruction return dans une fonction de type void pour par exemple cesser l’exécution de code)

Pour appeler une fonction : vous devez en connaître sa définition : vous pouvez double cliquer sur le nom de celle-ci dans l’éditeur de script de Neverwinter. Cependant, cela ne vous indiquera jamais les définitions de vos fonctions : pour cela, vous devez effectuer une manipulation particulière :

// Description // Ligne 1// ...// Ligne Ntype FunctionName( [[type Argument1 [= ValeurArg1][ , ..., type ArgumentN [= ValeurArgN ]]] ) ;

Vous devez placer la définition de la fonction en entête de votre script. Vous pouvez la faire précéder d’un commentaire décrivant son action. Dans ce cas, vous ne devrez utiliser que des commentaires sur une ligne, sinon ceux-ci ne s’afficheront jamais.

Une fois que vous avez la définition : vous pouvez l’appeler :

FunctionName( [[[ValeurArg1], ...,] ValeurArgN][,][[ValeurArgOpt1], ...,] ValeurArgOptN] ) ;

Par exemple :

Page 157: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

void Foo( int i, int j = 0, object = OBJECT_SELF ){ instruction ;}

Pour appeler Foo : Foo( 0 ) ; Foo( 0, 1 ) ; Foo( 0, 1, OBJECT_SELF ) ;

Mais pas : Foo( 0, OBJECT_SELF ) ; (Vous devez respecter l’ordre des arguments, même ceux qui sont optionnels)

Dans notre exemple, Foo ne renvoie rien : si vous tentiez de faire ceci :

int i = Foo( 1 ) ;

L’éditeur de script vous renverrait une erreur. Cependant, si Foo est définie ainsi :int Foo( int i, int j = 0, object = OBJECT_SELF ){ instruction ;}

Alors int i = Foo( 1 ) ; n’affichera plus d’erreur.

C’est à peu près tout ce qu’il y a à savoir sur les fonctions : ensuite, vous êtes libre de mettre ce que vous voulez dans votre fonction : par exemple, une fonction qui créerait 5 créatures à côté du joueur... etc.

Dans la section précédente nous vous avions parlé des fonctions récursives. Il s’agit de fonctions qui vont se rappeler elle-même :

void Foo( int i = 0 ){ if ( i < 100 ) Foo( ++i ) ; else instruction ;}

Cette fonction revient au même que faire :int i = 0 ; while ( ++i <= 100 ) continue ;instruction ;

L’existence des fonctions récursives est bonne à savoir, cependant vous ne devriez pas trop en avoir besoin dans vos NWScripts. Ces fonctions sont utiles pour par exemple « visiter » le contenu d’un répertoire.

C’est à peu près tout ce que vous avez à savoir sur les fonctions.

7. Les événements

Dans Neverwinter Nights les événements sont le fer de lance de vos scripts : ils vont vous permettre de lancer chacun de vos différents scripts (sauf les scripts d’inclusion, bien sûr).

Page 158: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

Lorsque vous utilisez un événement, celui-ci est attaché à un objet - représenté par la constante spéciale OBJECT_SELF : ne l’oubliez jamais, elle vous sera quasiment indispensable.

Les événements se découpent en fonction des types d’objets auquel vous avez affaire ; les différents types d’objets sont : zones, créature, portes, encounter, module, objets plaçables, pièges et triggers (déclencheurs).

Lorsqu’un événement se produit, il active automatiquement le script qui lui est lié.

a. Evénements liés aux zones :

- OnEnter : l’événement OnEnter se produit lorsqu’un objet rentre dans la zone. Vous pourrez obtenir l’objet qui vient de rentrer dans la zone avec la fonction GetEnteringObject() ;

- OnExit : cet événement se déclenche lorsque qu’un objet quitte la zone. Vous pourrez obtenir l’objet qui vient de sortir de la zone avec la fonction GetExitingObject().

- OnHeartBeat : cet événement se déclenche toutes les six secondes. Vous devez l’éviter au possible car celui-ci à une certaine tendance à rapidement saturer le processeur.

- OnUserDefined : il s’agit d’un événement plus ou moins défini par vous-même. Vous pourrez obtenir l’événement en cours avec GetUserDefinedEventNumber(). Nous ne sommes pas très sûrs du comportement de cet événement.

b. Evénements liés aux créatures :

- OnBlocked : cet événement se produit quand la créature est bloquée par une porte (et seulement par une porte). - OnCombatRoundEnd : cet événement se déclenche à chaque fin de round (toutes les 6 secondes dans

Neverwinter).- OnConversation : cet événement se produit chaque fois qu’une conversation se fini ou lorsqu’un cri est

entendu.- OnDamagedScript : cet événement se déclenche lorsque la créature est endommagée (ou blessée).- OnDeath : cet événement se produit lorsque la créature meurt quelque soit la raison.- OnDisturbed : cet événement se produit quand l’inventaire de la créature est perturbé. Par exemple, lorsqu’un

voleur tente de voler la créature.- OnHeartbeat : cet événement se déclenche à chaque round (soit toutes les 6 secondes). Il peut vous être utile

pour répéter une action, mais évitez d’utiliser trop de OnHeartBeat : cela ralentirai le PC. - OnPerception : cet événement se déclenche lorsque la créature perçoit une autre créature. Vous pouvez obtenir

le dernier objet perçu avec GetLastPerceved(). Neverwinter Nights fournit un ensemble de fonction qui vous permet de définir si la créature perçue a été vue, entendue, etc.

- OnPhysicalAttacked : cet événement se produit lorsque la créature est attaquée. Il ne se reproduit plus jusqu’à la fin de l’attaque.

- OnRested : cet événement se déclenche lorsque la créature tente de se reposer.- OnSpawn : ceci vous permet de définir une action par défaut pour la créature une fois qu’elle a été créee,

comme par exemple : attaquer les personnages d’alignement inverse.- OnSpellCastAt : cet événement se produit lorsqu’un sort a pour cible la créature porteuse du script

OnSpellCastAt.- OnUserDefined : il s’agit d’un événement plus ou moins défini par vous-même. Vous pourrez obtenir

l’événement en cours avec GetUserDefinedEventNumber(). Nous ne sommes pas très sûrs du comportement de cet événement.

c. Evénements liés aux portes

- OnAreaTransitionClick : cet événement se déclenche lorsque le joueur tente de changer de zone en cliquant sur la porte ; si vous définissez un script, alors vous devrez vous-même ajouter le code permettant au joueur de changer de zone.

- OnClose : cet événement se produit lorsque la porte est fermée.- OnDamagedScript : cet événement se déclenche lorsque la porte est endommagée.- OnDeath : cet événement se produit lorsque la porte est détruite quelque soit la raison. - OnFailToOpen : cet événement se produit lorsque la créature qui tente d’ouvrir la porte n’a pas réussi à

l’ouvrir. Ceci vous permet de faire venir un garde pour voir qui a tenté d’ouvrir la porte.- OnHeartbeat : cet événement se déclenche à chaque round (soit toutes les 6 secondes). Il peut vous être utile

pour répéter une action, mais évitez d’utiliser trop de OnHeartBeat : cela ralentirai le PC. - OnLock : cet événement se produit lorsque la porte est verrouillée.

Page 159: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

- OnOpen : cet événement est déclenché lorsque la porte est ouverte.- OnPhysicalAttacked : cet événement se produit lorsque la porte est attaquée. Il ne se reproduit plus jusqu’à la

fin de l’attaque.- OnSpellCastAt : cet événement se produit lorsqu’un sort a pour cible la porte porteuse du script

OnSpellCastAt.- OnUnlock : cet événement se déclenche lorsque la porte est déverrouillée. - OnUserDefined : il s’agit d’un événement plus ou moins défini par vous-même. Vous pourrez obtenir

l’événement en cours avec GetUserDefinedEventNumber(). Nous ne sommes pas très sûrs du comportement de cet événement.

d. Evénements liés aux encounters

- OnEnter : l’événement OnEnter se produit lorsqu’un objet rentre dans la zone délimitée par l’encounter. Vous pourrez obtenir l’objet qui vient de rentrer dans la zone avec la fonction GetEnteringObject() ;

- OnExhausted : cet événement démarre lorsque la dernière créature de l’encounter est crée.- OnExit : cet événement se déclenche lorsque qu’un objet quitte la zone délimitée par l’encounter. Vous pourrez

obtenir l’objet qui vient de sortir de la zone avec la fonction GetExitingObject().- OnHeartbeat : cet événement se produit toutes les 6 secondes. A éviter pour les mêmes raisons évoquées plus

haut.- OnUserDefined : il s’agit d’un événement plus ou moins défini par vous-même. Vous pourrez obtenir

l’événement en cours avec GetUserDefinedEventNumber(). Nous ne sommes pas très sûrs du comportement de cet événement.

e. Evénements liés aux modules

- OnAcquireItem : cet événement se déclenche lorsqu’un item a été obtenu par une créature (ou un placeable).- OnActivateItem : cet événement se produit lorsque un item a été activé. L’item ne doit pas forcément avoir la

capacité « Unique Power »- OnClientEnter : cet événement se déclenche lorsque un nouveau joueur rentre dans le module. Ceci peut vous

êtres très utile pour détruire des objets et avoir un personnage clean dés le début.- OnClientLeave : cet événement se produit lorsque un joueur quitte le module.- OnHeartbeat : cet événement se produit toutes les 6 secondes, et évidemment partout dans le module. Vous

devez éviter de mettre des scripts trop lourds dans cet événement-là.- OnModuleLoad : cet événement se produit lorsque le module est chargé pour la première fois. (Il se produit

lorsque le premier joueur arrive)- OnPlayerDeath : cet événement se produit lorsqu’un joueur meurt. Ceci vous permet de décider s’il doit

revivre, de faire un script laissant les objets du joueur par terre ... etc.- OnPlayerDying : cet événement se déclenche lorsque le joueur n’a plus que 0 points de vie (et pas -10 comme

dans le cas de l’événement OnPlayerDeath).- OnPlayerRespawn : cet événement se produit lorsque le joueur est mort et qu’il clique sur le bouton

« Respawn ».- OnPlayerRest : cet événement de déclenche quand un joueur se repose ; très utile pour lui envoyer quelques

ennemis... - OnUnAcquireItem : cet événement se produit lorsque le joueur perd un item (par exemple, il dépose une statue

en or, et des gens viennent l’attaquer pour la reprendre).- OnUserDefined : il s’agit d’un événement plus ou moins défini par vous-même. Vous pourrez obtenir

l’événement en cours avec GetUserDefinedEventNumber(). Nous ne sommes pas très sûrs du comportement de cet événement.

f. Evénements liés aux objets plaçables

- OnClose : cet événement se produit lorsque le plaçable est fermé.- OnDamagedScript : cet événement se déclenche lorsque le plaçable est endommagé.- OnDeath : cet événement se produit lorsque pour une quelconque raison le plaçable est détruit.- OnDisturbed : cet événement se produit lorsque l’inventaire du plaçable a été manipulé.- OnHeartbeat : ceci se produit toutes les 6 secondes (sauf si le plaçable est détruit). Comme pour les autres

types d’objets : évitez si possible de mettre un script pour cet événement.- OnLock : cet événement se déclenche lorsque le plaçable a été verouillé.- OnOpen : cet événement se produit lorsque quelqu’un ouvre le plaçable et fouille son contenu.

Page 160: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

- OnPhysicalAttacked : cet événement se déclenche lorsque quelqu’un « tape » le plaçable (par exemple, lorsque vous tentez d’ouvrir un coffre verrouillé en le détruisant à coup de projectiles magiques).

- OnSpellCastAt : cet événement se produit lorsqu’un sort est lancé sur le plaçable.- OnUnlock : cet événement se déclenche lorsque le plaçable est déverrouillé.- OnUsed : cet événement se produit lorsque le plaçable est utilisé. Servez vous en pour par exemple démarrer un

dialogue avec le plaçable.- OnUserDefined : il s’agit d’un événement plus ou moins défini par vous-même. Vous pourrez obtenir

l’événement en cours avec GetUserDefinedEventNumber(). Nous ne sommes pas très sûrs du comportement de cet événement.

g. Evénements liés aux pièges

- OnDisarm : cet événement se produit lorsque le piège est désarmé.- OnTrapTriggered : cet événement se produit lorsque le piège a été découvert.

h. Evénements liés aux triggers

- OnClick : cet événement se déclenche lorsqu’un joueur clique sur le trigger (si c’est un trigger « Area transition »).

- OnEnter : cet événement se déclenche lorsqu’une créature rentre dans la zone délimitée par le trigger. Utilisez GetEnteringObject() pour savoir quelle créature est rentrée.

- OnExit : cet événement se déclenche lorsqu’une créature quitte la zone délimitée par le trigger. Utilisez GetExitingObject() pour savoir quelle créature a quittée la zone.

- OnHeartbeat : cet événement se produit toutes les 6 secondes. Il peut être intéressant pour vérifier si une créature est encore dans la zone délimitée par le trigger, et pour l’avertir de quitter la zone (par exemple). Cependant, comme pour les autres types d’objets : cet événement a une tendance à surcharger le processeur, il vaut mieux éviter de s’en servir si possible.

- OnUserDefined : il s’agit d’un événement plus ou moins défini par vous-même. Vous pourrez obtenir l’événement en cours avec GetUserDefinedEventNumber(). Nous ne sommes pas très sûrs du comportement de cet événement.

8. La « norme »

Tout comme il existe une norme dans le langage humain, par exemple : ne pas mettre d’abréviations dans une lettre de motivation, il en existe aussi avec les langages de programmation.

Cette norme n’est pas forcément à suivre, mais si vous vous en servez, il se peut qu’elle vous facilite la vie, ou encore qu’elle facilite la vie de ceux qui passent après vous.

Cette norme a pour but de fixer quelques règles de codage :- Les variables locales : nous avons vu que nous pouvions avoir des variables de divers types,

cependant lorsque le code de la fonction est long, on ne sait plus trop qui contient quoi. C’est pour cela que vous devrez préfixer vos noms de variables d’une lettre (ou plus) en minuscule (en général) indiquant le type de la variable.

- Type : -Préfixe(s) : -Exemple : - action -a -aTuer- effect -e -eLigth- event -ev -evOnClose- float (nombre décimal) - f -fSecond- int (entier) - i -iNombre- int (utilisé comme des booléens (true, false))

-b -bTrue

- location - l -lAller- object -o -oTemple- string - s -sPlayerName

Page 161: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

- struct - str -strFX- talent - t -tSkillLock- vector -v -vVitesse

- A savoir aussi pour les noms de variables locales : il est d’usage d’utiliser une suite de majuscules/minuscules pour les nommer par exemple :

sPlayerName 

Ce qui représente le nom du joueur.

- Les variables globales : Neverwinter Nights ne nous permet pas de déclarer de vraies constantes, et nous devons utiliser les variables globales comme des constantes. Nous utiliserons aussi les règles usuelles pour les noms de constantes : Nous utiliserons donc les majuscules et le « _ ».

Par exemple : int VOLEUR_SKILL = 0 ;

- Indentation : votre code doit être indenté pour bien montrer jusqu’où vont les différents blocs. Si on considère ceci :

void main(){if ( condition ){ instruction ;}else if ( condition ){ instruction ; }}On y perd beaucoup en lisibilité. Imaginez un instant qu’il y ait beaucoup de blocs imbriqués... allez ensuite chercher l’erreur qui empêche le script d’être compilé : vous comprendrez que c’est assez dur de la trouver du premier coup. Cependant, en indentant de deux espaces tel que :

void main(){ if ( condition ) { instruction ; } else if ( condition ) { instruction ; }}

L’indentation révèle plus facilement les erreurs possibles. Pour les mêmes raisons, évitez le code de ce type-ci :

void main() { if ( condition ) { instruction ; } else if ( condition ) { instruction ; }}

Bien sur, il prend moins de place mais il est moins lisible...

Page 162: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

- Utilisation des booléens : Bioware n’a pas inclus de « vrais » booléens dans son script (pourtant, un vrai Booléen prend moins de place mémoire qu’un entier). Un booléen est, dans le cas des NWScript, un entier :

int bTrue = TRUE ;

Evitez les syntaxes de condition suivante :

bTrue == 1 bTrue != 1 bTrue == 0 bTrue != 0

Et préférez au choix l’utilisation suivante : bTrue == TRUE // ou bTrue (ex : if ( bTrue ) ) bTrue != TRUE // ou !bTrue bTrue == FALSE // ou !bTrue bTrue != FALSE // ou bTrue

- Fonctions : Les variables utilisées dans la fonction doivent être déclarée après la déclaration de la fonction (pour plus de lisibilité) par exemple :

void Foo(){ // Déclaration des variables int i, j, k, l ; string s1, s2, s3, s4 ; // autres instructions}

Aussi, évitez de mettre plusieurs instructions return dans vos fonctions : n’hésitez pas à passer par des variables auxiliaires.Au lieu de :

int Foo(){ if ( condition ) return TRUE ; else return FALSE ;}

Préférez ceci :

int Foo(){ int bReturn = FALSE;

if ( condition ) bReturn = TRUE ; else bReturn = FALSE ; // note ce else n’est pas utile dans ce cas // bReturn vaut par défaut FALSE ) return bReturn ;}

Page 163: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

9. Exercices

Bien, une fois que vous avez vu à peu près comment fonctionne le langage NWScript, on va pouvoir faire des exercices :

1. Cherchez les erreurs :

int a = 0; int b = 1; float c, d = 0.0f ;

- c = a + c- a = a * b- a = a / b- b = b / a- a = c + d

2. Quel est le problème dans ce code ?

void main(){ int i = 0 ;

while ( i == 0 ) continue ;}

3. Simplifiez : Soit a, b deux conditions.

if ( ( a || b ) && !( a && b ) ) if ( a ) instruction ; else if ( b ) instruction ;

Soit i, j deux entiers :

i = i +1 ; j = i * 3 ;

Soit a une condition et i, j deux entiers : if ( a )

j = i * 3 ; else if ( b ) j = i * 4 ;

4. Cherchez les erreurs : ici a est une conditionvoid Foo(){ int i , j , k = 10 ;

if ( I = j ) { i = j * k }

Page 164: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

else if ( a && i + j == k ) { break ; }

i = ( a ) k : i ;}

5. La fonction Foo est définie comme ci-dessous et doit normalement changer la valeur de la variable globale VAR_GLOBALE. Elle renvoie la valeur de cette même variable.

int VAR_GLOBALE = 1 ;int Foo(){ return VAR_GLOBALE ;

VAR_GLOBALE += 3 ;}Quelle est la valeur de VAR_GLOBALE ?

Voici la correction :

1. Cherchez les erreurs :- c = a + c : c est un nombre décimal, on peut donc lui ajouter une valeur entière.- a = a * b : il n’y pas de problème ici.- a = a / b : il n’y pas de problème ici.- b = b / a : ici, il ne s’agit que de maths, pas de type de variable : vous remarquerez que a vaut 0, et il est

impossible de diviser un nombre par 0.- a = c + d : a est un entier, on ne peut lui donner une valeur décimale. Dans ce cas, il faudrait se servir de

FloatToInt.

2. Le problème dans le code est que la boucle ne peut jamais se fermer ; il s’agit d’une boucle infinie.

3. Simplifiez : - On peut simplifier la condition ainsi :

if ( a && !b ) instruction ; else if ( !a && b ) instruction ;

- L’opération peut s’écrire ainsi : j = (++i) * 3 ;

- On peut réécrire l’opération sous deux formes :j = ( a ) ? (i * 3): (i * 4) ;ou :j = i;j *= ( a ) ? 3 : 4;

4. Cherchez les erreurs- « I » n’est pas la même chose que « i ». Ici vous auriez du déclarer et définir « I » ou changer I par i.- I = j : à supposer que I soit déclarée et définie : l’opération consistant à donner à I la valeur de j est tout le temps

vraie sauf en cas d’erreur. Ici, on aurait du utiliser le signe « == ».- Il manque un « ; » après le « k ».- Ce n’est pas une erreur, néanmoins :

( a && i + j == k )N’hésitez pas à mettre des parenthèses même si elles vous paraissent superflues :( ( a ) && ( ( i + j ) == k ) )Imaginez un instant que « a » soit une condition compliquée...

Page 165: Neverwinter Nights: Intro to the Toolset - Part 1sandrine.fabrice1.free.fr/toolsetintro.doc  · Web view2005-10-26 · NdT: Certains termes sont volontairement gardés en anglais

- Le « break » n’a rien à faire ici. Ce n’est pas une boucle ni un switch.- C’est sûrement une des erreurs les plus fréquentes dans l’utilisation des opérateurs ternaires : l’oubli du point

d’interrogation « ? » (ou du deux points « : »)

5. Ici, VAR_GLOBALE vaudra toujours « 1 » même après passage par Foo. Pour que VAR_GLOBALE soit changée il aurait fallu mettre le return VAR_GLOBALE après l’instruction « VAR_GLOBALE += 3 ».