You are on page 1of 5

How Do I Make My NPC's Initiate Dialogue On Their Own?

Intended Audience:
By David Gaider
[Printer Friendly / Syntax Highlight]
OK, first off: until you know EXACTLY what you are doing, do NOT alter the script that
is normally in the OnPerception event ("nw_c2_default2"). Leave it alone. If anyone tells
you to alter anything but the OnSpawn and OnUserDefined scripts for you NPCs and you
aren't confident of doing so, tell them they're full of monkeypoo.
As mentioned earlier, here, regarding UserDefined events, the generic AI is set up to
allow you to use these events without altering the default scripting.
Using the OnPerceive method of starting conversation //In the NWN1 OC, they used
Trigger method for starting conversations, and not this one.
1) Go into your OnSpawn script. Save it under a new name. Then go down to the line
where it says 'SetSpawnInCondition (NW_FLAG_PERCIEVE_EVENT);' and
uncomment it (remove the '//' double slashes at the beginning of the line). Compile the
new script.
2) In your NPC's dialogue file, go to the very first line where he starts his dialogue with
the PC. If you only want him to start this with any given PC once, add the following
script into 'Actions Taken':
NWScript: //in NWN2 toolset, there is an option in dialog editor for this like Show
Once
----------------void main()
{
SetLocalInt(GetPCSpeaker(), "Dlg_Init_" + GetTag(OBJECT_SELF), TRUE);
}
----------------

This sets the variable that is used in the script you were using, so the dialogue isn't done
more than once.
3) Now create a new script in the OnUserDefined event for your NPC. You can put that
second script in here, as follows:
NWScript:
------------

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);
}
}
}
-------------------

POSSIBLE DRAWBACK: Now... one reason why this may not work? If your PC starts
the game visible to this NPC, there is no OnPerceive event. The event only fires if the PC
was previously non-perceived and then became perceived.
Using the Trigger Method for starting a Conversation
This is the one we use in the official campaign. It allows you to control at which point the
NPC will run up to the PC, and also determine how far the NPC will run after the PC
before giving up.
To set this up, you need to do the following:
1) Like as in #2 above, in your NPC's dialogue file, go to the very first line where he
starts his dialogue with the PC. If you only want him to start this with any given PC once,
add the script from #2 above into 'Actions Taken':
NWScript:
-----------void main()
{
SetLocalInt(GetPCSpeaker(), "Dlg_Init_" + GetTag(OBJECT_SELF), TRUE);
}
--------------

2) Go into your toolset. Put down a waypoint at the spot where your NPC will return to.
Label it "WP_RETURN_" + the tag of the NPC. (so if the tag is 'Fred', label it
"WP_RETURN_Fred". Remember that all tags are case-sensitive! //Tried this in Moj
Modul 3, on greycloak, but he didnt return to that waypoint. Update: Solution to this is
bellow, and it works
3) While in the toolset, create a new generic trigger and draw a polygon around your
NPC. When the PC crosses into this area, the NPC will start running toward the PC to
talk. If the NPC leaves this area, he will stop chasing the PC and return to the waypoint.
4) Go to the trigger's 'Scripts' tab and include the following script under 'OnEnter':
NWScript: //in NWN2 there is speaktrigger, and it already has the necessary script in
it, so there is no need for this script below (except maybe in some special cases i dont
know about yet)
------------// this is the on enter script if a trigger that
// encompasses the NPC who will be initiating dialouge.
// Make sure to replace "NPC_TALKER" with the actual tag of the NPC
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) Now you want to prevent the NPC from chasing after the PC. Enter the following
under the trigger's OnExit event:
NWScript:
---------------// This will return the NPC to a starting position
// if he attempts to leave the trigger.

// You must replace "NPC_TALKER" with the tag of the NPC.


// You must also have a waypoint with the tag "WP_RETURN_" + NPC's Tag.
// This should be placed in the spot the NPC starts at.
void main()
{
string sTag = "NPC_TALKER";
object oExit = GetExitingObject();
if(GetTag(oExit) == sTag)
{
AssignCommand(oExit,ClearAllActions());
AssignCommand(oExit,ActionMoveToObject(GetNearestObjectByTag("WP_RETURN_
" + sTag)));
}
}
---------------------------------------^Modification of the above script(i made this script below):
-----//Can be placed on End Dialog node of conversation, under actions
//Can be used when NPC runs to meet you(commanded by Speak Trigger), to later return
to his spot, - to waypoint named WP_RETURN_+tag of the NPC
void main()
{
string sTag = GetTag(OBJECT_SELF);
AssignCommand(OBJECT_SELF,ClearAllActions());
AssignCommand(OBJECT_SELF,ActionMoveToObject(GetNearestObjectByTag("WP_
RETURN_" + sTag)));
SetFacing(90.0f, FALSE); //instead of 90.0f, set orientation that you want. For
example original orientation of the NPC from his properties window
}
-----------This method doesn't care if the PC is visible or not... crossing into the trigger will cause
the NPC to initiate. If you want to make sure that the NPC sees the PC, add the following
line immediately under 'if(GetIsPC(oPC) &&' in the OnEnter script:
GetObjectSeen(oPC, oNPC) &&

As well, in a multiplayer game, the NPC will attempt to talk to each and every player at
least one with this method. If you only want him to run up to one PC EVER, then do the
following:
1) In the dialogue script, replace 'GetPCSpeaker()' with 'OBJECT_SELF'.
2) In the OnUserDefined script (in the first method) or the OnEnter script (in the second
method), replace the 'oPC' in the GetLocalInt command to 'oNPC'.

You might also like