• New Horizons on Maelstrom
    Maelstrom New Horizons


    Visit our website www.piratehorizons.com to quickly find download links for the newest versions of our New Horizons mods Beyond New Horizons and Maelstrom New Horizons!

Solved How do I make the game find and insert the gender of a NPC?

Fluen

Freebooter
When I did a fetch quest for the weapon smith (female) in Grand Turk, I noticed the quest told me to bring the goods back to "him". I examined the text, which simply says "him" in all fetch quests.
I had run into a similar problem, when soldiers tried to arrest me in another game, and the officer ordered: "Seize him" (I almost always play a female character). In that case I looked into more dialogues and found the command #sgenderobj# and replaced the standard "him" with that command, so the next soldiers trying to arrest me correctly received the order: "Seize her".

But that doesn't work in quest texts. Now the quest text for the fetch quest doesn't say anything in the place for the artisan's gender. What command should I use to make the game engine check the NPC's gender and insert the correct pronoun?
 
In dialog and questbook text, anything which starts "#s" and ends "#" is a preprocessed variable. If you got it working in a dialog then you'll have found a command 'Preprocessor_Add' which fills in the variable.

For questbooks, use 'Preprocessor_AddQuestData' instead. After the questbook entry command 'AddQuestRecord', use 'Preprocessor_Remove' to avoid variable data being left behind after it's done its job. For example, in "PROGRAM\Storyline\standard\QUESTS\quests_reaction.c", case "Story_BlazeLeavesDanielleRoom":
Code:
            Preprocessor_AddQuestData("Danielle", GetMyName(CharacterFromID("Danielle")));
            Preprocessor_AddQuestData("pronoun", XI_ConvertString(GetMyPronounSubj(CharacterFromID("Danielle"))));
            if (Characters[GetCharacterIndex("Danielle")].sex == "woman") Preprocessor_AddQuestData("pronoun3", XI_ConvertString("her"));
            else Preprocessor_AddQuestData("pronoun3", XI_ConvertString("his"));
            Preprocessor_AddQuestData("Pronoun_upper", FirstLetterUp(XI_ConvertString(GetMyPronounSubj(CharacterFromID("Danielle")))));
            AddQuestRecord("Meet_Danielle_on_Muelle", 4);
            Preprocessor_Remove("Pronoun_upper");
            Preprocessor_Remove("pronoun3");
            Preprocessor_Remove("pronoun");
            Preprocessor_Remove("Danielle");
(The primary NPC in this storyline is always "Danielle". If you're playing a female character then "Danielle" is renamed as Nathaniel Hawk and gets a random choice of outfit, which is why you see Nathaniel. The character's ID is still "Danielle", though. It was a lot easier than having to rewrite the whole quest to take account of two different characters. :D)
 
I'm in dangerous waters here, as I've never worked with the program files behind the dialogue texts and questbook texts before. So I'll need further help.

1. I found Gunsmith_fetch.c, and what I think is the relevant routine:
case "save goods for me":
RemoveCharacterGoods(PChar,sti(NPChar.fetch_quest.good),sti(NPChar.temp_amount));
NPChar.fetch_quest.already_received = NPChar.temp_amount;
DeleteAttribute(NPChar,"temp_amount");
Diag.CurrentNode = Diag.TempNode;
questbookname = "fetch&number="+NPChar.fetch_quest.cargoid+NPChar.index; //Set a questname
AddQuestRecord(questbookname, 2);
DialogExit();
break;

2. I found the quest book file fetch.txt, which contains the textbook entries.
3. I opened PROGRAM/Characters/init/Turks.c and found ch.id: turks_gunsmith

So should I write a copy of your code in post #2 (modified to replace "Danielle" with "turks_gunsmith" in the code and to replace ""Meet_Danielle_on_Muelle", 4" with "questbookname, 2") into Gunsmith_fetch.c into the routine, so it surrounds the AddQuestRecord? And what is the pronoun him/her called?
 
You won't need all the code from my example. In fact, you won't need any of it because the word you want to replace is in "fetch.txt", line 1, currently "The #stype# of #stown# asked me to get #damount# #sgood# from somewhere and deliver it back to him for #dmoney# gold coins. But I have to deliver it before #sdate# or I will receive nothing." That's the objective pronoun, which is the only pronoun not shown in the example! So, first step is to edit "fetch.txt" and replace "him" with a preprocessed variable. You can call it whatever you like, you just need to make sure that wherever the questbook is written, there's a 'Preprocessor_AddQuestData' command using the same variable name. I often use "pronoun" or "pronoun1" for subjective ("he"/"she"), "pronoun2" for objective ("him"/"her"), and "pronoun3" for possessive ("his"/"her"). But you can use something different if you like.

That's line 1, so you're looking at the wrong dialog case. You want case "agree fetch", which includes 'AddQuestRecord(questbookname, 1);' along with a whole lot of other 'Preprocessor_AddQuestData' commands. Edit "fetch.txt" to replace "him" with your choice of preprocessed variable. Then edit "Gunsmith_fetch.c" and add:
Code:
Preprocessor_Add("pronoun2", XI_ConvertString(GetMyPronounObj(NPChar)));
That goes somewhere before the 'AddQuestRecord' line, probably among the other 'Preprocessor_AddQuestData' lines. And among the 'Preprocessor_Remove' lines after 'AddQuestRecord', add:
Code:
Preprocessor_Remove("pronoun2");
Replace "pronoun2" with whatever you used to replace "him".

