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

WIP Spanish translation

I think for some reason, the relation changes through console.c don't trigger a rumour/log entry, only the random ones. I manually made peace between Franc eand England and only got a rumour when they randomñy declared war again a couple days later, but then I realised some of the code in nations.c wasn't in place and had to redo it. Now I'm hoping for a new random change.

I see this in nations.c. If I change the 10 to 1000, would that mean a 100% chance of relations changes happening every day?
Code:
    if(rand(1000) < RELATION_CHANGE_PROBABILITY*10)            // do relation change
 
It depends on the value of 'RELATION_CHANGE_PROBABILITY'. If that's less than 1, it will make random changes a lot more likely but still not guaranteed. For absolute certainty, change that entire line to:
Code:
if(rand(1000) < 1001)
 
Incidentally, I had to make a new loading screen for "Brave Black Flag" for the Russian translation. With the scroll blanked and ready to accept translated text, it was easy to add a Spanish version as well. So, assuming the translation in "storyline_strings.txt" is correct:
Character_BraveBlackFlag.jpg
 
Nation relations tested and working. But a problem arises with the reasons for broken alliances. They are outside of the switch that handles the log but get added to it, so I applied XI_ConvertString and added them to interface_string.txt. To add each as one string I added preprocessors for the nations involved as with the logs themselves, but something is not right because the strings don't show up ingame
1682522578745.png

