• 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 Improve the Crewmembers on Shore Mod

Then I think this check makes more sense:
Code:
if (IsInServiceOf(PIRATE))
That one checks if you officially joined the pirates.

I've put it in there.

I do believe so. That should NEVER return true until you're Famous; after that, it gets up to around 50% chance by the time you've reached the maximum fame level.

Allright, that kind of works, but i would rather have it start at 0% chance and grow increasingly more likely as you grow more famous. Should i make it >1 then?
 
Maybe:
Code:
if ( frnd() < makefloat(GetRankFromPoints(GetScore(PChar)))/12.0 )
 
Maybe:
Code:
if ( frnd() < makefloat(GetRankFromPoints(GetScore(PChar)))/12.0 )

Ahh, i see. The higher your fame, the close it comes to 1, thus the easier it becomes for a value between 0 and 1 to be smaller than 1, thus the easier it becomes to get recognised.

This should be the pirate dialogues fixed then, barring bugtests. Now we just need to do the guards, patrols and sailors. :facepalm That's the ones that have been edited in beta 4 quite a bit too. Here's the stuff for the pirates, in any case. I should say i won't have any more time for this for a while though. I'll be gone until sunday evening.
 

Attachments

  • random_pirates_group_dialog.c
    2.8 KB · Views: 133
  • random_pirates_group_dialog.h
    2.4 KB · Views: 122
  • Like
Reactions: jsv
Say @Levis, when you modified random_guards_group_dialog.c, what did you do with the rest of it? There used to be a whole section dedicated to flase flags in there, unless i'm confusing it with the random patrols, which are distinctly different from the guards.

I've spotted some minor things that needed adjusting in the files concerning the guards, but i've left all the smuggling-related stuff alone. Please check if there wasn't some really recent update to these files that i've missed. The smuggling system is being constantly modified right now, so it's quite likely.

I'll reupload all of these files in a proper zipfile with file directories once i'm done with all of them, but here's the new guard files:
 

Attachments

  • random_guards_group_dialog.c
    5.6 KB · Views: 124
  • random_guards_group_dialog.h
    2.9 KB · Views: 116
The smuggling system is being constantly modified right now, so it's quite likely.
Actually, apart from some fine-tuning a few weeks ago, that one is not really being worked on anymore now. Partly also because nobody provides feedback on it anymore.
It has mainly been Levelling now, which is proving a tough nut to crack indeed. :shock
 
Actually, apart from some fine-tuning a few weeks ago, that one is not really being worked on anymore now. Partly also because nobody provides feedback on it anymore.
It has mainly been Levelling now, which is proving a tough nut to crack indeed. :shock

'a few weeks ago' is probably still ever so slightly more recent that what i'm working with, though not by much at worst. That's why it would be good if Levis could give it a look.
 
'a few weeks ago' is probably still ever so slightly more recent that what i'm working with, though not by much at worst. That's why it would be good if Levis could give it a look.
It HAS been changed in Beta 4 compared to Beta 3.4 yes, that's for sure.
 
That's no problem. The files i'm uploading are from beta 4, just without the random assortment of fixes that have been posted on the forums in the meantime.
I don't think there have been (m)any updates to those files since 8 Dec. Anyway, I can take care of any potential differences there. :doff
 
Okay, so i'm working on the sailors now, and their dialogue is a complete and utter mess. I'm rebuilding this thing from the ground up, and i'm pleased to say it's actually going quite well. I need to know what this is for though:

Code:
makeint(GetLocationNationFromID(NPchar.location))!=3)

The way things are going now means that that piece of code is going to be left out, so i need to know if it's important.
 
I need to know what this is for though:

Code:
makeint(GetLocationNationFromID(NPchar.location))!=3)

The way things are going now means that that piece of code is going to be left out, so i need to know if it's important.
I've already changed that in some instances, because that is just MASSIVELY confusing coding.
What it is meant to do is:
Code:
makeint(GetLocationNationFromID(NPchar.location))!=PIRATE)
Because "PIRATE" is defined as nation 3. But it is much clearer to just use the text. :facepalm

Anyway, it checks if you are in a pirate location or not.
 
I've already changed that in some instances, because that is just MASSIVELY confusing coding.
What it is meant to do is:
Code:
makeint(GetLocationNationFromID(NPchar.location))!=PIRATE)
Because "PIRATE" is defined as nation 3. But it is much clearer to just use the text. :facepalm

Anyway, it checks if you are in a pirate location or not.

That would imply that sailors from any nation can randomly show up in the taverns of pirate towns. Is that true? If so, that doesn't make sense, since the dialogue implies that the sailor takes offence to you also being there, which is massively hypocritical.

