I want to modify Urk’s one-liners script to use some kind of gender reference like conversations do, but I can find no clear example of how to do that. I find references to using getgender combined with some .2da token I can’t find.
I figured someone would have made an include file, or system, with the default conversation tokens for speakstring scripts, but I guess not.
I’ve read the custom token lexicon, and that doesn’t help me.
Help me get started please, and I can figure it out.
His partial script is this, and I have no idea how to proceed making an include file, or modifying it, with several of the gender tokens at least. Then make ActionSpeakString use the appropriate token in the random sText. The script works fine as is without any personalized responses, but it would be nice to have it say “Pardon me, sir”., or “madam” instead of plain old pardon me. Else I need to scrap it, and write up 60 conversations that can easily use tokens.
void main()
{
string sText;
int nRandom = d10(1);
object oSelf = OBJECT_SELF;
SetLocalInt(oSelf, “ConvKey”, nRandom);
if (nRandom == 1){
sText = “ENTER ONE LINER #1a HERE”;}
else if (nRandom == 2){
sText = “ENTER ONE LINER #2a HERE”;}
ActionSpeakString (sText, TALKVOLUME_TALK);
}
It’s not so difficult to write a ResolveStringToken function. Basically you have to scan the string for the tokens and translate them one by one. Getting the tokens is easy:
int nPosA, nPosE=-1;
string sToken;
while ((nPosA = FindSubString(sString, "<", nPosE+1))!=-1)
{
nPosE = FindSubString(sString, ">", nPosA+1);
if (nPosE!=-1)
{
sToken = GetSubString(sString, nPosA+1, nPosE-nPosA-1);
// for simplification we assume the string does not contain
// single "<" that are not part of a token. Otherwise we would
// have to search from nPosE to the left for the first "<" to really
// get the token.
Now that you have the token you have to search “stringtokens.2da” for that token to get a row number and then get the value of column “ActionCode”. Depending on that action code you can then start to translate the tokens (StrRef1, StrRef2, StrRef3, StrRef4 are columns in “stringtokens.2da”):
1: gender specific string: (male: column StrRef1, female: column StrRef2)
In your case this is probably all you need. The others are
2: full name
3: first name (not possible to get the first name with scripting, only thing you can do is guess)
4: last name (not possible to get the last name with scripting, only thing you can do is guess)
5: racial type (you can get that from racialtypes.2da, column ConverName)
6: race (you can get that from racialtypes.2da, column ConverNameLower)
7: subrace (you can get that from racialtypes.2da, column Name)
A solution with gender-based tokens based on x3_inc_string.
This is only a basic working script, but it has an unintended possibility for stacking the tokens (see example).
// By NWShacker 2020-05-14
#include "x3_inc_string"
string ReplaceTokensByGender(string sString, object oTokenSource=OBJECT_SELF)
{
string sSubString;
int iPosition1;
int iPosition2;
while(TRUE)
{
iPosition1 = FindSubString(sString, "<");
if(iPosition1 == -1)
{
return sString;
}
iPosition2 = FindSubString(sString, ">", iPosition1);
if(iPosition2 == -1)
{
return sString;
}
sSubString = GetSubString(sString,
iPosition1 + 1, iPosition2 - iPosition1 - 1);
if(FindSubString(sSubString, "/") == -1)
{
sSubString = "INVALID_TOKEN";
}
else
{
sSubString = StringParse(sSubString, "/",
GetGender(oTokenSource) == GENDER_FEMALE);
}
sString = GetSubString(sString, 0, iPosition1) +
sSubString + GetSubString(sString, iPosition2 + 1, -1);
}
return sString;
}
string ReplaceTokens(string sString, object oTokenSource=OBJECT_SELF)
{
sString = StringReplace(sString, "<name>", GetName(oTokenSource));
sString = StringReplace(sString, "<deity>", GetDeity(oTokenSource));
/* add your own token handlers here */
return ReplaceTokensByGender(sString, oTokenSource);
}
void main()
{
string sString = "Hello <name> <name> <deity> <man/woman> <<name>/<deity>> <badbad>";
SpeakString(ReplaceTokens(sString, GetFirstPC()));
// If PC's name is "FOO" and deity is "BAR", this returns:
// "Hello FOO FOO BAR man FOO INVALID_TOKEN" for GENDER_MALE
// "Hello FOO FOO BAR woman BAR INVALID_TOKEN" for GENDER_FEMALE
}
You add neutral token replacement code in ReplaceTokens function, while leaving the rest for ReplaceTokensByGender. And @Kamiryn has already written how to access StringRefs for localized strings (if needed).