Here's the entire switch and at the end the strings for GetBreakAllianceReason with my edits. Everything in the switch works fine as far as I can tell (although I'm sure it could be streamlined) but I include it because the alliance break case (the last one) calls for GetBreakAllianceReason, in case my mistake is in there.
Code:
        // STEP 2: Figure out what to do with them
        Preprocessor_Add("nationnamei", XI_ConvertString(GetNationNameByType(i)));
        Preprocessor_Add("nationnamej", XI_ConvertString(GetNationNameByType(j)));
        Preprocessor_Add("nationdesci", XI_ConvertString(GetNationDescByType(i)));
        Preprocessor_Add("nationdescj", XI_ConvertString(GetNationDescByType(j)));
        Preprocessor_Add("nationtowni", XI_ConvertString(GetTownByNation(i)))
        switch(GetNationRelation(i,j))
        {
                case RELATION_ENEMY:

                logTitle = GetTranslatedLog("#snationnamei# and #snationnamej# make peace");
                logEntry = GetTranslatedLog("After some time of bloody warfare #snationnamei# and #snationnamej# have declared a ceasefire.");
                if(GetNationRelation2MainCharacter(i)==RELATION_FRIEND && GetNationRelation2MainCharacter(j)==RELATION_FRIEND) logEntry += " " + GetTranslatedLog("This is good news as it was a very hard time to keep friendly relations with two warfaring parties.");
                if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += GetTranslatedLog("\n \nAlthough good news in general, this is bad news for me. Attacking #snationdescj# ships and towns will not raise my reputation with the #snationdesci# anymore.");
                if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += "\n \nAlthough good news in general, this is bad news for me. Attacking #snationdesci# ships and towns will not raise my reputation with the #snationdescj# anymore.");
                WriteNewLogEntry(PreprocessText(logTitle), PreprocessText(logEntry), "General",false);
                newRelation = RELATION_NEUTRAL;
                break;
            case RELATION_NEUTRAL:
                random = rand(2);
                if(random==0)
                {
                    logTitle = GetTranslatedLog("#snationnamei# and #snationnamej# have allied");
                    logEntry = GetTranslatedLog("#snationnamei# and #snationnamej# have formed an alliance. Attacking ships or towns of either nation will also decrease the standing with the ally.");
                    if(GetNationRelation2MainCharacter(i)==RELATION_FRIEND && GetNationRelation2MainCharacter(j)==RELATION_FRIEND) logEntry += " " + GetTranslatedLog("Very good news, indeed. Working for the #snationdesci# and the #snationdescj#, as I currently do, my deeds will raise my standing with both nations.");
                    if(GetNationRelation2MainCharacter(i)==RELATION_ENEMY && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += " " + GetTranslatedLog("Whoops! It seems I have bothered them a little too much. But their alliance won't stop me.");
                    if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += GetTranslatedLog("\n \nThis makes working for the #snationdesci# somewhat more difficult, as sinking #snationdescj# ships is no longer an option.");
                    if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += GetTranslatedLog("\n \nThis makes working for the #snationdescj# somewhat more difficult, as sinking #snationdesci# ships is no longer an option.");
                    WriteNewLogEntry(PreprocessText(logTitle), PreprocessText(logEntry), "General",false);
                    newRelation = RELATION_FRIEND;
                }
                if(random==1)  // i declared war on j
                {
                    logTitle = GetTranslatedLog("#snationnamei# is at war with #snationnamej#");
                    logEntry = GetTranslatedLog("#snationnamei# has declared war on #snationnamej#. #snationdesci# ships have attacked a small #snationdescj# settlement, as I was told.");
                    if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += GetTranslatedLog("\n \nIt was about time to show those #snationnamej# landlubbers who's in charge in the caribbean!");
                    if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += GetTranslatedLog("Those bloody cowards! The next #snationnamei# ship we encounter will surely pay for this.");
                    WriteNewLogEntry(PreprocessText(logTitle), PreprocessText(logEntry), "General",false);
                    newRelation = RELATION_ENEMY;
                }
                if(random==2)  // j declared war on i
                {
                    logTitle = GetTranslatedLog("#snationnamej# is at war with #snationnamei#");
                    logEntry = GetTranslatedLog("#snationnamej# has declared war on #snationnamei#. #snationdescj# troops have landed near #snationtowni#, as I was told.");
                    if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += GetTranslatedLog("Those bloody cowards! The next #snationnamej# ship we encounter will surely pay for this.");
                    if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += GetTranslatedLog("\n \nIt was about time to show those #snationnamei# landlubbers who's in charge in the caribbean!");
                    WriteNewLogEntry(PreprocessText(logTitle), PreprocessText(logEntry), "General",false);
                    newRelation = RELATION_ENEMY;
                }
                break;
            case  RELATION_FRIEND:
                random = rand(2);
                if(random==0)
                {
                    logTitle = GetTranslatedLog("#snationnamei# and #snationnamej# broke their alliance");
                    logEntry = GetTranslatedLog("#snationnamei# and #snationnamej# have broken their alliance, but are currently peaceful. Observers report military activity on both sides, but so far an open conflict has been avoided.");
                    newRelation = RELATION_NEUTRAL;
                }
                if(random==1) // i broke the alliance
                {
                    logTitle = GetTranslatedLog("#snationnamei# and #snationnamej# broke their alliance");
                    logEntry = GetTranslatedLog("#snationnamei# and #snationnamej# have broken their alliance and are now at war! It was reported that #snationnamei# broke the alliance by")+ " " +GetBreakAllianceReason(i,j);
                    if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += GetTranslatedLog("\n \nThose treacherous bastards! The #snationdesci# will pay for this betrayal. I have ordered to open fire on sight of any #snationdesci# ship.");
                    WriteNewLogEntry(PreprocessText(logTitle), PreprocessText(logEntry), "General",false);
                    newRelation = RELATION_NEUTRAL;
                }
                if(random==2) // j broke the alliance
                {
                    logTitle = GetTranslatedLog("#snationnamej# and #snationnamei# broke their alliance");
                    logEntry = GetTranslatedLog("#snationnamej# and #snationnamei# have broken their alliance and are now at war! It was reported that #snationnamej# broke the alliance by")+ " " +GetBreakAllianceReason(j,i);
                    if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += GetTranslatedLog("\n \nThose treacherous bastards! The #snationdescj# will pay for this betrayal. I have ordered to open fire on sight of any #snationdescj# ship.");
                    WriteNewLogEntry(PreprocessText(logTitle), PreprocessText(logEntry), "General",false);
                    newRelation = RELATION_ENEMY;
                }
            break;
            Preprocessor_Delete("nationnamei");
            Preprocessor_Delete("nationnamej");
            Preprocessor_Delete("nationdesci");
            Preprocessor_Delete("nationdescj");
            Preprocessor_Delete("nationtowni");
        }

        // STEP 3: Change relation and match player if required
        SetNationRelationBoth(i, j, newRelation);
        if(ServedNation != PERSONAL_NATION)                // For any player that serves a specific nation
        {
            if(i == ServedNation || j == ServedNation)
            {
                if(i == ServedNation) i = j;            // Don't change your relation to your OWN nation
                SetNationRelation2MainCharacter(i, newRelation);
            }
        }

        // STEP 4: Notify the player that this happened the first time
        if(!CheckAttribute(PChar, "changing_relations_note"))    // PB: Add clarifying note
        {
            SetQuestHeader("changing_relations");
            AddQuestRecord("changing_relations", "1");
            CloseQuestHeader("changing_relations");
            PChar.changing_relations_note = 1;
        }
    }
    // PB: Rewritten to a maximum of one change per day <--
}