This actually makes me wonder how the dialogue tree works for pirate sailors. They seem to be handled differently from the rest. The code, minus a bit at the bottom (which currently works properly, therefore left unchanged), currently looks like this:

Code:
void ProcessDialogEvent()
{
   ref NPChar;
   aref Link, Diag;

   DeleteAttribute(&Dialog,"Links");

   makeref(NPChar,CharacterRef);
   makearef(Link, Dialog.Links);
   makearef(Diag, NPChar.Dialog);

   ref PChar;
   PChar = GetMainCharacter();
   int loc_id = FindLocation(PChar.location);
   string nationme, nationhim;

   int maxCrewquantity = GetMaxCrewQuantity(PChar);
   int maxcrew = GetMaxLandCrew(sti(PChar.Ship.Crew.Quantity));

   switch(Dialog.CurrentNode)
   {
     case "exit":
       Diag.CurrentNode = Diag.TempNode;
       DialogExit();
       //if(Npchar.middlename!=""){LAi_tmpl_SetFollow(Npchar, CharacterFromId(Npchar.middlename), 120000);}
     break;

     case "first time":
       Dialog.defAni = "dialog_stay1";
       Dialog.defCam = "1";
       Dialog.defSnd = "dialogs\0\017";
       Dialog.defLinkAni = "dialog_1";
       Dialog.defLinkCam = "1";
       Dialog.defLinkSnd = "dialogs\woman\024";
       Dialog.ani = "dialog_stay2";
       Dialog.cam = "1";
       Dialog.snd = "voice\PADI\PADI001";

       MyFlag = GetCurrentFlag();
       int MyNation = PERSONAL_NATION;
       int MyFlag = GetCurrentFlag();
       if(GetFlagRMRelation(sti(Npchar.nation)) <= REL_WAR && rand(10)>8) //MT: if you're at war with the nation the sailor belongs to
       {
         if (frnd() < GetChanceDetectFalseFlag()
         {
           switch(makeint(Npchar.nation))
           {
           case 0 : LAi_group_SetRelation("ENGLAND_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_068.wav");}nationhim="english";break;
           case 1 : LAi_group_SetRelation("FRANCE_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_a_065.wav");}nationhim="french";break;
           case 2 : LAi_group_SetRelation("SPAIN_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_057.wav");}nationhim="spanish";break;
           case 4 : LAi_group_SetRelation("DOUWESEN_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_058.wav");}nationhim="dutch";break;
           case 5 : LAi_group_SetRelation("CONCEICAO_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_a_056.wav");}nationhim="portuguese";break;
           case 6 : LAi_group_SetRelation("AMERICA_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_068.wav");}nationhim="english";break;
           }
           LAi_group_SetRelation(LAI_GROUP_GUARDS, LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
           Dialog.Text = DLG_TEXT[13] + GetMyFullName(PChar) + DLG_TEXT[14];
           Link.l1 = DLG_TEXT[15] + NationHim + DLG_TEXT[16];
           Link.l1.go = "exit";
           LAi_group_SetRelation("random_sailors_group", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
           if(GetRMRelation(PChar, PIRATE) >= REL_NEUTRAL)
           {
             LAi_group_SetRelation("random_pirates_group", "random_sailors_group", LAI_GROUP_ENEMY);
           }
           if(loc_id != -1 && locations[loc_id].type == "tavern")
           {
             LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false);
             Random_Raid("soldiers", 5, makeint(NPchar.nation),"enemy","friend","");
           }
         }
         else
         {
           if (IsInServiceOf(PIRATE))   // PB: Link this to acting as a pirate MT: modified as of 15-12-2015. Same functionality
           {
             Dialog.Text = DLG_TEXT[10] + GetMyFullName(PChar) + DLG_TEXT[11];
             Link.l1 = RandSwear() + DLG_TEXT[12];
             Link.l1.go = "exit";
             switch(makeint(Npchar.nation))
             {
               case 0 : LAi_group_SetRelation("ENGLAND_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_052.wav");}break;
               case 1 : LAi_group_SetRelation("FRANCE_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_a_052.wav");}break;
               case 2 : LAi_group_SetRelation("SPAIN_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_043.wav");}break;
               case 4 : LAi_group_SetRelation("DOUWESEN_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_043.wav");}break;
               case 5 : LAi_group_SetRelation("CONCEICAO_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_a_043.wav");}break;
               case 6 : LAi_group_SetRelation("AMERICA_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_052.wav");}break;
             }
             LAi_group_SetRelation(LAI_GROUP_GUARDS, LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
             LAi_group_SetRelation("random_sailors_group", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
             if(loc_id != -1 && locations[loc_id].type == "tavern")
             {
               LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false);
               Random_Raid("soldiers", 5, makeint(NPchar.nation),"enemy","friend","");
             }
           }
           else
           {
             switch(mynation)
             {
             case 0 : nationme="english";break;
             case 1 : nationme="french";break;
             case 2 : nationme="spanish";break;
             case 3 : nationme="pirate";break;
             case 4 : nationme="dutch";break;
             case 5 : nationme="portuguese";break;
             case 10 : nationme="pirate";break;
             }
             LAi_group_SetRelation("random_sailors_group", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
             switch(makeint(Npchar.nation))
             {
             case 0 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_052.wav");}nationhim="english";break;
             case 1 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_a_052.wav");}nationhim="french";break;
             case 2 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_043.wav");}nationhim="spanish";break;
             case 4 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_043.wav");}nationhim="dutch";break;
             case 5 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_a_043.wav");}nationhim="portuguese";break;
             }
             Dialog.Text = DLG_TEXT[17] + nationhim + DLG_TEXT[18] + nationme + DLG_TEXT[19];
             Link.l1 = DLG_TEXT[20] + NationHim + DLG_TEXT[21];
             Link.l1.go = "exit";
             if(loc_id != -1 && locations[loc_id].type == "tavern")
             {
               LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false);
             }
           }
         }   
       }   
       else //MT: If you're NOT at war with the nation the sailor belongs to
       {
         if (HaveLetterOfMarque(sti(Npchar.nation)))
         {
           if(frnd()<makefloat(GetRankFromPoints(GetScore(PChar)))/12.0) //MT: LoM with sailor's nation and famous
           {
             Dialog.Text = DLG_TEXT[0];
           }
           else
           {
             Dialog.Text = DLG_TEXT[1]; //MT: If LoM, but not famous
           }           
           if(Pchar.Ship.Crew.Quantity<maxCrewquantity)
           {
             Link.l1 = DLG_TEXT[2];
             Link.l1.go = "engage";
             Link.l2 = DLG_TEXT[3];
             Link.l2.go = "exit";
           }
           else
           {
             Link.l1 = DLG_TEXT[4];
             Link.l1.go = "exit";
           }
           switch(makeint(Npchar.nation))
           {
             case 0 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_b_080.wav");}break;
             case 1 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_c_073.wav");}break;
             case 2 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_004.wav");}break;
             case 3 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_a_062.wav");}break;
             case 4 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_068.wav");}break;
             case 5 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_b_062.wav");}break;
           }
         }
         else //MT: if you don't have a LoM with the nation the sailor belongs to, and you're not at war with it
         {
           if(frnd()<makefloat(GetRankFromPoints(GetScore(PChar)))/12.0)
           {
             Dialog.Text = DLG_TEXT[0];
           }
           else
           {
             Dialog.Text = DLG_TEXT[30]; //MT: String of dialogue added for when you don't serve the crown, as line 1 would imply
           }           
           if(Pchar.Ship.Crew.Quantity<maxCrewquantity)
           {
             Link.l1 = DLG_TEXT[2];
             Link.l1.go = "engage";
             Link.l2 = DLG_TEXT[3];
             Link.l2.go = "exit";
           }
           else
           {
             Link.l1 = DLG_TEXT[4];
             Link.l1.go = "exit";
           }
           switch(makeint(Npchar.nation))
           {
             case 0 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_b_080.wav");}break;
             case 1 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_c_073.wav");}break;
             case 2 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_004.wav");}break;
             case 3 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_a_062.wav");}break;
             case 4 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_068.wav");}break;
             case 5 : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_b_062.wav");}break;
           }
         }
       }     
       Diag.TempNode = "first time";
     break;

