Is there a way to type in a name during conversation?

This might be an odd question, but I had an idea that would require the player to type in a name of a character, during a conversation, that is then somehow stored through a local int or something other. Is this at all possible? Could you perhaps use the chat window? I have a vague memory from back in the day when I played a lot of NWN1 modules that something along that line was do-able in NWN1, so maybe it’s do-able in NWN2?

Thanks for your time!

1 Like

For that you could use the OnChat global event script on your module, that is to intercept messages send by the players.

The most immersive way however is to show some custom XML GUI to the player to enter text.

Bonus points for integrating this GUI into the chat GUI so it covers the answer options to prevent the pass-through (I don’t remember whether you can enable/disable response options on the flight, knowing NWN 2 - probably not).

1 Like

Sadly, in NWN2, the OnChat event is kind of irrilevant because the system functions to retrieve who and what was actually typed do not exist, so you can only use it to trigger generic functions, like award a tot exp every X times you type something in say chat…

the XML is really the only way to go.

1 Like

You don’t need to use any special functions for that, this information is already included into the main method of the event: https://nwn2.fandom.com/wiki/On_Chat_Event

2 Likes

Really interesting topic. Following this closely. :slightly_smiling_face:

Yes, it is. You’ll have to create a script that calls DisplayInputBox, and two that will be called depending on which button (“OK” or “Cancel”) is clicked.

Here are the parameters for DisplayInputBox:

//This script function displays a text input box popup on the client of the
//player passed in as the first parameter.
//////
// oPC - The player object of the player to show this message box to
// nMessageStrRef- The STRREF for the Message Box message.
// sMessage - The text to display in the message box. Overrides anything
// - indicated by the nMessageStrRef
// sOkCB - The callback script to call if the user clicks OK, defaults
// - to none. The script name MUST start with ‘gui’
// sCancelCB - The callback script to call if the user clicks Cancel, defaults
// - to none. The script name MUST start with ‘gui’
// bShowCancel - If TRUE, Cancel Button will appear on the message box.
// sScreenName - The GUI SCREEN NAME to use in place of the default message box.
// - The default is SCREEN_STRINGINPUT_MESSAGEBOX
// nOkStrRef - The STRREF to display in the OK button, defaults to OK
// sOkString - The string to show in the OK button. Overrides anything that
// - nOkStrRef indicates if it is not an empty string
// nCancelStrRef - The STRREF to dispaly in the Cancel button, defaults to Cancel.
// sCancelString - The string to display in the Cancel button. Overrides anything
// - that nCancelStrRef indicates if it is anything besides empty string
// sDefaultString- The text that gets copied into the input area,
// - used as a default answer

And here’s how I do it in my campaign:

void main()
{
object oPC = GetPCSpeaker();
int nMessageStrRef = -1;
string sMessage = (GetGlobalInt(“nLangue”)==1?“Vous répondez :”:“Your answer is:”);
string sOkCB = “gui_checkanswer”;
string sCancelCB = “gui_noanswer”;
int bShowCancel = TRUE;
string sScreenName = “”;
int nOkStrRef = 181744;
string sOkString = “”;
int nCancelStrRef = 181745;
string sCancelString = “”;
string sDefaultString = (GetGlobalInt(“nLangue”)==1?“Je ne sais pas.”:“I don’t know.”); //default text in the message box…
DisplayInputBox(oPC, nMessageStrRef, sMessage, sOkCB, sCancelCB, bShowCancel, sScreenName, nOkStrRef, sOkString, nCancelStrRef, sCancelString, sDefaultString);
}

2 Likes

Thanks for all the replies you guys! I’m not feeling much wiser though…

Great to hear from you @4760 since you know my modules well (I hope the beta testing is progressing :slight_smile: ). Do you mean that I don’t need a custom xml file?

1 Like

If I don’t want the french reply, do I just take that away? How would that look inth the script then? This is kind of advanced, I will have to look at this closely.

This line of code is a bit too advanced for me (even though it shouldn’t be). What does 1? mean?
Sorry for again being such a noob when it comes to scripting.

Looking closely at it again, and the explanation for the function. Could I write it like this perhaps?

void main()
{
object oPC = GetPCSpeaker();
int nMessageStrRef = -1;
string sMessage = ("Your answer is:");
string sOkCB = "gui_checkanswer";
string sCancelCB = "gui_noanswer";
int bShowCancel = TRUE;
string sScreenName = "";
int nOkStrRef = 181744;
string sOkString = "";
int nCancelStrRef = 181745;
string sCancelString = "";
string sDefaultString = ("I don’t know."); //default text in the message box…
DisplayInputBox(oPC, nMessageStrRef, sMessage, sOkCB, sCancelCB, bShowCancel, sScreenName, nOkStrRef, sOkString, nCancelStrRef, sCancelString, sDefaultString);
}
1 Like

Not as fast as the first runthrough, but I’m on it!

Absolutely :wink:

Yes, just set sMessage to what you want:

string sMessage = “Your answer is:”; // or whatever you want

You can also set it to an empty string, and use nMessageStrRef instead

2 Likes

So three scripts are needed? This one you’ve posted is the one that calls DisplayInputBox? How are the other two supposed to look like then?

You put in the number 181744. How did you find that number? Is it under Globals perhaps?

1 Like

Ok. So I tried this script in game, calling the script under a blue node and it showed up and seemed to be working. :smiley: I guess I’ll have to see how to recall the answer that the player gives the game now…

How is the answer stored and how do I call it? Can I somehow call the sOkCB?

1 Like

I’ll be damned, I just learned something from Stalin! Thanks Comrade! It really works!