string GetBreakAllianceReason(int traitor, int victim)
{
    int random;
    Preprocessor_Add("nationdescv", XI_ConvertString(GetNationDescByType(victim)));
    Preprocessor_Add("nationnamet", XI_ConvertString(GetNationNameByType(traitor)));
    string sReasons[6];
    sReasons[0] = XI_ConvertString("'accidently' sinking the #snationdescv# military supply convoy.");
    sReasons[1] = XI_ConvertString("treating the #snationdescv# ambassador in a 'disrespectful' manner, as was reported from Europe.");
    sReasons[2] = XI_ConvertString("brutally burning down a small settlement of the #snationdescv#, leaving no one alive (I am curious how they got this report then?).");
    sReasons[3] = XI_ConvertString("officially knighting a notorious freebooter, who plundered the #snationdescv# colonies in the previous war.");
    sReasons[4] = XI_ConvertString("inciting a slave revolt in a major #snationdescv# colony.");
    sReasons[5] = XI_ConvertString("sending a horde of French squirrels with blond wigs to pillage a Spanish monastery.\n \n This doesn't make any sense at all and does not really explain why #snationnamet# broke their alliance, but that's what they did.");

    random = rand(5);
    return sReasons[random];
    Preprocessor_Delete("nationdescv");
    Preprocessor_Delete("nationnamet");
 
Last edited:
Nation relations tested and working. But a problem arises with the reasons for broken alliances. They are outside of the switch that handles the log but get added to it, so I applied XI_ConvertString and added them to interface_string.txt. To add each as one string I added preprocessors for the nations involved as with the logs themselves, but something is not right because the strings don't show up ingame

That's because 'XI_ConvertString' only looks at "common.ini". 'TranslateString' looks at various files including "interface_strings.txt". And 'GetTranslatedLog' checks "shipslog_strings.txt". I'd be surprised if 'GetBreakAllianceReason' is used anywhere other than to fill in the log for random alliances breaking, so perhaps put the translations into "shipslog_strings.txt" and use 'GetTranslatedLog' for those texts. Presumably everything else from 'RandomNationsRelationsChange' is going into "shipslog_strings.txt", so that would put everything related to logs about relation changes in one place.
 
Here's ChracterUtilite.c with all the log entries added to the Spanish shipslogstrings (I didn't add them to the English version, which I probably should have for the sake of other translations). Also I added the string "women like you" to common.ini, it's from Danielle's dialog and it wasn't in there, and a couple of small fixes to dialogs.
There's a slight problem with the version of "RESOURCE\INI\TEXTS\ENGLISH\common.ini" in your "promotion.zip". It's in Spanish. ;) I've added "Women like you" to my English version.
 
This includes
-All the ship logs from AIShip.c
-Updated utils.c with a Spanish-specific case for the date format
-sulan_shipslog with the translated date string for ship logs
-Updated English and Spanish shipslog_strings.txt (the English one could use a checkup, I literally copypasted twice the base English strings from the Spanish file and something may have slipped).
-English and Spanish common.ini with female titles (the Dutch and Swedish titles may be a little iffy) and a couple of other minor changes to the Spanish file, like lower case month names.
-English and Spanish interface_strings.txt because the Spanish file was missing some strings, and added the onscreen warning for attacking under a false flag from AIShip.c