In this, case 3 seems to be intended for pirates, even though there's a case 10 for pirates as well in one particular instance. I should probably remove that, since it isn't being referenced anywhere. Looking at the code, it seems case 3 is never referenced for situations where the sailors go hostile, meaning that the pirate sailors will never attack you. I suppose that's okay? They're pirates, after all. Not exactly the most patriotic bunch.

I'm also wondering if this bit
Code:
            {
             case 0 : nationme="english";break;
             case 1 : nationme="french";break;
             case 2 : nationme="spanish";break;
             case 3 : nationme="pirate";break;
             case 4 : nationme="dutch";break;
             case 5 : nationme="portuguese";break;
             case 10 : nationme="pirate";break;
             }
shouldn't be established sooner. The cases are referenced before this bit shows up, which was the case in the original file before i started modding it, but that doesn't seem quite right. With my limited knowledge i can't say for certain though.

As an aside, lines 26-29 aren't called up in this tree anywhere, yet seem to have been added quite recently:

Code:
"That raid of yours ruined my store! We'd been waiting for that cargo for weeks! I'm not letting you slip by now that I have my chance!",
"En garde!",
"Hey... hey guys. Bet that guy's got quite a bounty on his head. I say we get him!",
"Too rich for your blood!",

I assume this is for some other mod that uses the same dialogue file, so i've left them in, but it seems a bit odd.
 
