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

Raise different pirate flags

Jack Rackham

ex train dispatcher
Quest Writer
Storm Modder
I want to raise different pirate flags on land. I get the Rackham style always. It doesn't matter
what I try to choose.

@Pieter you helped me with the swedish flag for Kristiania, which is a personal flag. I can change that personal flag to something else and it works. But when I try to do the same but for pirate flags it doesn't work. (Rackham flag only)

Do you know if it's possible at all? :pflag
 
I recall having a very, VERY hard time with pirate flags on shore showing up properly at all.
From what I remember, in the end I had to use a shortcut so that a pirate flag on shore is always the "fort flag", which is indeed always the Rackham one.
Maybe it does actually work somewhat now, since stuff has changed since then.

What exactly do you want to accomplosh? And what have you tried so far?
For Kristiania, we had to set a governor for the town and then set the appropriate custom flag for him, right?
I imagine something very similar would be needed here.

Just so you know, user "Pieter" is someone else. ;)
 
It's not Kristiania I want to change, only using it to test the function.

Test1
This is the code for Kristiania:
Code:
ref ch = CharacterFromID("Swedish Guy");
    ch.nation = PERSONAL_NATION;
    ch.Flags.Personal = 3;
    ch.Flags.Personal.texture = 4;
    Towns[GetTownIndex("Khael Roa")].gov = "Swedish Guy";

If I change it to
Code:
ref ch = CharacterFromID("Swedish Guy");
    ch.nation = PIRATE;
    ch.Flags.Pirate = 3;
    ch.Flags.Pirate.texture = 4;
    Towns[GetTownIndex("Khael Roa")].gov = "Swedish Guy";

I don't even get a pirate flag but this one: see picture (another personal flag)

Test2
It's here I want to do something interesting with different pirate flags. Specially Teach's.
If I use the commander from Turks (which is PIRATE nation already) I get the Rackham pirate flag
whatever values I choose.
 

Attachments

  • test1.jpg
    test1.jpg
    513.2 KB · Views: 159
  • test2.jpg
    test2.jpg
    430.9 KB · Views: 120
Test1
This is the code for Kristiania:
Code:
ref ch = CharacterFromID("Swedish Guy");
ch.nation = PERSONAL_NATION;
ch.Flags.Personal = 3;
ch.Flags.Personal.texture = 4;
Towns[GetTownIndex("Khael Roa")].gov = "Swedish Guy";
If I change it to
Code:
ref ch = CharacterFromID("Swedish Guy");
ch.nation = PIRATE;
ch.Flags.Pirate = 3;
ch.Flags.Pirate.texture = 4;
Towns[GetTownIndex("Khael Roa")].gov = "Swedish Guy";
I don't even get a pirate flag but this one: see picture (another personal flag)
Did you try that in combination with CaptureTownForNation with PIRATE?
Note that the governor's nation doesn't actually matter. The town nation is what controls what flag to show.
The governor is just the one that is used to figure out what custom flag to show.
 
Did you try that in combination with CaptureTownForNation with PIRATE?
Then test1 looks like test2: Rackham's flag always.

What I can do is change which personal flag the Khael Roa gov is using. For ex the irish harp flag.
Maybe I can work things around by adding another row of personal flags (looking like pirate ones).
 
Maybe I can work things around by adding another row of personal flags (looking like pirate ones).
Don't. Not for now anyway.
Custom pirate flags work for ships. Maybe we can give it another shot to get them working for forts too. In theory, it should be possible.
For starters, I need to look up the relevant code. Should be easy enough to find, once I am at home again.
 
Note that there is already a 7th row in place, starting with my Brandenburg flag. The rest of that row is free to use - currently just blank flags with a choice of pennant styles to copy. It might not be a good idea to use the whole lot as that will prevent anyone else from devising a new Personal flag except by replacing an existing one, as the system probably doesn't support more than 7 rows.

I suspect the reason the Rackham flag always appears on the fort is that if you look at "frtflg*.tga.tx", the PIRATE fort flag in all periods is the Rackham flag. If you change that, all PIRATE forts will show the Teach flag (or whatever you change it to).
 
I suspect the reason the Rackham flag always appears on the fort is that if you look at "frtflg*.tga.tx", the PIRATE fort flag in all periods is the Rackham flag. If you change that, all PIRATE forts will show the Teach flag (or whatever you change it to).
That is indeed the reason. I had a very hard time getting forts to use pirate flags properly,
so eventually got fed up and decided to just give them all the same one just to be done with it.