Seriously though, thanks for pointing that out, they implemented it differently than in NWN1, I just thought that Obsidian had forgot the callback functions that were in NWN1, this really opens up to a lot of possibilities. Especially if it would be possible to make a custom Macro Text system (or use a stock one if there’s any?).

2 Likes

Yes, one on the action page in the conversation at the node where you need the answer, one for the OK button and another one for the Cancel button.

I used TlkEdit2 :wink:

Exactly.
Just make sure your script looks like this:

void main(string strRep)
{
// your code here
// check if strRep (the answer typed by the player) is correct
}

1 Like

Sorry, I don’t get this at all. There is no node where I call a script for the respective button. It’s just buttons. How do you mean?

Ok. You used that program somehow, and I get that it was a joke. Doesn’t explain anything though. Is it under some 2da file?

And I don’t get this either. This goes way above my head. I’m no programmer and I never was. I’ve had a hard time trying to get scripting for two years now and I still understand so little apparently. Maybe I should just give up on this then. :slightly_frowning_face:

I mean, I get that some kind of string is supposed to go in strRep maybe under a conversation node or something. And then I’m supposed to write some code…

To explain further: I would like, if possible to put the text answer into a conversation text, but I’m now doubting that to be possible. Uuurgh! I don’t know…

KevL_s usually manages to explain to a noob like me…

Sorry. What I mean is:

  • create a script that will call DisplayInputBox from the conversation (here, I named it “tgk_input”, it’s the one I posted earlier):
  • create a script that will be run when the OK button is clicked, and another one if it’s the Cancel button which is clicked.
    These scripts are called within DisplayInputBox:

So, if the player clicks OK, the script named “gui_checkanswer” will be executed (you can set any name you wish, as long as it starts with “gui_”).
Same for “Cancel”.

1 Like

Certainly no!

Correct. The variable strRep is filled with whatever the player type in DisplayInputBox (you can call it whatever you want by the way).
What I meant was that your script “gui_[name of your script called when the OK button is clicked]” should start with void main(string [name of your variable])
In my previous messages, I just used gui_checkanswer for the script name and strRep for the variable which will be used to store the answer from DisplayInputBox

Ok. I’m reading and re-reading right now. So…

As of right now I don’t want anything specifically to happen when the player types their text. The only thing I want to be able to somehow do is call what they said (I want to recall a name in this specific case) to be put inside of a text inside a node, sort of like Custom Token (I believe it is called).

So, I say I name my additional scripts (might as well keep it simple) “gui_checkanswer” and “gui_noanswer” and in gui_checkanswer I type void main(strRep){//my code here} I still don’t know what kind of code I’m going to put to be able to achieve what I want to achieve (if it is indeed possible to achieve what I want to achieve).

To be extremely clear of what I need: I would like the player to type the name of their character in my first module (chapter 1 (for those who don’t know these are standalone modules and not part of a campaign)), to then in the next node or the node after that, be put into the reply of the NPC he’s talking to (making a call-back from chapter 3 to chapter 1, so to speak). I thought of using something that kevL_s showed with storing the character used in my first module, but I’ve been thinking about that a lot, and that would require the player to maybe replay the whole chapter 1 again (since I would need to patch and implement that thing into chapter 1) before playing chapter 3, and I don’t think that’s fair to the player. So therefore I thought of maybe letting the player type their character name from the first module and that I could use that in some way (I’m not sure exactly how yet, but I’ve got a few ideas).

This is also possible, but then we’ll need to use custom tokens.

First things first, create a library for the functions we need: store and retrieve data.

/* Custom Token Library script

void SetCustomTokenEx(int iToken, string sValue)
Sets the custom token identified by the number in iToken to the string value specified in sValue. Also duplicates the value as a
local string stored on the module object so the GetCustomTokenEx function can retrieve it at any time.

string GetCustomTokenEx(int iToken)
Retrieves the current value of the custom token identified by the number in iToken by reading the local string variable containing
the duplicated token value which was stored on the module object by the SetCustomTokenEx function. If the custom token was set using
the default SetCustomToken function instead of SetCustomTokenEx, this function may return an incorrect or blank string.
*/

// Custom Token Constants
const int TKN_BASE = 6000;

void SetCustomTokenEx(int iToken, string sValue)
{
if (iToken <= 0) return;
// Change the custom token variable and duplicate it.
SetCustomToken(iToken, sValue);
SetLocalString(GetModule(), “CUSTOM” + IntToString(iToken), sValue);
}

string GetCustomTokenEx(int iToken)
{
if(iToken <= 0) return “”;
// Return the content of the module variable being used to duplicate the token variable.
return GetLocalString(GetModule(), “CUSTOM” +IntToString(iToken));
}

Note:
TKN_BASE is a constant to set where our numbering will start. Use whatever you want, as long as it’s higher than 1000 (CUSTOM0 etc… are used by the engine for some messages).

All you have to do now is, in your “gui_[script called from OK]”, set the CUSTOM6000 variable:
SetCustomTokenEx(TKN_BASE, strRep); // or whatever name you used for the variable for storing the answer typed in DisplayInputBox.
Don’t forget #include “LibCustomToken” (or whatever you called it)

Afterwards, in your dialog, just use (with the number matching TBN_BASE of course)

1 Like

Ok. I’ve not read your latest post that carefully since I finally think I understand what I needed to do with my gui_checkanswer script, namely SetCustomToken (and I used that in my second module). However, now that I did a test ingame the conversation continues to the end before displaying the DisplayInputBox gui. When looking at your picture of your conversation it seems that it should be possible to display the gui then continue the conversation afterwards. Is it perhaps because I use the NWN2 style conversation that it doesn’t work?