That would imply that sailors from any nation can randomly show up in the taverns of pirate towns. Is that true? If so, that doesn't make sense, since the dialogue implies that the sailor takes offence to you also being there, which is massively hypocritical.
What dialog file are you working on? I imagine that file can be triggered in both pirate and non-pirate towns.
Apparently there was meant to be different behaviour for pirates, so that check is in place to find out if you're in a pirate place.

Probably you could just check GetLocationNation != PIRATE or sti(NPChar.nation) != PIRATE instead.
I don't know if that particular dialog file could end up used for a pirate character in a non-pirate port or the other way around.

I'm also wondering if this bit
Code:
            {
             case 0 : nationme="english";break;
             case 1 : nationme="french";break;
             case 2 : nationme="spanish";break;
             case 3 : nationme="pirate";break;
             case 4 : nationme="dutch";break;
             case 5 : nationme="portuguese";break;
             case 10 : nationme="pirate";break;
             }
shouldn't be established sooner. The cases are referenced before this bit shows up, which was the case in the original file before i started modding it, but that doesn't seem quite right. With my limited knowledge i can't say for certain though.
At the very least, the numbers there should be replaced with ENGLAND/FRANCE/SPAIN/Etc. instead.
But there are functions to give the "nation describe" with a simple function call and then no switch is needed at all.
Can't remember the name by the top of my head; probably GetNationDescribe(sti(PChar.nation)) and GetNationDescribe(sti(NPChar.nation)) .
Search PROGRAM\Nations\nations.c for "describe" to find the correct function name though.

As an aside, lines 26-29 aren't called up in this tree anywhere, yet seem to have been added quite recently:

Code:
"That raid of yours ruined my store! We'd been waiting for that cargo for weeks! I'm not letting you slip by now that I have my chance!",
"En garde!",
"Hey... hey guys. Bet that guy's got quite a bounty on his head. I say we get him!",
"Too rich for your blood!",

I assume this is for some other mod that uses the same dialogue file, so i've left them in, but it seems a bit odd.
That looks like something @Levis added quite a while back for an early version of the "Fetch Quests". But that isn't used anymore.
If it isn't used, feel free to remove it or overwrite it.
 
What dialog file are you working on? I imagine that file can be triggered in both pirate and non-pirate towns.
Apparently there was meant to be different behaviour for pirates, so that check is in place to find out if you're in a pirate place.

random_sailors_group_dialog.c, which concerns the sailors you can find sitting around in a tavern. I haven't found them anywhere else in the game so far. As for the check, i could figure out a way to put that functionality back in.

Probably you could just check GetLocationNation != PIRATE or sti(NPChar.nation) != PIRATE instead.
I don't know if that particular dialog file could end up used for a pirate character in a non-pirate port or the other way around.

Looking at how the code used to be, it seems that you could have sailors of any nationality in a pirate town, or at least that's what the dialogue was designed to deal with. Wether they can actually spawn there i don't know.

At the very least, the numbers there should be replaced with ENGLAND/FRANCE/SPAIN/Etc. instead.
But there are functions to give the "nation describe" with a simple function call and then no switch is needed at all.
Can't remember the name by the top of my head; probably GetNationDescribe(sti(PChar.nation)) and GetNationDescribe(sti(NPChar.nation)) .
Search PROGRAM\Nations\nations.c for "describe" to find the correct function name though.

I've found GetNationDescByType. Does that mean it should look like this?
Code:
else
           {
             LAi_group_SetRelation("random_sailors_group", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
             Dialog.Text = DLG_TEXT[17] + GetNationDescByType(sti(NPChar.nation)) + DLG_TEXT[18] + GetNationDescByType(sti(PChar.nation)) + DLG_TEXT[19];
             Link.l1 = DLG_TEXT[20] + GetNationDescByType(sti(NPChar.nation)) + DLG_TEXT[21];
             Link.l1.go = "exit";
             if(loc_id != -1 && locations[loc_id].type == "tavern")
             {
               LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false);
             }
           }

instead of this?