'GetMyPronounObj' is defined in "PROGRAM\Dialog_func.c", and you'll find some other pronoun functions in there as well.

'XI_ConvertString' translates the word into whichever language the player is using - we have a Spanish translation in a fairly advanced state, as well as Russian and Polish translations in rather less advanced condition.

'NPChar' is usually the person talking to you - you may need to check at the top of the dialog file to make sure it's defined, but you can be certain that it's safe here because some of the other 'Preprocessor_AddQuestData' lines already use it. (You can't use a specific character ID such as "turks_gunsmith" because the same file is also used by the gunsmith in Sao Jorge.)

And now the Turks Island gunsmith should fill in the questbook with the correct pronoun. But you're not finished yet! That questbook covers all fetch quests from all types. So you'll need to make similar changes to "apothecary_fetch.c", "Blacksmith_fetch.c", "shipyard.c" and "tailor.c", otherwise their fetch questbooks will all have a blank where there should be a pronoun. (Incidentally, the blacksmith in St. Pierre, Martinique, will also benefit from your work, being another one for whom "him" is inappropriate!)
 
I think I'm beginning to understand your explanation. Three things, though:

1. Is it the text in the fetch.txt with the quest texts, I'm supposed to correct with a variable for the correct pronoun? Then what about the similar text in gunsmith_fetch.c?
2. How exactly should I write the variable into the text? Example: the other variables in gunsmith_fetch.c are defined as "town" and "amount", but are written as #stown# and #damount# in fetch.txt. What determines, if it should be a #s or a #d?
3. If I modify gunsmith_fetch.c with a pronoun variable, which is only used in the English questbook. What happens to the questbook texts in other languages? Will they be messed up?
 
1: Exactly. Replace "him" with a variable in the questbook text, then use 'Preprocess_AddQuestData' in "gunsmith_fetch.c" to fill in that variable.
2: The first thing I'd do is play a fetch quest, check the questbook and make sure the amount of cargo and the money offered do show up. If they don't, it's a mistake. If they do, my guess is that "#stown#" is a string while "#damount#" is a number. In "gunsmith_fetch.c":
Code:
Preprocessor_AddQuestData("town",ctown.name);
...
Code:
Preprocessor_AddQuestData("amount",sti(NPChar.fetch_quest.amount));
"ctown.name" and "NPChar.fetch_quest.amount" are attributes, which are strings. Function 'sti' converts String To Integer. So "town" is filled in with a string while "amount" is filled in with an integer. I'd never even noticed the difference until you pointed it out, and as the whole lot is going to end up as a string anyway, you may as well just use '#s' for everything - I do!
3: If you use functions such as 'XI_ConvertString(GetMyPronounObj(NPChar))', it should work in other languages. For example, 'GetMyPronounObj' returns "him" or "her". 'XI_ConvertString' then looks for those words in "RESOURCE\INI\TEXTS\ENGLISH\common.ini", where it will find:
Code:
string = him,"him"
string = her,"her"
But if you're playing in Spanish then it will search "RESOURCE\INI\TEXTS\SPANISH\common.ini" instead:
Code:
string = him,"lo"
string = her,"la"
 
Ok. I think, I'm ready to do the modification. But while I can modify the gunsmith_fetch.c (and the other artisan fetchquest c-files) and the English quest texts, I know nothing about the syntax in the other languages, so I have no idea of where to insert the new variable (or what words to delete) in the quest texts in other languages. Someone with a better understanding of those languages will have to pick up the mantle from there.
 
Last edited:
That is all you need to do - make the changes to the English dialog and quest texts, and change the "dialog.c" files to fill in variables. It's then up to our translators to see what has changed in the "ENGLISH" folders and make similar changes to their language versions.
 
So far I haven't had much luck.
I edited apothecary_fetch.c, blacksmith_fetch.c, gunsmitch_fetch.c, shipyard.c and tailor.c to contain following blocks into the routine "case agree fetch":
Code:
            Preprocessor_AddQuestData("money",sti(NPChar.fetch_quest.money));
            Preprocessor_AddQuestData("pronoun2",XI_ConvertString(GetMyPronounObj(NPChar)));
            Preprocessor_AddQuestData("date",NPChar.fetch_quest.expire);
and
Code:
            Preprocessor_Remove("money");
            Preprocessor_Remove("pronoun2");
            Preprocessor_Remove("date");
The the middle lines are the ones, I inserted. The other code parts are just to show, where I inserted them.

I also changed the fetch.txt to say:
text.t1=The #stype# of #stown# asked me to get #damount# cargo units of #sgood# from somewhere and deliver it back to #spronoun2# for #dmoney# gold coins. But I have to deliver it before #sdate# or I will receive nothing.

The bold parts are my insertions.

But when I take on a new fetch quest, I still get a version of the quest book saying only "units" and with an empty space, where "him/her" should have been. It was my first attempt to modify the fetch quest book, from before I asked for help here. And that version should be gone by now, so where does the game engine even find it?
 
It's possible that the old version of "fetch.txt" is still loaded as a result of a previous quest. Try starting a new game - you don't need to lose the existing game, just start a new one with a new profile name, or in a different storyline.

Are the other variables ("type", "town", "amount" etc.) still being properly filled in?
 
A new game worked. But it lasted several days of playing, before one of the two female artisans finally needed help, so I could confirm that the modification works for both genders.
 
Back
Top