RPGDialog - NPC interaction system
by Nelson A. K. Gonsalves · 11/29/2002 (12:27 pm) · 186 comments
RPGDialog is a Torque Game Engine modification that adds standard RPG Dialogs support, including multiple choice questions and question linking(underlined words on a question that perform actions when clicked on). Also included is an editor for creating and editing dialogs easily.
Instructions on installing are included on the zip file.
New download location since geocities is dead
Have fun using it! :)
And let me know of any problems you might find.
Contact me at dk_uo@yahoo.com or leave a comment here.
Features
- Multiple choice questions, present a question and a list of answers and do something depending on which answer the player picks, the choices are numbered and can be picked either by the mouse or by pressing the 1,2,...,9,0 keys on the keyboard, choices after 10 must be selected via mouse.
- Question Links, Ex: "Hello, I'm Mary, how are you?" clicking on the word Mary would trigger an action as if it was a choice in the Multiple choice window.
- Portraits, pictures that represent the NPC, change it depending on the choices of the player or even use them to show the mood of the NPC.
- Sounds, add voice overs or any sound effects that are triggered when the question is displayed.
- Fully functional in multiplayer games, only allowing one player to talk to each NPC at a time, sending a message telling the others that the NPC is busy if they try to talk to it.
- Moving the player too far away from the NPC closes the Dialog automatically.
- Each option triggers a function, allowing complete customization of the actions caused by the dialog, either by using the included functions, altering them or creating your own.
June 8th 2005.
I finnaly got around to giving this a much deserved update!
Firstly I updated the instructions and made a few changes to make it fully compatible with TGE 1.3.
Also I've added buttons to move the answers up and down in the editor, so its now easier to organize the available options.
And finnaly, multiple actions can now be triggered by one response, thanks goes to BrokeAss Games for the idea. To execute multiple actions just add them one after the other without anything separating them, there is one example of this in the test scripts. Ohh, and now clicking on the actions list will add them to the actions edit and not replace them.
I have one warning though, version 1.0 .dla files are incompatible with version 1.3, there is an easy workaround I've used on my files, just open them directly in a text editor and do a quick replace all from "<" to "<END><", add <END> to the end of each line and remove the <END> from the beginning of the line, that should make them 100% compatible.
Let me know if you find any problems.
-Nelson
Instructions on installing are included on the zip file.
New download location since geocities is dead
Have fun using it! :)
And let me know of any problems you might find.
Contact me at dk_uo@yahoo.com or leave a comment here.
Features
- Multiple choice questions, present a question and a list of answers and do something depending on which answer the player picks, the choices are numbered and can be picked either by the mouse or by pressing the 1,2,...,9,0 keys on the keyboard, choices after 10 must be selected via mouse.
- Question Links, Ex: "Hello, I'm Mary, how are you?" clicking on the word Mary would trigger an action as if it was a choice in the Multiple choice window.
- Portraits, pictures that represent the NPC, change it depending on the choices of the player or even use them to show the mood of the NPC.
- Sounds, add voice overs or any sound effects that are triggered when the question is displayed.
- Fully functional in multiplayer games, only allowing one player to talk to each NPC at a time, sending a message telling the others that the NPC is busy if they try to talk to it.
- Moving the player too far away from the NPC closes the Dialog automatically.
- Each option triggers a function, allowing complete customization of the actions caused by the dialog, either by using the included functions, altering them or creating your own.
June 8th 2005.
I finnaly got around to giving this a much deserved update!
Firstly I updated the instructions and made a few changes to make it fully compatible with TGE 1.3.
Also I've added buttons to move the answers up and down in the editor, so its now easier to organize the available options.
And finnaly, multiple actions can now be triggered by one response, thanks goes to BrokeAss Games for the idea. To execute multiple actions just add them one after the other without anything separating them, there is one example of this in the test scripts. Ohh, and now clicking on the actions list will add them to the actions edit and not replace them.
I have one warning though, version 1.0 .dla files are incompatible with version 1.3, there is an easy workaround I've used on my files, just open them directly in a text editor and do a quick replace all from "<" to "<END><", add <END> to the end of each line and remove the <END> from the beginning of the line, that should make them 100% compatible.
Let me know if you find any problems.
-Nelson
#42
Second i found that the InitContainerRadiusSearch() method in serverCmdRPGDialogRay() for finding NPCs was inconsistent. It seemed not to work in many cases where it should. So i replaced it with ContainerRayCast(). Now it's works 100% of the time that i aim at the NPC i want to look at and he's in range. I'm also adding an NPC chat in range cursor now as it helps visualize the results of serverCmdRPGDialogRay() better for both me as the designer and the player.
04/23/2005 (2:42 pm)
Well there are two issues there.... if it can't find the TalkTo() function you're either not exec'ing it or you have an error in the code. Look in the console for red error spew from some script file not compiling.Second i found that the InitContainerRadiusSearch() method in serverCmdRPGDialogRay() for finding NPCs was inconsistent. It seemed not to work in many cases where it should. So i replaced it with ContainerRayCast(). Now it's works 100% of the time that i aim at the NPC i want to look at and he's in range. I'm also adding an NPC chat in range cursor now as it helps visualize the results of serverCmdRPGDialogRay() better for both me as the designer and the player.
#43
A couple of points:
1. The search radius used for the InitContainerRadiusSearch calls is way too small. 0.5 means that the crossbow in starter.fps has to penetrate the NPC to be close enough for dialog. Could lead to some interesting conversations... :)
At a minimum, the initial test in serverCmdRPGDialogRay needs the radius changed from 0.5 to 2.5, in IsRPGDialogBusy change it to 5, and in CheckRPGDialogStatus change it to 5.
2. Also in starter.fps/server/scripts/RPGDialog.cs, LightMaleHumanArmor can be changed to DemoPlayer for the starter.fps game.
@ari - your snippets for multiple actions per response are great, just what I needed.
05/10/2005 (10:27 am)
Wow, what a great resource. Just applied it to my custom 1.3 starter.fps (with AdvancedCamera, Factions, NPCs and improved crosshairs) and I've got a strong basis for an RPG already.A couple of points:
1. The search radius used for the InitContainerRadiusSearch calls is way too small. 0.5 means that the crossbow in starter.fps has to penetrate the NPC to be close enough for dialog. Could lead to some interesting conversations... :)
At a minimum, the initial test in serverCmdRPGDialogRay needs the radius changed from 0.5 to 2.5, in IsRPGDialogBusy change it to 5, and in CheckRPGDialogStatus change it to 5.
function serverCmdRPGDialogRay(%client)
{
%StartPos=%client.player.gettransform();
%Eye = %client.player.getEyeVector();
%EndPos = vectorScale(%Eye, -1);
%EndPos = vectorsub(%StartPos,%EndPos);
InitContainerRadiusSearch(%EndPos, 2.5, $TypeMasks::PlayerObjectType);
%rayCast=ContainerSearchNext();
while(%rayCast != 0 )
{
if(%rayCast.aiPlayer && %rayCast.RPGDialogScript!$="")
{
if(!%rayCast.RPGDialogBusy)
{
RPGDialogMessageClient(%client, %rayCast, %rayCast.RPGDialogScript,%rayCast.RPGDialogStartQuestion); //start dialog.
return;
}
else
{
if(IsRPGDialogBusy(%rayCast))
{
if(%client!=%raycast.RPGDialogTalkingTo)
{
messageClient(%client, '', %rayCast.RPGDialogBusyText, %raycast.RPGDialogTalkingTo.player.getShapeName());
return;
}
else
return;
}
else
{
RPGDialogMessageClient(%client, %rayCast, %rayCast.RPGDialogScript,%rayCast.RPGDialogStartQuestion); //start dialog.
return;
}
}
}
%rayCast=ContainerSearchNext();
}
}
function IsRPGDialogBusy(%AiPlayerID)
{
InitContainerRadiusSearch(%AiPlayerID.getTransform(), 5, $TypeMasks::PlayerObjectType);
%rayCastBusyCheck=ContainerSearchNext();
while(%rayCastBusyCheck != 0 )
{
if(%rayCastBusyCheck==(%AiPlayerID.RPGDialogTalkingTo).player)
{
return(true);
}
%rayCastBusyCheck=ContainerSearchNext();
}
return(false);
}
function CheckRPGDialogStatus(%Client,%Sender) //Checks if the player has moved since he started the dialog, moving too far from the sender will cancel the dialog
{
InitContainerRadiusSearch(%Sender.getTransform(), 5, $TypeMasks::PlayerObjectType);
%rayCast=ContainerSearchNext();
while(%rayCast != 0 )
{
if(%rayCast==%Client.player)
{
schedule(1000,0,"CheckRPGDialogStatus",%Client,%Sender);
return;
}
%rayCast=ContainerSearchNext();
}
CommandToClient(%client,'CloseRPGDialog');
%Sender.RPGDialogBusy=false;
%Sender.RPGDialogTalkingTo=0;
%Sender.clearAim();
}2. Also in starter.fps/server/scripts/RPGDialog.cs, LightMaleHumanArmor can be changed to DemoPlayer for the starter.fps game.
function SpawnTestNPC()
{
%player = new AIPlayer() {
dataBlock = DemoPlayer; // was LightMaleHumanArmor
aiPlayer = true;
RPGDialogScript = "Test";
RPGDialogPortrait = "Test.png";
RPGDialogStartQuestion = 1;
RPGDialogBusy = false;
RPGDialogBusyText = 'Sorry but I\'m busy talking to %1 right now.';
RPGDialogTalkingTo = 0;
};
MissionCleanup.add(%player);
// Player setup
%player.setMoveSpeed(8);
%player.setTransform(pickSpawnPoint(2));
%player.setEnergyLevel(60);
%player.setShapeName(%player);
return %player;
}
function SpawnNPC(%Name,%Script,%Portrait,%startQuestion,%location)
{
%player = new AIPlayer() {
dataBlock = DemoPlayer; // was LightMaleHumanArmor
aiPlayer = true;
RPGDialogScript = %Script;
RPGDialogPortrait = %Portrait;
RPGDialogStartQuestion = %startQuestion;
RPGDialogBusy = false;
RPGDialogBusyText = 'Sorry but I\'m busy talking to %1 right now.';
RPGDialogTalkingTo = 0;
};
MissionCleanup.add(%player);
// Player setup
%player.setMoveSpeed(8);
%player.setTransform(%location);
%player.setEnergyLevel(60);
%player.setShapeName(%Name);
return %player;
}@ari - your snippets for multiple actions per response are great, just what I needed.
#44
@ari or seb or anyone..
i dont understand how exactly the rewards or sell items work.
where does the go:
RewardItem(FlameThrower_01,1)RewardItem(FlameThrowerAmmo_01,500)RewardItem(Pistol_01,
1)RewardItem(PistolAmmo_01,34)SayChat("Thank you for completing that for me.")-
when i sell a item is this just a predetermined everything listed? or can you specify "what you want to sale?
confused on this stuff
05/10/2005 (1:09 pm)
@sebastion.. thanks for the update the little things help alot.@ari or seb or anyone..
i dont understand how exactly the rewards or sell items work.
where does the go:
RewardItem(FlameThrower_01,1)RewardItem(FlameThrowerAmmo_01,500)RewardItem(Pistol_01,
1)RewardItem(PistolAmmo_01,34)SayChat("Thank you for completing that for me.")-
when i sell a item is this just a predetermined everything listed? or can you specify "what you want to sale?
confused on this stuff
#45
getSubStr(...): error, starting position and desired length must be >= 0: (0, -1)
getSubStr(...): error, starting position and desired length must be >= 0: (0, -1)
Syntax error in input.
getSubStr(...): error, starting position and desired length must be >= 0: (0, -1)
getSubStr(...): error, starting position and desired length must be >= 0: (0, -1)
Syntax error in input.
seems to be either right after i close the question window in game or after i click a question like rename the sender. anyone else get this?
ok narrowed it down to close dialog i // all the closedialog in the rest of the file like Ari had. but everytime i choose a question window drops and get the errors not sure where else closes the window that causes the problem
05/10/2005 (2:06 pm)
hmm getting a errorgetSubStr(...): error, starting position and desired length must be >= 0: (0, -1)
getSubStr(...): error, starting position and desired length must be >= 0: (0, -1)
Syntax error in input.
getSubStr(...): error, starting position and desired length must be >= 0: (0, -1)
getSubStr(...): error, starting position and desired length must be >= 0: (0, -1)
Syntax error in input.
seems to be either right after i close the question window in game or after i click a question like rename the sender. anyone else get this?
ok narrowed it down to close dialog i // all the closedialog in the rest of the file like Ari had. but everytime i choose a question window drops and get the errors not sure where else closes the window that causes the problem
#46
That goes in the command area of the answer edit dialog.
I made a screen shot to demonstrate.
http://www.imagedump.com/index.cgi?pick=setandget&tp=256628&poll_id=0&category_id=20&warned=y
The errors you are getting used to happen in my code as well.
I have fixed it, and I'll try and update my snippit as soon as possible.
Currently I'm taking a small break from coding so as not to get burned out.
Ari
05/29/2005 (5:53 pm)
@DejaBlueThat goes in the command area of the answer edit dialog.
I made a screen shot to demonstrate.
http://www.imagedump.com/index.cgi?pick=setandget&tp=256628&poll_id=0&category_id=20&warned=y
The errors you are getting used to happen in my code as well.
I have fixed it, and I'll try and update my snippit as soon as possible.
Currently I'm taking a small break from coding so as not to get burned out.
Ari
#47
It renders the dialog editor almost useless.
I had to roll back a bit and lost my fix and now I'm wrapped up in other code.
Sorry.
Ari
06/29/2005 (5:18 am)
With the multiple commands snippit in, I have to use notepad to edit my dialogs.It renders the dialog editor almost useless.
I had to roll back a bit and lost my fix and now I'm wrapped up in other code.
Sorry.
Ari
#48
06/29/2005 (5:26 am)
I am going to be implimenting this tonight or tomorrow. Seems like you guys have done a lot on it.
#49
06/29/2005 (9:01 am)
Just implemented this in tutorial.base, make sure to include chathud.cs, messagehud.cs, chathud.gui and graphics needed for those and all should be fine.
#50
06/29/2005 (9:08 am)
Thanks for the tips
#51
06/30/2005 (12:31 am)
I have a question, is there somewhere that explains the color code system for the font colors? I see that Question color is C1 and Answer color is C5, but I've done a search and don't see these referenced anywhere. I'd like my questions to be a light gray and my answers to be green.
#52
07/01/2005 (3:43 pm)
This is even better then I thought... Thanks.
#53
07/01/2005 (3:47 pm)
Matt - Check out : starter.fps\client\ui\RPGDialog.gui
#54
i execute all tasks...
F5 works....
but i go to console and type:
SpawnTestNPC();
then... nothing happens.....
am i doiing something wrong???
thks
07/06/2005 (7:41 am)
Hi...i execute all tasks...
F5 works....
but i go to console and type:
SpawnTestNPC();
then... nothing happens.....
am i doiing something wrong???
thks
#55
I placed an item in the world... then wrote down it's coordinates (F11->F3) ... and used that for my spawn point.
07/06/2005 (9:21 am)
Does it give you errors in teh console ? Open server/scripts/RPGDialog.cs and change the spawn position. It is probably spawning somewhere that you can't see. I placed an item in the world... then wrote down it's coordinates (F11->F3) ... and used that for my spawn point.
#56
the testing function where you can type:
Execute SpawnTestNPC(); to bring up an NPC at the center of the world.....
It works great.
So how can I add this TestNPC INTO my game at a particular location?
(and another at a different location?)
(with a different skin?)
OH!! And another question... Is there a programming reason as to WHY there HAS to be a reply IF the NPC is questioned by another player (when in multiplayer??) It seems to me that it would be better if its was possible just for all players to speak to NPC's at the same time! (Thats how it works in Anarchy Online and World of Warcraft anyhow...)
m
07/10/2005 (6:25 am)
BUT.. OK here is ONE small newbie question...the testing function where you can type:
Execute SpawnTestNPC(); to bring up an NPC at the center of the world.....
It works great.
So how can I add this TestNPC INTO my game at a particular location?
(and another at a different location?)
(with a different skin?)
OH!! And another question... Is there a programming reason as to WHY there HAS to be a reply IF the NPC is questioned by another player (when in multiplayer??) It seems to me that it would be better if its was possible just for all players to speak to NPC's at the same time! (Thats how it works in Anarchy Online and World of Warcraft anyhow...)
m
#57
(just after...
function GameConnection::spawnPlayer(%this)
{
)and I got the SpawnTestNPC to turn up in game!!! HURRAH!!
But Now Im thinking.. Im defining my character in RPGDialog.cs, and calling it in game.cs ... is this wise... can I move ALL the code pertaining to SpawnTestNPC to... um... somewhere else (where would YOU put it?) somewhere that I define ALL my characters... its OWN BRAND NEW FILE perhaps.. of straight in game.cs perhaps??? whats the USUAL thing here???
AND ONE MORE THING... I also managed to put the RPGDialog on another NPC, the one that started out as Kork... Now hes unning in circles like a mad thing.. can RPGDialog Stop him running? (in the same way as they look your way) as soon as the Dialog starts? Right now, the RPGDialog convo box opens up when I hit Q, and then the NPC runs off, taking him out of the minimum distance...and the Dialog closes...
Silly
M
m
07/10/2005 (7:19 am)
WELL ...I typed SpawnTestNPC() into server/scripts/game.cs for a giggle(just after...
function GameConnection::spawnPlayer(%this)
{
)and I got the SpawnTestNPC to turn up in game!!! HURRAH!!
But Now Im thinking.. Im defining my character in RPGDialog.cs, and calling it in game.cs ... is this wise... can I move ALL the code pertaining to SpawnTestNPC to... um... somewhere else (where would YOU put it?) somewhere that I define ALL my characters... its OWN BRAND NEW FILE perhaps.. of straight in game.cs perhaps??? whats the USUAL thing here???
AND ONE MORE THING... I also managed to put the RPGDialog on another NPC, the one that started out as Kork... Now hes unning in circles like a mad thing.. can RPGDialog Stop him running? (in the same way as they look your way) as soon as the Dialog starts? Right now, the RPGDialog convo box opens up when I hit Q, and then the NPC runs off, taking him out of the minimum distance...and the Dialog closes...
Silly
M
m
#58
I call spawnNPCs in startgame() in game.cs
07/19/2005 (6:38 am)
Mark I created a seperate script. In it I declared a funciton spawnNPCs() ... Which basically calls SpawnNPC for every locastion and PlayerData datablock I need. I call spawnNPCs in startgame() in game.cs
#59
If afraid I CANNOT write ANY code from scratch, Im no programmer... but a helluver code stealer... I need a For instance really.
BTW: Is there a document that simply lays out which files DO what... it seems to me that theres bits and pieces all over the place... and VERY irritating that there are multiple files with the same name.. I bought Kens Book,to try and figure this out... which is low level on all the tools (the in game tools-- - Quark - - Milkshape etc... ) but jumps right in and confusing with the scripting... for me anyhow... I dont need a "type this in" and something will happen.. I need a " Use THIS code to do THIS... and stick it HERE..."because... kind of tut... ANyway getting off topic for this forum...
07/20/2005 (6:30 am)
If you are saying that you made a new xxx.cs that handles all the parameters for ALL your NPC's.. I was thinking along these lines too... but do you HAVE to then call them in game.cs? I was trying to make a character.cs file where simply all people in the game get created... everything... parameters for different meshes..RPGDiologs... position... everything...If afraid I CANNOT write ANY code from scratch, Im no programmer... but a helluver code stealer... I need a For instance really.
BTW: Is there a document that simply lays out which files DO what... it seems to me that theres bits and pieces all over the place... and VERY irritating that there are multiple files with the same name.. I bought Kens Book,to try and figure this out... which is low level on all the tools (the in game tools-- - Quark - - Milkshape etc... ) but jumps right in and confusing with the scripting... for me anyhow... I dont need a "type this in" and something will happen.. I need a " Use THIS code to do THIS... and stick it HERE..."because... kind of tut... ANyway getting off topic for this forum...
#60
Go into the game hit F5 and build yourself some scripts, make sure you write down the names of them.
Then go into RPGDialog and check out the SpawnNPC() functoin. That will tell you and show you what you need to send into the spawnNPC function when you create your npc's.
Ok... so you have a basis. Since there is no way to set a spawnpoint or anything... I went in and created a healthpack where ever I wanted an NPC. I named them the same as what script they were to use.
Then I went into my .mis file, cut out the item declerations for my npcs. Saved the mis file. Created a new text file in server/scripts. Called it NPCCharacters.cs and pasted the item declerations into it.
Now... Knowing that I needed to spawn NPC's with those locations I created a spawnNPC() funciton that would create an NPC with the right script at the right location. I knew the name of the script because I wrote it down, and I knew the location because I named the item the same as the name of the script I wanted to use.
Now, I made a spawnNPC call for each of the locations... Which was a lot. I also had to create new PlayerData datablocks for each NPC that needed a different shapefile used. Which means I had to change the spawnNPC() function. I added %datablock to the end of its decleration, and changed the spawnTestNPC() function to tack DemoPlayer onto its call to spawnNPC().
Now to get my NPC's to have the right shape, I went into server/scripts/player.cs, searched for PlayerData... That is the datablock that tells TGE what DemoPlayer (PlayerBody) what it does and how to act and look. To extend it you add something like this: (could be wrong, I have NO code here)
All that did was tell TGE: "Hey, I need a Player datablock... Gimme everything the same as the Orc, but make it into 'enter new character' instead"
Now. You have everything set up and ready to rock.
Make sure that the only thing in you NPCCharacters script is the spawnNPC() function calls. You have to add just a little more to it.
You want to place all of those in a function... So change it like this:
and execute your script by placing the following in game.cs:
[code]
exec(
07/20/2005 (9:41 am)
Mark - server/scripts/RPGDialog has everything you need really.Go into the game hit F5 and build yourself some scripts, make sure you write down the names of them.
Then go into RPGDialog and check out the SpawnNPC() functoin. That will tell you and show you what you need to send into the spawnNPC function when you create your npc's.
Ok... so you have a basis. Since there is no way to set a spawnpoint or anything... I went in and created a healthpack where ever I wanted an NPC. I named them the same as what script they were to use.
Then I went into my .mis file, cut out the item declerations for my npcs. Saved the mis file. Created a new text file in server/scripts. Called it NPCCharacters.cs and pasted the item declerations into it.
Now... Knowing that I needed to spawn NPC's with those locations I created a spawnNPC() funciton that would create an NPC with the right script at the right location. I knew the name of the script because I wrote it down, and I knew the location because I named the item the same as the name of the script I wanted to use.
Now, I made a spawnNPC call for each of the locations... Which was a lot. I also had to create new PlayerData datablocks for each NPC that needed a different shapefile used. Which means I had to change the spawnNPC() function. I added %datablock to the end of its decleration, and changed the spawnTestNPC() function to tack DemoPlayer onto its call to spawnNPC().
Now to get my NPC's to have the right shape, I went into server/scripts/player.cs, searched for PlayerData... That is the datablock that tells TGE what DemoPlayer (PlayerBody) what it does and how to act and look. To extend it you add something like this: (could be wrong, I have NO code here)
PlayerData (NEWBody : PlayerBody)
{
//new shapefile
ShapeFile = "I am a shape directory";
}All that did was tell TGE: "Hey, I need a Player datablock... Gimme everything the same as the Orc, but make it into 'enter new character' instead"
Now. You have everything set up and ready to rock.
Make sure that the only thing in you NPCCharacters script is the spawnNPC() function calls. You have to add just a little more to it.
You want to place all of those in a function... So change it like this:
function spawnEveryone()
{
// Place all the SpawnNPC(...); calls here
}and execute your script by placing the following in game.cs:
[code]
exec(

Torque Owner NA
Also - it states it cant even FIND the TalkTo function when attempting to use the console, so maybe thatll do it?