Code:
else
           {
             switch(mynation)
             {
             case ENGLAND : nationme="english";break;
             case FRANCE : nationme="french";break;
             case SPAIN : nationme="spanish";break;
             case PIRATE : nationme="pirate";break;
             case DUTCH : nationme="dutch";break;
             case PORTUGUESE : nationme="portuguese";break;
             }
             LAi_group_SetRelation("random_sailors_group", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
             switch(makeint(Npchar.nation))
             {
             case ENGLAND : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_052.wav");}nationhim="english";break;
             case FRANCE : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_a_052.wav");}nationhim="french";break;
             case SPAIN : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_043.wav");}nationhim="spanish";break;
             case DUTCH : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_043.wav");}nationhim="dutch";break;
             case PORTUGUESE : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_a_043.wav");}nationhim="portuguese";break;
             }
             Dialog.Text = DLG_TEXT[17] + nationhim + DLG_TEXT[18] + nationme + DLG_TEXT[19];
             Link.l1 = DLG_TEXT[20] + nationhim + DLG_TEXT[21];
             Link.l1.go = "exit";
             if(loc_id != -1 && locations[loc_id].type == "tavern")
             {
               LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false);
             }
           }

That does mean the sound effects aren't triggered anywhere. It also means that sailors belonging to the pirate nation will always have the same reaction as those not belonging to the pirates, which was not originally intended. In fact, looking at the original code makes me really confused as to what the pirate sailors were originally meant to do. Do pirate sailors even exist in this game?

I'm also unsure of what to do with america. They seem to be ignored in about half the code.

That looks like something @Levis added quite a while back for an early version of the "Fetch Quests". But that isn't used anymore.
If it isn't used, feel free to remove it or overwrite it.

I'll wait for levi's judgement on that one. For now i've simply added a comment.
 
Looking at how the code used to be, it seems that you could have sailors of any nationality in a pirate town, or at least that's what the dialogue was designed to deal with. Wether they can actually spawn there i don't know.
You'd have to search the PROGRAM folder for the name of that dialog file. That would allow you to track down the code that creates the characters that use it.
Be sure to use tip #3 here: Tutorial - Modding Tips & Tricks | PiratesAhoy!

I've found GetNationDescByType. Does that mean it should look like this?
Code:
else
           {
             LAi_group_SetRelation("random_sailors_group", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
             Dialog.Text = DLG_TEXT[17] + GetNationDescByType(sti(NPChar.nation)) + DLG_TEXT[18] + GetNationDescByType(sti(PChar.nation)) + DLG_TEXT[19];
             Link.l1 = DLG_TEXT[20] + GetNationDescByType(sti(NPChar.nation)) + DLG_TEXT[21];
             Link.l1.go = "exit";
             if(loc_id != -1 && locations[loc_id].type == "tavern")
             {
               LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false);
             }
           }

instead of this?

Code:
else
           {
             switch(mynation)
             {
             case ENGLAND : nationme="english";break;
             case FRANCE : nationme="french";break;
             case SPAIN : nationme="spanish";break;
             case PIRATE : nationme="pirate";break;
             case DUTCH : nationme="dutch";break;
             case PORTUGUESE : nationme="portuguese";break;
             }
             LAi_group_SetRelation("random_sailors_group", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
             switch(makeint(Npchar.nation))
             {
             case ENGLAND : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_052.wav");}nationhim="english";break;
             case FRANCE : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_a_052.wav");}nationhim="french";break;
             case SPAIN : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_043.wav");}nationhim="spanish";break;
             case DUTCH : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_043.wav");}nationhim="dutch";break;
             case PORTUGUESE : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_a_043.wav");}nationhim="portuguese";break;
             }
             Dialog.Text = DLG_TEXT[17] + nationhim + DLG_TEXT[18] + nationme + DLG_TEXT[19];
             Link.l1 = DLG_TEXT[20] + nationhim + DLG_TEXT[21];
             Link.l1.go = "exit";
             if(loc_id != -1 && locations[loc_id].type == "tavern")
             {
               LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false);
             }
           }
I think that would pretty much work. You may want to check if you should use the "nation describe" (English) or the "nation name" (England).

That does mean the sound effects aren't triggered anywhere.
If you want to keep the sounds, keep that switch ONLY for that and do away with the rest.
But if they're always the same sound files used in different dialogs, it may be nicer to make a "PlayNationSound(int iNation)" function out of it.
That is usually better than having the same section of code copied into different dialogs.

Also, the code names are "HOLLAND" and "PORTUGAL". Check PROGRAM\globals.c for the actual list that is used.
There you would find also "AMERICA" and "PERSONAL_NATION", for example.


It also means that sailors belonging to the pirate nation will always have the same reaction as those not belonging to the pirates, which was not originally intended. In fact, looking at the original code makes me really confused as to what the pirate sailors were originally meant to do. Do pirate sailors even exist in this game?
Now you know why those files haven't been touched in a while. They ARE confusing. So you're doing a grand job at making sense of them. :onya

If you use the trick I mention above, you should be able to figure out where this dialog file is actually used.
I figure that pirate sailors SHOULD exist. After all, why not? But whether they DO is a different question altogether. ;)