Everything tested ok on my end after many missing brackets were added.
 

Attachments

  • misc.zip
    224.2 KB · Views: 56
Last edited:
One additional update which I've made in English:
Code:
string = Scourge of the Caribbean_f,"Wicked Wench of the West"
Sorry, but it had to be done - a combination of the original name of Jack Sparrow's ship and a character from "The Wizard of Oz" just seemed to fit so perfectly. :D Feel free to suggest female alternatives for other pirate "titles".

Spanish ranks and titles seem a bit confused in the Spanish translation:
Code:
string = Almirante General,"Capitán General"
string = Capitán General,"Almirante General de la Armada"
string = Caballero,"Hidalgo"
string = Baronet,"Caballero"

By comparison, in English:
Code:
string = Capitán General,"Capitán General"
string = Almirante General,"Almirante General de la Armada"
string = Hidalgo,"Hidalgo"
string = Caballero,"Caballero"

And in "nations_init.c":
Code:
    rNation.Ranks.11 = "Capitán General";
    rNation.Ranks.12 = "Almirante General";
Code:
    rNation.Titles.7 = "Hidalgo";
    rNation.Titles.8 = "Caballero";
Which should be the higher rank, Capitán General or Almirante General de la Armada? It would be best to put them in the correct order in "nations_init.c" and then translate them directly, rather than swap them round in the translation.

Spanish "common.ini" has no direct translation for "Hidalgo", so you'll either see "Hidalgo" anyway because 'TranslateString' returns the untranslated text if it can't find a match, or nothing at all because 'XI_ConvertString' returns nothing if it can't find a match. The translation for "Baronet" will either do nothing because it's already translated in the British section, or it will mess up British Baronets, and in any case it's not needed because the Spanish section of "nations_init.c" doesn't use it.

As far as I can tell from Wikipedia, Dutch has no female versions of titles, so "Ridder_f", "Erfridder_f" should just stay the same as the male titles. I've no idea about Swedish titles so "Riddarinna", "Friherrinna" etc. can go in. @Pieter Boelen, @Jack Rackham - any comments?
 
Spanish ranks and titles seem a bit confused in the Spanish translation:
Code:
string = Almirante General,"Capitán General"
string = Capitán General,"Almirante General de la Armada"
string = Caballero,"Hidalgo"
string = Baronet,"Caballero"
By comparison, in English:
Code:
string = Capitán General,"Capitán General"
string = Almirante General,"Almirante General de la Armada"
string = Hidalgo,"Hidalgo"
string = Caballero,"Caballero"
And in "nations_init.c":
Code:
rNation.Ranks.11 = "Capitán General";
rNation.Ranks.12 = "Almirante General";
Code:
rNation.Titles.7 = "Hidalgo";
rNation.Titles.8 = "Caballero";
Which should be the higher rank, Capitán General or Almirante General de la Armada? It would be best to put them in the correct order in "nations_init.c" and then translate them directly, rather than swap them round in the translation.
Don't know what happened there, nations_init and the English common.ini are correct, it's the Spanish file that seems to be out of date in that part. At first I just replaced the translations as a quick and dirty fix but then we added them properly to nations_init.c. That must have been three years ago but apparently I forgot to update the Spanish file accordingly.
 
As far as I can tell from Wikipedia, Dutch has no female versions of titles, so "Ridder_f", "Erfridder_f" should just stay the same as the male titles. I've no idea about Swedish titles so "Riddarinna", "Friherrinna" etc. can go in. @Pieter Boelen, @Jack Rackham - any comments?
For Dutch I found an article that (via google translate) cited "Ridderin" as a period term for a noblewoman or the wife of a knight (the article mentioned several other options and stressed none is perfectly accurate to a female knight but this at least seems to be historical), and most of the others appear in dictionaries, including wiktionary. But I'll happily defer to the native speakers on that one.
 