Actually.... thinking back on that again now, I'm not at all looking forward to having to dive into that once more.
Especially not considering the amount of other stuff that I should be doing. :modding

Still, it should be possible. In theory.
It works for Personal Flags, so the relevant Pirate code should probably just be adapted to match with Personal instead.
 
Relevant code is in PROGRAM\BATTLE_INTERFACE\Flags.c:
Code:
ref procGetRiggingData()
{
   int n;
   int retVal = 0;
   int locidx = FindLoadedLocation();
   bool PirateOverride = false;                               // PB: For Pirate Flags on Forts and Ashore
   ref chr;

   string datName = GetEventData();
   if (datName == "GetFlagTexNum") {
     n = GetEventData();
     n = GetEventData();
     if (n == SHIP_FLAG || n == SHIP_PENNANT) {
       if (locidx < 0)
         chr = GetCharacter(Ships[CurrentShip]);
       else
         chr = GetCharacter(iShips[CurrentShip]);
       if (ShipFlagsQuantity == -1) {
         ShipFlagsQuantity = GetShipFlagsQuantity(chr);
         bShipWithoutPennants = ShipWithoutPennants(chr);
         if (!bShipWithoutPennants) ShipFlagsQuantity *= 2;
         CurrentFlag = 0;
       }
       int pos = CurrentFlag;
       if (n == SHIP_PENNANT) {
         pos -= (ShipFlagsQuantity / 2);
       }
       string FlagType = GetShipFlagType(chr, pos);
       if (bShipWithoutPennants) {
         if (n == SHIP_PENNANT) FlagType = FLAG_ENSIGN;
         if (FlagType == FLAG_PENNANT) {
           n = SHIP_FLAG;
           FlagType = FLAG_ENSIGN;
         }
       }
       CurrentFlag++;
       if (FlagType == FLAG_NONE) {
         retVal = FLAGS_NULL_PICTURE_TEXTURE_INDEX;
         return &retVal;
       }
       if (FlagType == FLAG_ENSIGN && n == SHIP_PENNANT) {
         retVal = FLAGS_NULL_PICTURE_TEXTURE_INDEX;
         return &retVal;
       }
       if (FlagType == FLAG_PENNANT && n == SHIP_FLAG && bShipWithoutPennants == false) {
         retVal = FLAGS_NULL_PICTURE_TEXTURE_INDEX;
         return &retVal;
       }
     } else {
       chr = GetCharacter(n);
       PirateOverride = true;                               // PB: For Pirate Flags on Forts and Ashore
     }
     n = sti(chr.nation);
     switch (n)
     {
       case HOLLAND:  retVal = 0;  break;
       case ENGLAND:  retVal = 1;  break;
       case FRANCE:  retVal = 2;  break;
       case PORTUGAL:  retVal = 3;  break;
       case SPAIN:  retVal = 4;  break;
       case PIRATE:
         if(PirateOverride) retVal = 6;                         // PB: For Pirate Flags on Forts and Ashore
         else        retVal = GetPirateFlag(chr, &n);  break;
       case GUEST1_NATION:  retVal = 5;  break;
       case GUEST2_NATION:  retVal = 6;  break;
       case PRIVATEER_NATION: retVal = GetPersonalFlag(chr, &n);  break;
       case UNKNOWN_NATION:  retVal = FLAGS_NULL_PICTURE_TEXTURE_INDEX; break;     //added by KAM     // changed after build 11 by KAM
       case NEUTRAL_NATION:  retVal = FLAGS_NULL_PICTURE_TEXTURE_INDEX; break;     //added by KAM
       case PERSONAL_NATION:  retVal = GetPersonalFlag(chr, &n);  break;
     }
   }
   return &retVal;
}
Note that 'PirateOverride' boolean, which is the main thing responsible for this behaviour.

You could try to replace this:
Code:
      case PIRATE:
         if(PirateOverride) retVal = 6;                         // PB: For Pirate Flags on Forts and Ashore
         else        retVal = GetPirateFlag(chr, &n);  break;
With this:
Code:
      case PIRATE:  retVal = GetPirateFlag(chr, &n);  break;

I can give no guarantees that will work though. There must be a very good reason I added such an ugly hack just to make it work. :facepalm