I'm also unsure of what to do with america. They seem to be ignored in about half the code.
Much better to have support for them in place as well. Or ensure any switches have a "default" option like this:
Code:
             switch(makeint(Npchar.nation))
             {
             case ENGLAND : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_052.wav");}break;
             case FRANCE : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_a_052.wav");}break;
             case SPAIN : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_043.wav");}break;
             case HOLLAND: if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_043.wav");}break;
             case PORTUGAL: if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_a_043.wav");}break;
             //default:
             if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_052.wav");}
             }
Of course anything after "//" doesn't DO anything; I always just add that in similar cases to explain what it does to people looking at the code. ;)
 
You'd have to search the PROGRAM folder for the name of that dialog file. That would allow you to track down the code that creates the characters that use it.
Be sure to use tip #3 here: Tutorial - Modding Tips & Tricks | PiratesAhoy!

It's led me to LEnc_monsters.c (which was the only file it was referenced in besides the dialogue files themselves), which had this little line:
Code:
    if(nation==3){chr.nation=rand(5);}

Does that imply that if a sailor belongs to the pirate nation, it gets turned into a random one? The full code is here:

void Random_sailors_group(int bmax, int nation)
{
if(bmax==0) return;
//Log_SetStringToLog("sailors group");

ref chr, chr_prec;
float hasgun;
string ani, group, locator;
hasgun = 0.5;
ani = "man";
group = "goto";

for(int i = 0; i < bmax; i++)
{
locator = LAi_FindRandomLocator(group); //Levis moved in the loop to spread them more
chr=LAi_CreateFantomCharacterEx(false, 0, true, true, hasgun, GetRandomModelForTypeExSubCheck(1, "sailors", ani, nation), ani, group, locator);
if(i==0)
{
chr.middlename = "";
chr_prec = CharacterFromId(chr.id);
}
//LAi_SetWarriorType(chr);
//if(rand(10)>9)
//{
//chr.Dialog.filename="Smuggler Agent_dialog.c";
//chr.greeting = "Gr_Smuggler Agent";
//}
//else
//{
//Disabled for now because of to much brawls
//if(rand(10)>7)
//{
chr.Dialog.filename="Enc_walker.c";
//}
//else
//{
// chr.Dialog.Filename = "Random_sailors_group_dialog.c";
//}
//}
//LAi_warrior_DialogEnable(chr, true);
LAi_SetCivilianPatrolType(chr);
if(nation==3){chr.nation=rand(5);}
else{chr.nation = nation;}
//chr.sex ="man";
//if(chr.sex=="woman"){chr.ani="woman";}
//if(i>0){LAi_tmpl_SetFollow(chr, chr_prec, 120000);chr.middlename = chr_prec.id;}
LAi_group_MoveCharacter(chr, "random_sailors_group");
}
LAi_group_SetRelation(LAI_GROUP_PLAYER, "random_sailors_group", LAI_GROUP_NEITRAL);
LAi_group_SetRelation("random_pirates_group", "random_sailors_group", LAI_GROUP_NEITRAL);
LAi_group_SetRelation(LAI_GROUP_GUARDS, "random_sailors_group", LAI_GROUP_NEITRAL);
LAi_group_SetRelation(LAI_DEFAULT_GROUP, "random_sailors_group", LAI_GROUP_NEITRAL);
LAi_group_SetRelation(LAI_GROUP_MONSTERS, "random_sailors_group", LAI_GROUP_NEITRAL);
LAi_group_SetRelation(GetCurrentCitizenGroup(), "random_sailors_group", LAI_GROUP_NEITRAL);
LAi_group_SetRelation(GetCurrentSoldierGroup(), "random_sailors_group", LAI_GROUP_NEITRAL);
}

Weirdly enough, the line actually referencing Random_sailors_group_dialog.c has been commented out, despite the fact that i am most certainly seeing the dialogue in-game. I really don't know what's going on there. Also, NEUTRAL is constantly spelled wrong. Might be intentional, might not. Who knows? Comments at the start of the file suggest that noone who dared work with the file understood what exactly was going on.

I think that would pretty much work. You may want to check if you should use the "nation describe" (English) or the "nation name" (England).

That would indeed be describe then. Allright.

But if they're always the same sound files used in different dialogs, it may be nicer to make a "PlayNationSound(int iNation)" function out of it.

I have no idea how to do this. Do i just replace the whole switch and cases with "PlayNationSound(int iNation)" , including the bit between brackets, copy and paste (minus the " ")? Would this just play a random nationality-appropriate sound, or does that sound need to be defined somewhere? There's different sounds for aggressive and friendly reactions.

Also, the code names are "HOLLAND" and "PORTUGAL". Check PROGRAM\globals.c for the actual list that is used.
There you would find also "AMERICA" and "PERSONAL_NATION", for example.