Last edited:
Where was that article? The only reference I found to "Ridderin" was on a forum in which someone was advising on fantasy writing and suggesting that as a female version of "Ridder" based on general Dutch language rules. On the other hand, from the Wikipedia article on "Knight":
Ridder, Dutch for "knight", is a hereditary noble title in the Netherlands. It is the lowest title within the nobility system and ranks below that of "Baron" but above "Jonkheer" (the latter is not a title, but a Dutch honorific to show that someone belongs to the untitled nobility). The collective term for its holders in a certain locality is the Ridderschap (e.g. Ridderschap van Holland, Ridderschap van Friesland, etc.). In the Netherlands no female equivalent exists.
Incidentally, this also suggests that the Dutch level 7 title should be "Jonkheer", "Ridder" should be level 8, and level 9 remain as "Baron" - similar to Spanish "Hidalgo", "Caballero", "Barón".

And for Pirates, could you translate "Wicked Wench of the West"?
 
Where was that article? The only reference I found to "Ridderin" was on a forum in which someone was advising on fantasy writing and suggesting that as a female version of "Ridder" based on general Dutch language rules. On the other hand, from the Wikipedia article on "Knight":
Similar context, also advice for writers Ridster, ridderin of ridderes?
Is 'Ridderin' a better choice then? The word is similar to ‘herderin’ ('shepherdess') or ‘keizerin’ ('empress').
'Ridderin' turns out to be an old word. The historical Dictionary of the Dutch Language states; 'Ridderin, a woman of nobility (...), or: the wife of a knight'.
So the word Ridderin was once in use, but had a different meaning
I think it's a similar case to chevaleresse. A rare occurrence so there's not a standardized official title for it. But if the case were to occur, I believe they'd use a feminine word, not just reuse the masculine form. Especially if the language in question is hevaily gendered and has rules for precisely that kind of thing, even if it wasn't official or widespread because it didn't agree with the social roles at the time. For example, when "caballera" is used in Spanish historically, it's often in a humourous or informal tone.

And for Pirates, could you translate "Wicked Wench of the West"?

I'm not sure the joke would translate well. Apparently the name of the ship was translated as «Jovencita Traviesa» (Mischievous Girl) in Spain and «Bruja del Mar» (Sea Witch) in Latin America, which don't fit great with the Wizard of Oz pun (which itself isn't such a recognized cultural headstone for the Spanish speaking world).
 
Similar context, also advice for writers Ridster, ridderin of ridderes?
From the same source:
Firstly, it is established that there is no common feminine form for 'knight' and therefore you could use 'knight' as a gender-neutral word.

I'm not sure the joke would translate well. Apparently the name of the ship was translated as «Jovencita Traviesa» (Mischievous Girl) in Spain and «Bruja del Mar» (Sea Witch) in Latin America, which don't fit great with the Wizard of Oz pun (which itself isn't such a recognized cultural headstone for the Spanish speaking world).
The joke was just based on something which randomly went through my head, sounded good, and inspired the female pirate title - it doesn't need to translate. Google translates "Wicked Wench of the West" as "Malvada Moza del Oeste", so if there's no better translation, we may as well use that. There are several other pirate titles waiting to be given female alternatives, so you could always add in a joke one which works in Spanish but not in English. (We've already done that once, for something completely different. Character model "33_Ronal2" gets the name "Ron" and the description "He's big, he's bad, and he can out-drink anyone!" because "Ron" is Spanish for "Rum".)
 
Yeah I know, but Scourge of the xxx and its translation are completely neutral gender-wise so it doesn't really need it. Without the context of the joke "Malvada Moza del Oeste" or other jokes I can think of don't have the same punch that the highest pirate titles should have. I'll have a think about it, but I'll rather keep the Scourge titles than a joke that doesn't really land
 
Last edited:
Thanks, @Jack Rackham!

What about Borgmästare, Landshövding and Riksråd? I'm not sure if they're even valid, they're what we currently use for Sweden's level 10, 11 and 12 titles. Britain uses Viscount, Earl and Marquis - the Swedish titles don't need to be exact equivalents, just something for privateers to earn at the highest levels. If Greve is the equivalent of Count (level 11) then we need something else at level 9, where other nations have Baron.
 
Back
Top