If anyone wants to look into fixing it properly, probably the most relevant code is in PROGRAM\SEA_AI\AIShip.c, specifically the 'CreateFlagEnvironment' function.

I did some huge simplifying of the Different Flags code as it refused to behave itself for some reason.
Refer also to this outcommented section in PROGRAM\Towns\Towntable.c:
Code:
void InitTownTable(bool first)
{
   int i, flagidx, flagtex;
   ref rTown;
   ref mchr = GetMainCharacter();
   string stmp = "Towns\InitTowns.c";
   if (LoadSegment(stmp)) {
     InitTowns(first);
     UnloadSegment(stmp);
   }
   stmp = GetStorylinePath(FindCurrentStoryline());
   if (FindFile("PROGRAM\" + stmp + "Towns", "*.c", "InitTowns.c") != "") {
     stmp += "Towns\InitTowns.c";
     if (LoadSegment(stmp)) {
       InitTowns(first);
       UnloadSegment(stmp);
     }
   }
   for (i = 0; i < TOWNS_QUANTITY; i++)
   {
     rTown = GetTownByIndex(i);
     // PB: Pirate and Personal Towns Always Same Flag -->
/*     if (GetTownNation(rTown.id) == PIRATE) {
       if (!CheckAttribute(rTown, "Flags.Pirate")) rTown.Flags.Pirate = rand(FLAGS_PICTURES_QUANTITY_PER_TEXTURE - 2); // PB: -2 to prevent Jack Sparrow flag in random encounters
       if (!CheckAttribute(rTown, "Flags.Pirate.texture")) rTown.Flags.Pirate.texture = rand(PIRATEFLAGS_TEXTURES_QUANTITY - 1);
       flagidx = GetPirateFlag(mchr, &flagtex);
       if (sti(rTown.Flags.Pirate.texture) == flagtex && sti(rTown.Flags.Pirate) == flagidx) {
         if (flagidx == 0)
           rTown.Flags.Pirate = flagidx + 1;
         else
           rTown.Flags.Pirate = flagidx - 1;
       }
     }*/
/*     if (GetTownNation(rTown.id) == PRIVATEER_NATION) {
       if (!CheckAttribute(rTown, "Flags.Personal")) rTown.Flags.Personal = rand(FLAGS_PICTURES_QUANTITY_PER_TEXTURE - 1);
       if (!CheckAttribute(rTown, "Flags.Personal.texture")) rTown.Flags.Personal.texture = rand(PERSONALFLAGS_TEXTURES_QUANTITY - 1);
       flagidx = GetPersonalFlag(mchr, &flagtex);
       if (sti(rTown.Flags.Personal.texture) == flagtex && sti(rTown.Flags.Personal) == flagidx) {
         if (flagidx == 0)
           rTown.Flags.Personal = flagidx + 1;
         else
           rTown.Flags.Personal = flagidx - 1;
       }
     }*/
     // PB: Pirate and Personal Towns Always Same Flag <--
   }
}
 
Note that there is already a 7th row in place, starting with my Brandenburg flag. The rest of that row is free to use
I thought of that but couldn't even get the Brandenburg flag to appear.
I can't get any flags at all from perflg6 or perflg7 to show up.

in globals:
#define PERSONALFLAGS_TEXTURES_QUANTITY 7
So those flags should be available. :confused:
 
I thought of that but couldn't even get the Brandenburg flag to appear.
I can't get any flags at all from perflg6 or perflg7 to show up.
What are you trying? I'm pretty sure they work through F2>Nation Relations for the player ship(s), right?
 
Okay, I tried that and it gave another fortflag. (portugese which corresponds to the numbers below)

Code:
CaptureTownForNation("Khael Roa", PIRATE);
    ref ch = CharacterFromID("Swedish Guy");
    ch.nation = PIRATE;
    ch.Flags.Pirate = 3;
    ch.Flags.Pirate.texture = 4;
    Towns[GetTownIndex("Khael Roa")].gov = "Swedish Guy";

Maybe I could use the black (empty) spot in one of the 4 first fortflags.
Either black or modded as Teach's.
 
Okay, I tried that and it gave another fortflag. (portugese which corresponds to the numbers below)
Ah, probably this section in Flags.c needs to be edited too:
Code:
void SetTownFlag(ref loc, object mdl)
{
   int i, idx, iNation;
   string town;
   ref chr;
   if (!CheckAttribute(loc, "townsack")) return;
   SendMessage(&Flag, "li", MSG_FLAG_DEL_GROUP, &mdl);
   SendMessage(&MerchantFlag, "li", MSG_FLAG_DEL_GROUP, &mdl);
   for (i = 0; i < PIRATEFLAGS_TEXTURES_QUANTITY; i++)
   {
     if (IsEntity(&PirateFlag[i])) SendMessage(&PirateFlag[i], "li", MSG_FLAG_DEL_GROUP, &mdl);
     if (IsEntity(&PiratePennant[i])) SendMessage(&PiratePennant[i], "li", MSG_FLAG_DEL_GROUP, &mdl);
   }
   for (i = 0; i < PERSONALFLAGS_TEXTURES_QUANTITY; i++)
   {
     if (IsEntity(&PersonalFlag[i])) SendMessage(&PersonalFlag[i], "li", MSG_FLAG_DEL_GROUP, &mdl);
     if (IsEntity(&PersonalPennant[i])) SendMessage(&PersonalPennant[i], "li", MSG_FLAG_DEL_GROUP, &mdl);
   }
   SendMessage(&FortFlag, "li", MSG_FLAG_DEL_GROUP, &mdl);
   town = loc.townsack;
   iNation = GetTownNation(town);
   idx = GetTownGovernorIndex(town);
   if (idx < 0) idx = GetTownFortCommanderIndex(town, 0);
   if (idx < 0) idx = GetMainCharacterIndex();
   chr = GetCharacter(idx); // PB
   switch (iNation) {
/*     case PIRATE:
       GetPirateFlag(chr, &i);
       SendMessage(&PirateFlag[i], "lil", MSG_FLAG_INIT, &mdl, idx);
     break;
     case PRIVATEER_NATION:
       GetPersonalFlag(chr, &i);
       SendMessage(&PersonalFlag[i], "lil", MSG_FLAG_INIT, &mdl, idx);
     break;*/
     case PERSONAL_NATION:
       GetPersonalFlag(chr, &i);
       SendMessage(&PersonalFlag[i], "lil", MSG_FLAG_INIT, &mdl, idx);
     break;
     // default:
       SendMessage(&FortFlag, "lil", MSG_FLAG_INIT, &mdl, idx);
   }
}
Try removing the /* and */ around that 'PIRATE' section. That might help.
 
I was testing the Brandenburg flag on land. Much the same way the swedish
flag works ok in Kristiania.

Code:
ref ch = CharacterFromID("Swedish Guy");
    ch.nation = PERSONAL_NATION;
    ch.Flags.Personal = 0;                               //first one from left
    ch.Flags.Personal.texture = 6;                //perflg7
    Towns[GetTownIndex("Khael Roa")].gov = "Swedish Guy";

Empty flagpole.
 
I was testing the Brandenburg flag on land. Much the same way the swedish
flag works ok in Kristiania.
The Swedish flag is the same as the actual player personal flag, right?
Tests you could try:
1. Use a different flag in the same row as the Swedish flag
2. Use a different flag in another row

It could be that #1 does work, but #2 doesn't.
Which can probably be fixed in some way. But everything related to the Different Flags mod is very tricky and finicky. :facepalm
 
Tried it but sorry. Empty pole.
Did you try from something that works too? I've got a suggestion in my post above.
While I do have some idea of how this all works, there are still some very definite mysteries about it.
 
Works.

No other rows work.
Then I've got a fair idea of WHY it doesn't work.
Apparently the alternate texture isn't loaded in the memory and therefore isn't available.

Fixing it will be a bit trickier though, since then we need to know WHY that texture isn't being loaded in the memory.
 
What does the "ch.Flags.Personal.texture" attribute do? I thought the personal flag was entirely controlled by "ch.Flags.Personal". For example, from "initModels.c", specifically the definition for Johan Elting:
Code:
model.Flags.Personal = 9;
That translates to second row, third flag, which indeed is Elting's personal flag - the one with red, black, red horizontal stripes and three white X's on the black stripe. Likewise, for Roxanne Lalliere:
Code:
model.Flags.Pirate = 27;
model.Flags.Personal = 40;
So the pirate flag would be fourth row, flag 7, while the personal flag would be sixth row, flag 6 - the red flag with the white mermaid and the red flag with the yellow cross, respectively.
 
Back
Top