Much better to have support for them in place as well. Or ensure any switches have a "default" option like this:
Code:
             switch(makeint(Npchar.nation))
             {
             case ENGLAND : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_052.wav");}break;
             case FRANCE : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_a_052.wav");}break;
             case SPAIN : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_043.wav");}break;
             case HOLLAND: if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_043.wav");}break;
             case PORTUGAL: if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_a_043.wav");}break;
             //default:
             if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_052.wav");}
             }
Of course anything after "//" doesn't DO anything; I always just add that in similar cases to explain what it does to people looking at the code. ;)

Done and done.

I'm somewhat tempted to just throw the special treatment for the pirates out the window and make them act like the sailors of any other nation. The only thing stopping me is stuff like this:

Code:
        if (frnd() < GetChanceDetectFalseFlag()
         {
           switch(makeint(Npchar.nation))
           {
           case ENGLAND : LAi_group_SetRelation("ENGLAND_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_068.wav");}break;
           case FRANCE : LAi_group_SetRelation("FRANCE_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_a_065.wav");}break;
           case SPAIN : LAi_group_SetRelation("SPAIN_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_057.wav");}break;
           case HOLLAND : LAi_group_SetRelation("DOUWESEN_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_058.wav");}break;
           case PORTUGAL : LAi_group_SetRelation("CONCEICAO_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_a_056.wav");}break;
           case AMERICA : LAi_group_SetRelation("AMERICA_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_068.wav");}break;
           }
           LAi_group_SetRelation(LAI_GROUP_GUARDS, LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
           Dialog.Text = DLG_TEXT[13] + GetMyFullName(PChar) + DLG_TEXT[14];
           Link.l1 = DLG_TEXT[15] + GetNationDescByType(sti(NPChar.nation)) + DLG_TEXT[16];
           Link.l1.go = "exit";
           LAi_group_SetRelation("random_sailors_group", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
           if(GetRMRelation(PChar, PIRATE) >= REL_NEUTRAL)
           {
             LAi_group_SetRelation("random_pirates_group", "random_sailors_group", LAI_GROUP_ENEMY);
           }
           if(loc_id != -1 && locations[loc_id].type == "tavern")
           {
             LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false);
             Random_Raid("soldiers", 5, makeint(NPchar.nation),"enemy","friend","");
           }
         }

As you can see, there is no case for PIRATE at the top. Instead, something else is done with it further down that i don't quite understand. Is that bit only triggered if it doesn't find the sailor's nationality amongst the cases, in this case PIRATE? This bit originally had a check to see if you were in a pirate location as well, which i might put back in, once i fully understand what was orignally meant to happen with pirate sailors.
 
It's led me to LEnc_monsters.c (which was the only file it was referenced in besides the dialogue files themselves), which had this little line:
Code:
    if(nation==3){chr.nation=rand(5);}

Does that imply that if a sailor belongs to the pirate nation, it gets turned into a random one? The full code is here:
Effectively that reduces the chance of a pirate sailor, but doesn't eliminate it; that would have required a while loop.
Because rand(5) CAN return 3 again, which makes it a pirate anyway.

If that code IS to be used, this would be much better:
Code:
rand(NATIONS_QUANTITY-1)
Also, I see no particular need for reducing the chance of pirates. Should be fully eliminated or simply allowed.

Weirdly enough, the line actually referencing Random_sailors_group_dialog.c has been commented out, despite the fact that i am most certainly seeing the dialogue in-game. I really don't know what's going on there.
Indeed it IS commented out. And I see absolutely no other reference to it in the game.
How can you be sure that it IS used in the game? Aren't you looking at a dialog file that is very similar?
Or are you seeing your changes take effect? That'd be odd. I'm probably missing something there.... o_O

Also, NEUTRAL is constantly spelled wrong. Might be intentional, might not. Who knows?
Just another of those "consistent typos" throughout the code that @Grey Roger mentioned. Game was made by Russians, remember. ;)

I have no idea how to do this. Do i just replace the whole switch and cases with "PlayNationSound(int iNation)" , including the bit between brackets, copy and paste (minus the " ")? Would this just play a random nationality-appropriate sound, or does that sound need to be defined somewhere? There's different sounds for aggressive and friendly reactions.
The function I describe doesn't yet exist. But if you can find some consistency in the sounds used, we could MAKE it.
Would end up looking something like:
Code:
void PlayNationSound(int iNation, bool bFriendly)
{
   if (bFriendly)
   {
     switch(makeint(Npchar.nation))
     {
       case ENGLAND : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_052.wav");}break;
       case FRANCE  : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_a_052.wav");}break;
       case SPAIN  : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_043.wav");}break;
       case HOLLAND : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_043.wav");}break;
       case PORTUGAL: if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_a_043.wav");}break;
       //default:
       if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_052.wav");}
     }
   }
   else
   {
     // Similar to above, but with other sounds
   }
}
Then you call it with:
Code:
PlayNationSound(sti(NPChar.nation), true);
Or false if it is not friendly.

