La Bibliothèque de Neverwinter Nights
Aide et informations diverses sur Neverwinter Nights ainsi que D&D3.
La date/heure actuelle est 23/11/2024 19:45:39


  Page 1 sur 1 ¤

Voir le sujet précédent ¤ Voir le sujet suivant 
Auteur Message
Shan-Kuei
Novice
Inscrit le: 27 Avr 2005
Messages: 13
Répondre en citant
Posté le : 20/12/2005 17:20:02 Sujet du message : Ensemble plutôt balèze

Bonjour à tous,

Depuis quelques temps, j'ai une idée démente dans ma tête, mais je n'arrive pas à la poser sur le toolset. Je requiers de l'aide de la part d'âmes charitables et calées.

Description de la scène:

Une porte dissimulée. Si le joueur la trouve et l'emprunte, il débouche dans une nouvelle pièce (rien de bien extraordinaire jusque là). La nouvelle pièce possède deux personnes. Lorsque le joueur entre dans la zone, il déclenche un trigger. Ce trigger fait courrir le pnj2 vers un waypoint donnée avant de disparaitre. Dans sa course, il prononce une phrase à l'adresse du pnj1. Le pnj1 répond par une autre phrase, puis devient hostile au pj. Peu importe qui gagne, qui perd. Cependant, lorsque le pj quitte la zone, il faut que les deux pnjs reprennent leurs positions initiales, pour accueuillir d'éventuels autres joueurs. Il faut également un script de limitation. 1 seul pj dans la pièce au max.

Plutôt chaud, non ?
Résumé:
->Script de porte dissimulé
->Script scriptant la scène(Razz)
->Script de limitation
->Script de réinitialisation

