• 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!

Need Help Updating the Russian Translation

No, the dialog is not trying to add the character's name there. "Node_7" and parts of "Second time" and "Help_Failed" certainly need the correction, and case "Agreed_Help" may as well be corrected even though it does add the space between 'GetMyAddressForm(NPChar, PChar, ADDR_CIVIL, false, false)' and 'GetMyName(PChar)'.

Try this version.
 

Attachments

  • Rys Bloom_dialog.c
    14 KB · Views: 23
1) PROGRAM\Storyline\standard\quests\quests_reaction.c
In the case of "Story_InvasionVideoAfterLeaveOxbay" the video for English and other versions is not produced because the folder with the video is not specified.
Replace:
else PostVideoAndQuest("Invasion",1,"Story_MapLoadAfterleavingOxbay");
On the:
else PostVideoAndQuest("standard\English\Invasion",1,"Story_MapLoadAfterleavingOxbay");
2) Tancrede Rimbaud_dialog.c
Why do you need GetMyAddressForm(NPChar, PChar, ADDR_CIVIL, false, false) for Virgile Boone if the character is always male.
In this case, I approached this Tancrede and he said don’t interfere with talking to Mademoiselle Boone.
 

Attachments

  • 1718583319587.png
    1718583319587.png
    889.4 KB · Views: 39
Last edited:
1: Odd. The video works for me in English and it's been like that for ages, even in the stock game.
2: That's certainly a mistake, though the mistake is putting "PChar" there when it should be referring to Virgile Boone. Also, the line then adds 'Characters[GetCharacterIndex(DLG_TEXT[2])].lastname' to the end. We've been trying to discourage direct use of attributes like that, and the whole line can be made much tidier by using 'GetMyAddressFrom' properly. The 'false, false' part is two arguments which control whether the character's first and last names are to be included. So there is no need to explicitly add the character's last name if the second 'false' is changed to 'true'.

Try changing that line to:
Code:
d.Text = DLG_TEXT[0] + GetMyAddressForm(NPChar, PChar, ADDR_CIVIL, false, false) + DLG_TEXT[1] + GetMyAddressForm(NPChar, CharacterFromID(DLG_TEXT[2]), ADDR_CIVIL, false, true) + DLG_TEXT[3];
 
2: That's certainly a mistake, though the mistake is putting "PChar" there when it should be referring to Virgile Boone. Also, the line then adds 'Characters[GetCharacterIndex(DLG_TEXT[2])].lastname' to the end. We've been trying to discourage direct use of attributes like that, and the whole line can be made much tidier by using 'GetMyAddressFrom' properly. The 'false, false' part is two arguments which control whether the character's first and last names are to be included. So there is no need to explicitly add the character's last name if the second 'false' is changed to 'true'.
Yes, it worked. Now Boone is monsieur.
1: Odd. The video works for me in English and it's been like that for ages, even in the stock game.
It's strange, because this video is not in the RESOURCE\VIDEOS folder. Translators into Polish at beyond-new-horizons informed me about this and there is a black screen in any language except Russian. Probably because this video is in the POTC engine itself? In the standard version of NH the video works, but in the English version I have a video in Russian.
 
Check that you have the correct version of "PROGRAM\INTERFACE\interface.c". Function 'PostVideoAndQuest' is defined there. It calls 'StartPostVideo', which sets an event handler for "evntPostVideo" and then triggers the event. The handler is function 'stPostVideo', which calls 'StartVideo', which sends a call to the engine using function 'GetVideoFileName' to supply the full filename for the video.