I'm somewhat tempted to just throw the special treatment for the pirates out the window and make them act like the sailors of any other nation.
If that is OK for the dialog, then why not? No need making this more complicated than it needs to be.

Additionally, this section of code could be simplified too:
Code:
switch(makeint(Npchar.nation))
{
case ENGLAND : LAi_group_SetRelation("ENGLAND_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_068.wav");}break;
case FRANCE : LAi_group_SetRelation("FRANCE_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_a_065.wav");}break;
case SPAIN : LAi_group_SetRelation("SPAIN_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_057.wav");}break;
case HOLLAND : LAi_group_SetRelation("DOUWESEN_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_058.wav");}break;
case PORTUGAL : LAi_group_SetRelation("CONCEICAO_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_a_056.wav");}break;
case AMERICA : LAi_group_SetRelation("AMERICA_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_068.wav");}break;
}
You could use this instead:
Code:
LAi_group_SetRelation(GetSoldiersName(sti(NPChar.nation))+"_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
PlayNationSound(sti(NPChar.nation), false);
Much shorter, much less confusing and would end up doing pretty much exactly the same thing.

As you can see, there is no case for PIRATE at the top. Instead, something else is done with it further down that i don't quite understand. Is that bit only triggered if it doesn't find the sailor's nationality amongst the cases, in this case PIRATE? This bit originally had a check to see if you were in a pirate location as well, which i might put back in, once i fully understand what was orignally meant to happen with pirate sailors.
Apparently that code is trying to NOT set the pirates ashore hostile to you, unless you are actually NOT hostile with the pirates.
Which to me sounds like it does exactly the opposite of what I'd expect.

If this is just a prelude to a tavern brawl, I don't think all those LAi group relations need touching at all.
Those can be tricky because they turn ALL town guards hostile to you, even after you leave the location.
I think.... there are some ancient bugs related to AI group relations, so I'm not quite sure what it does and doesn't do....
 
How can you be sure that it IS used in the game? Aren't you looking at a dialog file that is very similar?
Or are you seeing your changes take effect? That'd be odd. I'm probably missing something there.... o_O

Well, as it turns out i actually HAVE been looking at the wrong file. I was supposed to be working in Random_sailors_sit_tavern_dialog, not random_sailors_group_dialog. The dialogue is, as it turns out, extremely similar, hence the confusion. Fortunately this also means it's code is quite similar, but i'll have to do some very thorough checking to make sure. What a waste.

You could use this instead:
Code:
LAi_group_SetRelation(GetSoldiersName(sti(NPChar.nation))+"_SOLDIERS", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
PlayNationSound(sti(NPChar.nation), false);
Much shorter, much less confusing and would end up doing pretty much exactly the same thing.

But that would include the function that doesn't exist yet. I think i'll just try to get this to work first, escpecially since the sounds are not all that consistent.

Apparently that code is trying to NOT set the pirates ashore hostile to you, unless you are actually NOT hostile with the pirates.
Which to me sounds like it does exactly the opposite of what I'd expect.

If this is just a prelude to a tavern brawl, I don't think all those LAi group relations need touching at all.
Those can be tricky because they turn ALL town guards hostile to you, even after you leave the location.
I think.... there are some ancient bugs related to AI group relations, so I'm not quite sure what it does and doesn't do....

Once i get the dialogue working, it'll be easier to see where any bugs might show up. Until then i'll just leave anything i don't understand the way it is.
 
Well, as it turns out i actually HAVE been looking at the wrong file. I was supposed to be working in Random_sailors_sit_tavern_dialog, not random_sailors_group_dialog. The dialogue is, as it turns out, extremely similar, hence the confusion. Fortunately this also means it's code is quite similar, but i'll have to do some very thorough checking to make sure. What a waste.
In the end, they both could use updating anyway. If the dialog does what we'd WANT it to, it can be restored to proper use.
Which would make it NOT a waste, but actually restoring lost functionality! :cheers

But that would include the function that doesn't exist yet. I think i'll just try to get this to work first, escpecially since the sounds are not all that consistent.
Yes, it would. It is simple enough to add that function somewhere though.
But if it is truly different every time, then you can skip the function and just have switches for ONLY the sounds in the dialog files.

Once i get the dialogue working, it'll be easier to see where any bugs might show up. Until then i'll just leave anything i don't understand the way it is.
Fair enough. :doff
 
Back
Top