Un grand merci pour ceux qui vont se pencher sur le problème(si ça intéresse quelqu'un) ou du moins qui vont essayer.
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Enki
Légende vivante
Inscrit le: 06 Déc 2005
Messages: 432
Répondre en citant
Posté le : 21/12/2005 17:03:38 Sujet du message :

Salut Shan-Kuei,je suis en train de faire un petit module de démo concernant ton problème, que je trouve intéressant. Dès qu'il est fini, je te donne les réponses à tes questions. Par contre, pour la porte dissimulée, j'ai pris des étagères comme tu ne précisais pas d'objet en particulier.
A plus.
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Shan-Kuei
Novice
Inscrit le: 27 Avr 2005
Messages: 13
Répondre en citant
Posté le : 21/12/2005 20:48:16 Sujet du message :

Merci de ta réponse rapide !
J'attend ton petit Mod avec impatiencce Smile
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Enki
Légende vivante
Inscrit le: 06 Déc 2005
Messages: 432
Répondre en citant
Posté le : 22/12/2005 04:08:34 Sujet du message : Explications

Bonsoir à tous,
suite à une discussion avec Shan-Kuei et à un petit module de démo que je lui ai fait parvenir, et après les critiques et les corrections que ce dernier a formulé, nous avons décidé ensemble qu'il serait peut-être utile à tous que je présente ces scripts et que j'explique en deux mots comment faire la scène décrite par Shan-Kuei. Pardon par avance aux super-cracks du scriptage, cela fait peut de temps que je suis sur ce forum et je ne connais pas le niveau de ses membres (j'ai moi-même un niveau trés moyen Crying or Very sad ) donc je donne un maximum de détails.
Pour ce faire :
- Il vous faut d'abord trois zones, peu importe leurs types ou leurs tags.
- Il faut deux pnj dans la palette, mais pas dans une des zones du module. Le tag des pnj, pour être conformes à ceux que je vais utiliser dans les scripts que vais poster doivent être les suivants. "mechant" et "PNJ02" leurs resrefs doivent être les même mais en minuscules pour "pnj02".
1) dans la zone 1, où arrive les PJs, il doit y avoir un placeable quelconque, par cohèrence j'ai pris une étagère-bibliothèque. Il faut que cette étagère soit utilisable, intrigue, sans inventaire et qu'elle ai un dialogue. Pour que ce dialogue soit utilisé, il faut mettre dans le OnUsed le script suivant que tous le monde connait :
NWScript :Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.

Je le remets juste au cas où !
Les astérisques dans les dialogues renvoient à des scripts.
Le dialogue est trés important, il doit contenir 4 branches :

004 - Fouiller cette étagère ?
003 - Il y a un mécanisme qui actionne une porte secrète. Voulez-vous l'utiliser ?
002 - Il y a un mécanisme qui actionne une porte secrète. Voulez-vous l'utiliser ?
001 - Fouiller cette étagère ?


C'est la dernière qui apparait en premier, du moins si toutes les conditions des autres ont été évaluées comme fausses.
Je vais mettre des numéros pour indiquer à quelle branche se raporte telle ou telle réponse.
je vais la développer :

001 - Fouiller cette étagère ?
01 - Oui.
02 - Il y a un mécanisme qui actionne une porte secrète. Voulez-vous l'utiliser ? *
03 - Oui. **
03 - Non.

02 - Il n'y a rien de spécial.
01 - Non.

* dans les conditions :
NWScript :
#include "nw_i0_tool"
int StartingConditional()
{
 
  if(!(AutoDC(DC_EASY, SKILL_SEARCH, GetPCSpeaker())))
    return FALSE;
  return TRUE;
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.


On fait un jet de fouille, si on le veut plus dur, on change DC_EASY par DC_HARD ou DC_MEDIUM.
* dans le actions conséquentes :
NWScript :
void main()
{
 
  SetLocalInt(GetPCSpeaker(), "fouille", 100);
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.


On inscrit une variable sur le pc qui fait que s'il répond non, il n'est pas obligé de retenter un jet de fouille, il a trouvé l'intérupteur caché. La prochaine fois qu'il utilise l'étagère, il ira direct à la branche 002.
** S'il répond Oui. alors dans les conséquences :
NWScript :
void main()
{
  object oEntre=GetWaypointByTag("entre");
  SetLocalInt(GetModule(),"occupe",100);
  AssignCommand(GetPCSpeaker(),ActionJumpToObject(oEntre));
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.

le PJ est téléporté dans la 2e zone sur un waypoint dont le tag est "entre".
En outre, une variable locale est inscrite sur le module, qui fait que tout autre PJ qui trouve l'intérupteur, ne peut accéder à la pièce secrète, c'est le script de limitation que m'avait demandé Shan-Kuei. Car le pj numéro 2 (ou plus), qui utilise le placeable sera devant la branche 004 du dialogue, qui est une copie de la 001, à l'exception du fait que si le PJ répond "oui" à la question 02 - Il y a un mécanisme qui actionne une porte secrète. Voulez-vous l'utiliser ? *il aura comme réponse tant que le pj 1 ne sera pas sortie de la zone (vivant ou mort) : 04 - Le mécanisme semble comme bloqué de l'intérieur.

Passons à la zone 2.
Pour aérer, je fais un nouveau post par zone.
Dernière édition par Enki le 23/12/2005 14:06:20; édité 1 fois
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Enki
Légende vivante
Inscrit le: 06 Déc 2005
Messages: 432
Répondre en citant
Posté le : 22/12/2005 05:21:33 Sujet du message : La zone 2

La zone 2 se compose de 4 déclencheurs, 4 Waypoints et deux placeables.
En premier lieu il faut remettre une étagère pour indiquer que l'on vient bien de la porte secrète, devant on met un waypoint avec le tag "entre". Sur l'étagère, on met un dialogue simple qui dit que le mécanisme est bloqué par exemple. Cela empêche le Pj de revenir sur ses pas ...
Devant le waypoint mais pas dessus, on met un déclencheur de sorte que le PJ soit obligé de marcher dessus avec ce script sur le onEnter :
NWScript :
void main()
{
object oPC=GetEnteringObject();
object wPNJ01= GetWaypointByTag("way01");
object wPNJ02= GetWaypointByTag("way02");
location lPNJ01=GetLocation(wPNJ01);
location lPNJ02=GetLocation(wPNJ02);

    if (GetLocalInt(oPC,"NW_DO_ONCE01") != 0)
    {
      return;
    }
  SetLocalInt(oPC,"NW_DO_ONCE01",1);
  SetLocalInt(oPC,"fouille",200);

    CreateObject(OBJECT_TYPE_CREATURE,"mechant",lPNJ01);
    CreateObject(OBJECT_TYPE_CREATURE,"pnj02",lPNJ02);
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.

Ce script créé les 2 Pnj préalablement édités dans la palette, à l'emplacement des 2 waypoints dont les tags sont respectivement "way01" et "way02". Je suggere de mettre ces waypoints assez loin du lieu d'arrivée du PJ, de sorte qu'il ne les voit pas apparaitre.
NWScript :
if (GetLocalInt(oPC,"NW_DO_ONCE01") != 0)
    {
      return;
    }
  SetLocalInt(oPC,"NW_DO_ONCE01",1);
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.

Cette portion du script s'assure que si le PJ marche à nouveau sur le déclencheur, il n'entraine pas la création de 2 autres PNJ.

NWScript :
SetLocalInt(oPC,"fouille",200);
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.

Cette portion du script empêche le PJ de revenir dans cette zone s'il est victorieux du méchant ou s'il meurt. Cela le renvoi à la branche 003 du dialogue de la première étagère, avec comme condition :
NWScript :
int StartingConditional()
{
  // Inspecter variables locales
  if(!(GetLocalInt(GetPCSpeaker(), "fouille") == 200))
    return FALSE;
  return TRUE;
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.

Dans ce cas, s'il répond oui à la question - Il y a un mécanisme qui actionne une porte secrète. Voulez-vous l'utiliser ? on lui dira : Le mécanisme semble comme bloqué de l'intérieur.

A quelque distance du 1er déclencheur, il faut mettre le 2e.
Celui là va initier un dialogue ou du moins donner l'impréssion d'un dialogue entre les 2 pnj.
toujours dans le onenter :
NWScript :
void main()
{
object oPC=GetEnteringObject();
object oPNJ01= GetObjectByTag("mechant");
object oPNJ02= GetObjectByTag("PNJ02");
  if (GetLocalInt(oPC,"NW_DO_ONCE02") != 0)
    {
      return;
    }
  SetLocalInt(oPC,"NW_DO_ONCE02",1);
  DelayCommand(1.0,AssignCommand(oPNJ02,SpeakString("")));
  DelayCommand(3.0,AssignCommand(oPNJ01,SpeakString("")));
  DelayCommand(5.0,AssignCommand(oPNJ02,SpeakString("")));
  DelayCommand(6.5,AssignCommand(oPNJ01,SpeakString("C'est bien mon fils, je t'ai toujours dit de ne pas te laisser faire ! ")));
          }
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.

Ce script se passe de commentaire.

Toujours un peu plus loin, on met le 3e déclencheur, dans le OnEnter :
NWScript :
void main()
{
object oPC=GetEnteringObject();
object oPNJ01= GetObjectByTag("mechant");
object oPNJ02= GetObjectByTag("PNJ02");
object oFuite=GetWaypointByTag("fuite");
    if (GetLocalInt(oPC,"NW_DO_ONCE03") != 0)
    {
      return;
    }
  SetLocalInt(oPC,"NW_DO_ONCE03",1);
  AssignCommand(oPNJ02,ClearAllActions(TRUE));
  AssignCommand(oPNJ01,ClearAllActions());
  AssignCommand(oPNJ02,ActionForceMoveToObject(oFuite,TRUE,0.0f));
  DelayCommand(0.5,AssignCommand(oPNJ02,SpeakString("AU SECOUR PAPA, c'est ce monstre qui voulait me voler mon casse-croute !!")));
  ClearPersonalReputation(oPC,oPNJ02);
  SetIsTemporaryEnemy(oPC,oPNJ01);
  DelayCommand(1.5,AssignCommand(oPNJ01,SpeakString("")));
  DelayCommand(2.5,AssignCommand(oPNJ01,ActionAttack(oPC)));
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.

Le pnj "mechant" attaque alors le PJ et on oblige le PNJ2 à s'enfuir au waypoint dont le tag est "fuite", que l'on aura préalablement placé près d'une trappe et sous lequel on aura mis le 4e déclencheur, dont dépend toute l'astuce qui suit.
En effet, j'ai rencontré un bug que je n'ai pu m'expliquer, soit c'est le jeu, soit plutôt, mes mauvaises connaissances en script. Je voulais que le PNJ2 soit détruit en entrant dans ce trigger, mais en fait il était détruit ainsi que le pnj au tag de "mechant", ayant cherché pendant une heure et demi (et sans résultat Mad ) la cause d'un tel bug, j'ai trouvé un subterfuge, que l'on pourrait encore améliorer. Au moment où le PNJ2 entre dans le 4e trigger, ce script se déclenche le rendant invisible :
NWScript :
#include "NW_I0_GENERIC"
void main()
{
object oNPC=GetEnteringObject();
object oDestroy=GetObjectByTag("PNJ02");
  effect eEffect=EffectInvisibility( INVISIBILITY_TYPE_NORMAL);
if (GetTag(oNPC)==GetTag(oDestroy))
{
  ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oNPC);
}
  }
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.


on pourrait peut-être si nécessaire lui appliquer un effet de paralysie en plus, à voir.

Enfin, on arrive au noeud du problème, faire en sorte que si le PJ gagne le combat, (ce qui est souhaitable), une petite animation, basique dans cet exemple, mais qui peut être embellie, se délenche.

1) D'abord il faut éditer (dans une copie) le script onSpawn de notre PNJ "mechant". et enlever les commentaires de cette ligne (239) :
NWScript :Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.


puis on créé un nouveau script dans le user defined du PNJ avec ce code :
NWScript :
void main()
{
    int nUser = GetUserDefinedEventNumber();

    if(nUser == 1001) //HEARTBEAT
    {

  object oPC=GetLastHostileActor();
  object oEntre=GetWaypointByTag("sort");


      if (GetCurrentHitPoints()<=10)
      {
              if (GetLocalInt(oPC,"mort") != 0)
    {
      return;
    }

  SetLocalInt(oPC,"mort",1);
  SetCutsceneMode(oPC,TRUE);

  SpeakString("Avant de mourrir, je vais te lancer un sort !!");
  effect eEffect= EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3);
  ApplyEffectToObject(DURATION_TYPE_INSTANT,eEffect,oPC);

  DelayCommand(1.5,PlayAnimation(ANIMATION_LOOPING_DEAD_BACK,1.0,2.0));

  DelayCommand(3.0,AssignCommand(oPC,JumpToObject(oEntre)));
  DelayCommand(3.0,SetCutsceneMode(oPC,FALSE));

              }
}
    }
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.


Il est impératif que le PNJ soit immortel mais pas intrigue dans ses propriétés. Il donnera l'impréssion de mourrir, mais juste avant, il lancera un sort qui téléportera le PJ au waypoint dont le tag est "sort" et qui se situe dans la zone 3. Encore une ou deux précision et j'ai fini ( ouf ! ).
Il faut remarquer ici que puisque le PNJ ne meurt pas vraiment, le pj n'aura aucun point d'XP, il faut donc le rajouter dans le code précédent.
Enfin, Il ne faut surtout pas oublier de mettre dans le onExit de la zone deux le script suivant pour détruire les PNJ pour que le procahin PJ qui entre dans cette zone en ai bien 2 en face de lui et pas 4.
NWScript :
void main()
{
  SetLocalInt(GetModule(),"occupe",0);
  object oPNJ01= GetObjectByTag("mechant");
  object oPNJ02= GetObjectByTag("PNJ02");
  DestroyObject(oPNJ01,0.5f);
  DestroyObject(oPNJ02,0.5f);
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.


Là aussi, la variable du module "occupe" doit être remise à zéro, pour dire que la zone est libre, et que les autres PJ ayant trouvé la porte secrète puisse enfin entrer.
Voilà, je crois n'avoir rien oublié, j'espère que ces explications (un peu pompeuses, je le reconnais) auront répondu à tes attentes Shan-Kuei, ainsi qu'à celles des autres scripteurs que nous sommes.
A bientôt !
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Shan-Kuei
Novice
Inscrit le: 27 Avr 2005
Messages: 13
Répondre en citant
Posté le : 22/12/2005 17:41:15 Sujet du message :

Un excellent boulot Enki.

Il y a eu quelques modifications depuis l'idée que j'avais formulé dans le premier post, en particulier la téléportation. Mais c'est pas gênant pour un sou, et rend plutôt bien dans le cadre d'une quête.

Le Monsieur au-dessus a extrêmement bien expliqué la partie technique de la scène. Adaptable n'importe où, il suffit juste de changer les dialogues incluts dans le script pour des soucis de cohérence Very Happy
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Montrer les messages depuis :
Page 1 sur 1 ¤


Vous ne pouvez pas poster de nouveaux sujets dans ce forum
Vous ne pouvez pas répondre aux sujets dans ce forum
Vous ne pouvez pas éditer vos messages dans ce forum
Vous ne pouvez pas supprimer vos messages dans ce forum
Vous ne pouvez pas voter dans les sondages de ce forum


Sauter vers:
FAQ | Rechercher | Liste des Membres | Groupes d'utilisateurs | S'enregistrer | Profil | Se connecter pour vérifier ses messages privés | Connexion
Powered by phpBB 2.* [m] © 2001, 2002 phpBB Group
Theme rewritten in beautiful XHTML code by Baldurien.
Thème "La Bibliothèque de Neverwinter" crée par Kruger
Traduction par : phpBB-fr.com
Page generated in 61.029ms