'GetVideoFileName' is the function which tries to find the file:
Code:
        if (baseName == "") return "";
        sidx = strlen(baseName) - 1;
        if (strcut(baseName, sidx - 3, sidx) == ".wmv") return baseName;
        language = LanguageGetLanguage();
        default_language = "ENGLISH";
        sldir = "common";
        sidx = FindCurrentStoryline();
        if (sidx >= 0) {
            sldir = GetStorylineDir(sidx);
            if (FindFile("RESOURCE\VIDEOS\" + sldir + language, "*.wmv", baseName + ".wmv") != "") return sldir + language + "\" + baseName + ".wmv";
            if (FindFile("RESOURCE\VIDEOS\" + sldir + default_language, "*.wmv", baseName + ".wmv") != "") return sldir + default_language + "\" + baseName + ".wmv";
            if (FindFile("RESOURCE\VIDEOS\" + sldir, "*.wmv", baseName + ".wmv") != "") return sldir + "\" + baseName + ".wmv";
        }
        if (FindFile("RESOURCE\VIDEOS\common\" + language, "*.wmv", baseName + ".wmv") != "") return "common\" + language + "\" + baseName + ".wmv";
        if (FindFile("RESOURCE\VIDEOS\common\" + default_language, "*.wmv", baseName + ".wmv") != "") return "common\" + default_language + "\" + baseName + ".wmv";
        if (FindFile("RESOURCE\VIDEOS\common", "*.wmv", baseName + ".wmv") != "") return "common\" + baseName + ".wmv";
If the video name presented to the function ends with ".wmv", it just returns that name. That's not the case here - the name presented to the function is just "Invasion".

Next, it finds which storyline you're playing and finds the folder for that storyline. In sequence, it searches the subfolder for your chosen language, the subfolder for the default language (English), and the storyline folder itself.

If that doesn't work, it tries the "common" folder and again tries first the subfolder for your language, the subfolder for the default language, and the "common" folder itself.

That means this should not be necessary:
Code:
            if(LanguageGetLanguage() == "RUSSIAN") PostVideoAndQuest("standard\RUSSIAN\Invasion",1,"Story_MapLoadAfterleavingOxbay");
            else PostVideoAndQuest("Invasion",1,"Story_MapLoadAfterleavingOxbay");
It should find the Russian version automatically. And indeed, if I delete that and just leave 'PostVideoAndQuest("Invasion",1,"Story_MapLoadAfterleavingOxbay");', then switch to Russian language and start "Tales of a Sea Hawk", it plays the Russian version of the "Invasion" video. On the other hand, if I don't change "quests_reaction.c" and leave those lines in, and if I play in English or Spanish, it plays the English video.

Try this version of "interface.c". If the game crashes, post "error.log" because it means I've probably made a typing mistake. Otherwise, try starting "Tales of a Sea Hawk" in any language except Russian, play as far as the video, then quit and post "compile.log" and "system.log". This "interface.c" has a lot of 'trace' commands added which should show what 'GetVideoFileName' is doing.
 

Attachments

  • interface.c
    63.4 KB · Views: 24
Check that you have the correct version of "PROGRAM\INTERFACE\interface.c". Function 'PostVideoAndQuest' is defined there. It calls 'StartPostVideo', which sets an event handler for "evntPostVideo" and then triggers the event. The handler is function 'stPostVideo', which calls 'StartVideo', which sends a call to the engine using function 'GetVideoFileName' to supply the full filename for the video.

'GetVideoFileName' is the function which tries to find the file:
Code:
        if (baseName == "") return "";
        sidx = strlen(baseName) - 1;
        if (strcut(baseName, sidx - 3, sidx) == ".wmv") return baseName;
        language = LanguageGetLanguage();
        default_language = "ENGLISH";
        sldir = "common";
        sidx = FindCurrentStoryline();
        if (sidx >= 0) {
            sldir = GetStorylineDir(sidx);
            if (FindFile("RESOURCE\VIDEOS\" + sldir + language, "*.wmv", baseName + ".wmv") != "") return sldir + language + "\" + baseName + ".wmv";
            if (FindFile("RESOURCE\VIDEOS\" + sldir + default_language, "*.wmv", baseName + ".wmv") != "") return sldir + default_language + "\" + baseName + ".wmv";
            if (FindFile("RESOURCE\VIDEOS\" + sldir, "*.wmv", baseName + ".wmv") != "") return sldir + "\" + baseName + ".wmv";
        }
        if (FindFile("RESOURCE\VIDEOS\common\" + language, "*.wmv", baseName + ".wmv") != "") return "common\" + language + "\" + baseName + ".wmv";
        if (FindFile("RESOURCE\VIDEOS\common\" + default_language, "*.wmv", baseName + ".wmv") != "") return "common\" + default_language + "\" + baseName + ".wmv";
        if (FindFile("RESOURCE\VIDEOS\common", "*.wmv", baseName + ".wmv") != "") return "common\" + baseName + ".wmv";
If the video name presented to the function ends with ".wmv", it just returns that name. That's not the case here - the name presented to the function is just "Invasion".

Next, it finds which storyline you're playing and finds the folder for that storyline. In sequence, it searches the subfolder for your chosen language, the subfolder for the default language (English), and the storyline folder itself.

If that doesn't work, it tries the "common" folder and again tries first the subfolder for your language, the subfolder for the default language, and the "common" folder itself.

That means this should not be necessary:
Code:
            if(LanguageGetLanguage() == "RUSSIAN") PostVideoAndQuest("standard\RUSSIAN\Invasion",1,"Story_MapLoadAfterleavingOxbay");
            else PostVideoAndQuest("Invasion",1,"Story_MapLoadAfterleavingOxbay");
It should find the Russian version automatically. And indeed, if I delete that and just leave 'PostVideoAndQuest("Invasion",1,"Story_MapLoadAfterleavingOxbay");', then switch to Russian language and start "Tales of a Sea Hawk", it plays the Russian version of the "Invasion" video. On the other hand, if I don't change "quests_reaction.c" and leave those lines in, and if I play in English or Spanish, it plays the English video.

Try this version of "interface.c". If the game crashes, post "error.log" because it means I've probably made a typing mistake. Otherwise, try starting "Tales of a Sea Hawk" in any language except Russian, play as far as the video, then quit and post "compile.log" and "system.log". This "interface.c" has a lot of 'trace' commands added which should show what 'GetVideoFileName' is doing.
Here are the logs for English and Spanish. I think I understood why my Russian video was playing in English. For some reason, in the RESOURCE\VIDEOS\standard\English folder there was a Russian video, not an English one. I replaced it from beyond-new-horizons with the correct video.
 

Attachments

  • ENGLISH.7z
    3.7 KB · Views: 20
  • SPANISH.7z
    4 KB · Views: 22
In both English and Spanish, "compile.log" shows a full set of traces near the top. That's probably an introductory video when you start the game and it's probably in "RESOURCE\VIDEOS\common", so that's to be expected.

Near the end, English "compile.log" has this line alone:
Code:
GetVideoFileName: trying 'RESOURCE\VIDEOS\standard\English'
That's also to be expected - the chosen language is English so the first place 'GetVideoFileName' looks is "RESOURCE\VIDEOS\standard\English", which is where it finds the English "Invasion.wmv".

The Spanish "compile.log" has two lines there:
Code:
GetVideoFileName: trying 'RESOURCE\VIDEOS\standard\Spanish'
GetVideoFileName: trying 'RESOURCE\VIDEOS\standard\ENGLISH'
This time the chosen language is Spanish so 'GetVideoFileName' tries to find a Spanish folder, fails, then tries the default English folder.

For another experiment, edit "quests_reaction.c". In case "Story_InvasionVideoAfterLeaveOxbay", comment out these lines:
Code:
if(LanguageGetLanguage() == "RUSSIAN") PostVideoAndQuest("standard\RUSSIAN\Invasion",1,"Story_MapLoadAfterleavingOxbay");
else PostVideoAndQuest("Invasion",1,"Story_MapLoadAfterleavingOxbay");
And add a single line without condition:
Code:
PostVideoAndQuest("Invasion",1,"Story_MapLoadAfterleavingOxbay");
Then play in Russian, and if it does not show the Russian video, post "compile.log".
 
In both English and Spanish, "compile.log" shows a full set of traces near the top. That's probably an introductory video when you start the game and it's probably in "RESOURCE\VIDEOS\common", so that's to be expected.

Near the end, English "compile.log" has this line alone:
Code:
GetVideoFileName: trying 'RESOURCE\VIDEOS\standard\English'
That's also to be expected - the chosen language is English so the first place 'GetVideoFileName' looks is "RESOURCE\VIDEOS\standard\English", which is where it finds the English "Invasion.wmv".

The Spanish "compile.log" has two lines there:
Code:
GetVideoFileName: trying 'RESOURCE\VIDEOS\standard\Spanish'
GetVideoFileName: trying 'RESOURCE\VIDEOS\standard\ENGLISH'
This time the chosen language is Spanish so 'GetVideoFileName' tries to find a Spanish folder, fails, then tries the default English folder.

For another experiment, edit "quests_reaction.c". In case "Story_InvasionVideoAfterLeaveOxbay", comment out these lines:
Code:
if(LanguageGetLanguage() == "RUSSIAN") PostVideoAndQuest("standard\RUSSIAN\Invasion",1,"Story_MapLoadAfterleavingOxbay");
else PostVideoAndQuest("Invasion",1,"Story_MapLoadAfterleavingOxbay");
And add a single line without condition:
Code:
PostVideoAndQuest("Invasion",1,"Story_MapLoadAfterleavingOxbay");
Then play in Russian, and if it does not show the Russian video, post "compile.log".
Yes, it shows Russian video.
Then perhaps the same can be done with videos of Jack Sparrow and Hornblower?
 
Last edited:
"Hornblower" should work - the video folder is "Hornblower", which is also the storyline folder defined in "PROGRAM\Storyline\Hornblower.c", so 'GetVideoFileName' should look in the right place.

"JackSparrow" is another matter. "PROGRAM\Storyline\JackSparrow.c" defines the storyline folder as "JackSparrow\" but the videos are in "LegendJackSparrow". So all the quest commands to play videos specific to the storyline include the path, e.g. in case "Jack's_arrival_at_Redmond2":
Code:
if(LanguageGetLanguage() == "RUSSIAN") PostVideoAndQuest("LegendJackSparrow\RUSSIAN\jack_entrance", 25, "You_need_to_pay_mooring");
else PostVideoAndQuest("LegendJackSparrow\jack_entrance", 25, "You_need_to_pay_mooring");
My guess is that 'GetVideoFileName' will search for the whole string "LegendJackSparrow\jack_entrance", fail to find it in any of the places it expects, and then return the string unchanged. That's fine as the string itself includes the folder name, but it does mean the check for Russian is needed.
 
1) If you kill the soldiers without talking to them, the plot will break and Tobias will not say that you need to go to the shipyard. (case "Counterspy_Exit_fight")
2) I am teleported outside without having time to finish the dialogue in the tavern with Rabel Iverneau. Teleports on line 23 of the dialogue "Rabel Yverneau_dialog.h".
3) During the first fight with Pintel and Ragetti, I can run into the tavern and then I will freeze in place.
 

Attachments

  • 1718975569002.png
    1718975569002.png
    720.5 KB · Views: 32
  • 1719096682230.png
    1719096682230.png
    962 KB · Views: 30
Last edited:
1: In case "Counterspy_Exit_fight", add:
Code:
LAi_LocationFightDisable(&Locations[FindLocation("Oxbay_tavern")], true);
There's already a code to re-enable fighting in case "arrest_in_tavern_for_fra_occupants", and was even there in the stock game.

2: In "Rabel Yverneau_dialog.c", case "Node_6", replace...
Code:
DoQuestCheckDelay("Story_Blaze_and_Rabel_Leave_tavern", 1.0);
... with...
Code:
AddDialogExitQuest("Story_Blaze_and_Rabel_Leave_tavern");

3: They're cursed pirates. They're magical. If you try to cheat by somehow skipping past them into the tavern, expect them to use magic to cheat back. ;p

Can you provide a savegame from just before you start talking to the pirates? I'll need to see about adding some more 'StartQuestMovie' and 'EndQuestMovie' commands to lock all exits after you first talk to the pirates and then unlock them when you've given them the chest.
 
1: In case "Counterspy_Exit_fight", add:
Code:
LAi_LocationFightDisable(&Locations[FindLocation("Oxbay_tavern")], true);
There's already a code to re-enable fighting in case "arrest_in_tavern_for_fra_occupants", and was even there in the stock game.
Now it works great.
2: In "Rabel Yverneau_dialog.c", case "Node_6", replace...
Code:
DoQuestCheckDelay("Story_Blaze_and_Rabel_Leave_tavern", 1.0);
... with...
Code:
AddDialogExitQuest("Story_Blaze_and_Rabel_Leave_tavern");
Now it works great.
3: They're cursed pirates. They're magical. If you try to cheat by somehow skipping past them into the tavern, expect them to use magic to cheat back. ;p

Can you provide a savegame from just before you start talking to the pirates? I'll need to see about adding some more 'StartQuestMovie' and 'EndQuestMovie' commands to lock all exits after you first talk to the pirates and then unlock them when you've given them the chest.
Here are 2 saves, one at night just before the tavern, and the second on the open sea in front of Port Royal and teleporting to the residence in case you need it in the morning.
 

Attachments

  • standard.7z
    589.2 KB · Views: 20
Try these versions of "quests_reaction.c" and "both_reaction.c". A new pair of 'StartQuestMovie' and 'EndQuestMovie' are added to "both_reaction.c" to block all exits from the start of the encounter until you hand over the chest, and "quest_reaction.c" now blocks fast travel from when you finish talking to Silehard until you've been to the tavern. That's because the scene in which you meet Danielle (or Nathaniel, since you're playing a female character) takes place in a quest-specific duplicate of the tavern. If you fast-travel to the tavern, you'll be in the normal tavern, not the quest one, so you won't see Danielle/Nathaniel. A player who prefers to fast-travel everywhere and who teleports to the tavern right after talking to Silehard won't even meet the cursed pirates either. So, no fast-travel until you've met the cursed pirates, handed over the chest, then walked through the door into the quest tavern.
 

Attachments

  • quests.zip
    78.8 KB · Views: 22
Try these versions of "quests_reaction.c" and "both_reaction.c". A new pair of 'StartQuestMovie' and 'EndQuestMovie' are added to "both_reaction.c" to block all exits from the start of the encounter until you hand over the chest, and "quest_reaction.c" now blocks fast travel from when you finish talking to Silehard until you've been to the tavern. That's because the scene in which you meet Danielle (or Nathaniel, since you're playing a female character) takes place in a quest-specific duplicate of the tavern. If you fast-travel to the tavern, you'll be in the normal tavern, not the quest one, so you won't see Danielle/Nathaniel. A player who prefers to fast-travel everywhere and who teleports to the tavern right after talking to Silehard won't even meet the cursed pirates either. So, no fast-travel until you've met the cursed pirates, handed over the chest, then walked through the door into the quest tavern.
Also in the tavern and prison I can go onto the ship, which will also break the quest.
 

Attachments

  • 1719320173136.png
    1719320173136.png
    733.6 KB · Views: 22
  • 1719320355326.png
    1719320355326.png
    720.5 KB · Views: 20
Delete this line in case "to_quest_redmond_tavern_complete":
Code:
DisableFastTravel(false);    // And you can fast-travel again
And put it (minus the comment) in case "blaze_from_prison_to_residence_complete". That's when Silehard has talked to you in prison, then you teleport to the residence. Ideally fast travel should be enabled after he talks to you in the residence, but the dialog does not trigger another quest case. It just sets an attribute which will be recognised by Ines Diaz when you go to Nevis Pirate Settlement tavern. But the dialog with Silehard happens immediately after the teleport, so if anyone manages to fast travel before he talks, they're really determined to break the game - let them have their fun. :D
 
1) The new hero Gerald Blanc is not being translated.
2) As soon as I start talking to the townspeople, an entry is immediately written in the quest log stating that Raoul Reims was on the island. I don't even select the dialogue item about him. (6 line QC citizen_dialog.h)
3) I tried all the options for reputation and authority, but Ines never told me anything.
Go to tavern – talk to tavernkeeper – if you have the correct Reputation and Leadership Skill Level tavernkeeper will tell you what you need to know.
 

Attachments

  • 1719450591008.png
    1719450591008.png
    805.5 KB · Views: 18
  • 1719450865219.png
    1719450865219.png
    793 KB · Views: 17
Last edited:
1: In "RESOURCE\INI\TEXTS\RUSSIAN\Storyline\storyline_strings.txt", you'll probably find the untranslated "Gérald" and "Blanc" directly under the translated text for "Aveline" and "de_Grandpré". Translate it. ;)
2: In "PROGRAM\DIALOGS\QC citizen_dialog.c", find this line in case "first time":
Code:
AddQuestRecord("Blaze_search_Rheims", "12");
Move it to the top of case "search_rheims". And then check that the dialog line correctly ends by calling you "sir" or "ma'am". It's using a preprocessed variable and questbook entries sometimes mess those up. That is why the line to add it must be at the top of the dialog case, before the 'Preprocessor_Add' command.

Also, replace this:
Code:
link.l1 = DLG_TEXT[5] + characters[GetCharacterIndex(DLG_TEXT[6])].name + " " + characters[GetCharacterIndex(DLG_TEXT[7])].lastname + DLG_TEXT[8];
... with this...
Code:
link.l1 = DLG_TEXT[5] + GetMySimpleName(CharacterFromID(DLG_TEXT[6])) + DLG_TEXT[8];
It shouldn't make much difference here, but using "name" and "lastname" attributes directly can sometimes do odd things - better to use functions like 'GetMySimpleName'.

3: If I read the code properly, your reputation must be over 40, which is slightly below neutral. And your Leadership must be higher than 4. That's your Leadership - officers don't count, though bonus items might. Depending on what you say next, you may need Leadership higher than 5.

If your reputation is at least neutral and your Leadership is at least 5, and you're still not getting anything useful from Ines Diaz, upload a savegame before you talk to her and I'll see if I can figure out why.
 
2: In "PROGRAM\DIALOGS\QC citizen_dialog.c", find this line in case "first time":
Code:
AddQuestRecord("Blaze_search_Rheims", "12");
Move it to the top of case "search_rheims". And then check that the dialog line correctly ends by calling you "sir" or "ma'am". It's using a preprocessed variable and questbook entries sometimes mess those up. That is why the line to add it must be at the top of the dialog case, before the 'Preprocessor_Add' command.

Also, replace this:
Code:
link.l1 = DLG_TEXT[5] + characters[GetCharacterIndex(DLG_TEXT[6])].name + " " + characters[GetCharacterIndex(DLG_TEXT[7])].lastname + DLG_TEXT[8];
... with this...
Code:
link.l1 = DLG_TEXT[5] + GetMySimpleName(CharacterFromID(DLG_TEXT[6])) + DLG_TEXT[8];
It shouldn't make much difference here, but using "name" and "lastname" attributes directly can sometimes do odd things - better to use functions like 'GetMySimpleName'.
Yes, it works well now. But if I first ask about the news in the city, then there will be no dialogue about Reims.
3: If I read the code properly, your reputation must be over 40, which is slightly below neutral. And your Leadership must be higher than 4. That's your Leadership - officers don't count, though bonus items might. Depending on what you say next, you may need Leadership higher than 5.

If your reputation is at least neutral and your Leadership is at least 5, and you're still not getting anything useful from Ines Diaz, upload a savegame before you talk to her and I'll see if I can figure out why.
I tried again, but it didn't bring any results. In all cases, Ines says nothing and I have to go to the man on the street.
 

Attachments

  • -=Тест1=- Невис.7z
    553.4 KB · Views: 15
Yes, it works well now. But if I first ask about the news in the city, then there will be no dialogue about Reims.
That is correct. If you follow the dialog branch to information about the colony, the dialog goes into a loop in which you can ask about places, people, or the colony generally. You won't get to ask about Rheims again until you exit the dialog and then talk to the citizen again.
 
That is correct. If you follow the dialog branch to information about the colony, the dialog goes into a loop in which you can ask about places, people, or the colony generally. You won't get to ask about Rheims again until you exit the dialog and then talk to the citizen again.
But the repeated dialogue calls lines 5 and 15 of QC citizen_dialog.h.
 

Attachments

  • 1719501213219.png
    1719501213219.png
    823.2 KB · Views: 21
Back
Top