Scripting Tutorial: How Do I Make My NPC's Initiate Dialogue On Their Own?
Tutorial de Script : Comment faire pour que mon PNJ engage la conversation de lui même ?
par David Gaider
OK, premièrement : tant que vous ne savez pas EXACTEMENT ce que vous faites, ne toucher PAS au script qui est normalement dans l'événement OnPerception ("nw_c2_default2"). Laissez-le tranquille. Si quelqu'un vous dit de modifier quelque chose des scripts OnSpawn et OnUserDefined pour vos PNJs et que vous ne vous sentez pas pour le faire, dites lui qu'il est plein de monkeypoo (Note du traducteur : je ne sais pas ce que c'est que cette histoire de singe mai ça a pas l'air gentil !!)
Comme c'est dit avant, ici, concernant les événements UserDefined, l'IA est installée pour vous permettre d'employer ces événements sans changer le script de base.
Utilisons OnPerceive pour lancer la conversation.
1) Allez dans le script OnSpawn. Sauvegardez le sous un nouveau nom. Maintenant allez à la ligne où il est écrit SetSpawnInCondition(NW_FLAG_PERCEIVE_EVENT);
et décommentez le (enlevez les '//' double slashe au début de la ligne). Compilez le nouveau script.
2) Dans le fichier de dialogue de votre PNJ, allez à la première ligne de dialogue avec le PJ. Si vous voulez qu'il le fasse avec n'importe quel PJ une seule fois, insérer ceci dans Actions Taken :
void main()
{
SetLocalInt(GetPCSpeaker(), "Dlg_Init_" + GetTag( OBJECT_SELF), TRUE);
}
Ceci place la variable qui est employée dans le script utilisé, ainsi le dialogue n'est pas fait plus d'une fois.
3) Maintenant créez un nouveau script dans l'événement OnUserDefined pour votre PNJ. Vous pouvez insérer ce second script directement à l'intérieur.
void main()
{
int nEvent = GetUserDefinedEventNumber();
if (nEvent == 1002)
{
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);
}
}
}
INCONVENIENTS POSSIBLES : Maintenant... une raison pour laquelle ceci peut ne pas fonctionner ? Si le joueur commence le jeu en vue du PNJ, il n'y a pas événement OnPerceive. L'événement se déclenchera uniquement si le joueur était invisible pour le PNJ et l'est devenu ensuite.
Utilisation des Trigger pour lancer une conversation.
C'est ce que nous utilisons dans la campagne officielle. Cela permet de déterminer à partir de quelle distance le PNJ courra vers le PJ, et également sur quelle distance le NPJ courra après le PJ avant d'abandonner.
Pour établir ceci vous devez faire ce qui suit :
1) Comme dans le #2 précédent, dans le fichier de dialogue du PNJ, allez à la toute première ligne où le dialogue commence avec le PJ. Si vous voulez qu'il le fasse une seule fois par PJ rajoutez le script suivant (même que #2) dans action taken :
void main()
{
SetLocalInt(GetPCSpeaker(), "Dlg_Init_" + GetTag( OBJECT_SELF), TRUE);
}
2) Allez à votre zone. Posez un waypoint à l'endroit où le PNJ reviendra. Nommez le "WP_RETURN_" + le tag du PNJ. (si le tag est 'Fred', nommez le "WP_RETURN_Fred". Rappelez vous que tous les Tags sont sensibles à la casse ! (nota: la casse correspond aux majuscules et aux minuscules. Ainsi, dans les NWScript a n'est pas la même chose que A.)
3) Pendant que vous êtes dans la zone, créez un Trigger generique et dessinez un polygône avec, autour de votre PNJ. Quand le PJ traversera la zone, le PNJ va commencer à courir à la rencontre du PJ. Si le PJ sort de la zone, il arrêtera de poursuivre le PJ et reviendra au Waypoint.
4) Allez sur l'onglet Scripts du Trigger et ajoutez le script suivant dans le champ OnEnter :
void 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));
}
}
5) Maintenant vous voulez empêchez le PNJ de courir après le PJ si il sort de la zone. Entrez donc ce script dans l'événement OnExit :
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 s'occupe pas de savoir si le PJ est visible ou pas... si il traverse la zone, il va activer le PNJ. Si vous voulez être sur que le PNJ voie le PJ, ajoutez cette ligne juste en-dessous de if ( GetIsPC( oPC ) &&
dans le script de l'événement OnEnter :
GetObjectSeen(oPC, oNPC) &&
Ceci dit, dans une partie multi-joueur, le PNJ va essayer de parler à chacun des joueurs de cette façon. Si vous voulez qu'il ne parle qu'à un seul joueur faites ce qui suit :
1) Dans le script du dialogue, remplacez GetPCSpeaker()
par OBJECT_SELF.
2) Dans le script OnUserDefined (première méthode) ou dans le script OnEnter (deuxième méthode), remplacez 'oPC' dans la commande GetLocalInt par 'oNPC'.