• 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 New Passenger Transfer Interface

Looks like I’ve made an error somewhere, but it’s certainly an interesting one. When making one of my officers the captain of a companion ship, they remain as an officer. This should obviously not be the case, which would be for balance reasons since there appears to be no conflicts at all.

I’m also wondering about removing officers from the passenger list, which would mean they cannot be transferred at all unless they are removed from their officer slot. What options are there for achieving this? One idea I have is to go so far as removing them as a passenger altogether, and thus reinstating them when they are removed as an officer. This should be absolutely fine considering in the above situation the officer is not in the passenger list but will quite happily follow me around and command their ship as well.
 
I know some quest characters, such as Danielle Greene, can be in command of their own ship AND follow you around ashore as well.
If that character dies ashore, I think you'll then lose that ship too.
For an immortal quest character, that is a non-issue, but for regular officers/companions I am not sure you should want that....
 
The function you probably want is 'RemovePassenger(ref _refCharacter,ref _refPassenger)', defined in "PROGRAM\Characters\CharacterUtilite.c". "_refCharacter" is the character who owns the passenger list, normally the player character. "_refPassenger" is the passenger being removed. For example, in "Hornblower", 'RemovePassenger(pchar, characterFromID("Lt. Uriah Quelp"));' removes Lt. Uriah Quelp from your passenger list.

To add someone as a passenger, you can use 'AddPassenger(ref _refCharacter,ref _refPassenger, int prisonFlag)'. "prisonFlag" determines whether the person is a normal passenger, or a prisoner who will appear in your cargo hold and can be ransomed. You'll probably want that to be 0 if you're putting one of the player's officers back in the passenger list! So, also in "Hornblower", 'AddPassenger(Pchar, characterFromID("Patrick Harper"), 0);' puts Patrick Harper into your passenger list but not into your hold.
 
So if I set the prisoner flag then they won’t show in the passenger list? Wait, I think they will because they are still passengers and are still officers.

Okay, so the passenger enumeration function uses GetNotCaptivePassenger, so no they won’t be displayed.

I suppose officers aren’t exactly “passengers”, they’re not just random clutter around the ship are they? I think removing them as passengers altogether is a very viable and logical thing to do. This would affect the player’s main passenger interface, but I’d have thought it would be easy enough to run a second function, well placing it above so that they are displayed first. It just doesn’t make sense that they appear in a transfer situation.

Will setting them as prisoners affect anything? I don’t know much about how the captive system works, I should probably look into it.
 
Last edited:
So if I set the prisoner flag then they won’t show in the passenger list?
[...]
Will setting them as prisoners affect anything? I don’t know much about how the captive system works, I should probably look into it.
They'll show up either way. It just adds an attribute and skips the skill update:
Code:
     if(prisonFlag==true)   _refPassenger.prisoned = true;
     else
     {
       for(i = 0; i < 10; i++)
       {
         string skillName = GetSkillName(i);
         ResetPartySkill(_refCharacter, skillName); // PB: Let's be careful here and reset ONLY party skill (could also be ResetSkillModifier/ResetEffectiveSkill)
       }
     }

I suppose officers aren’t exactly “passengers”, they’re not just random clutter around the ship are they? I think removing them as passengers altogether is a very viable and logical thing to do. This would affect the player’s main passenger interface, but I’d have thought it would be easy enough to run a second function, well placing it above so that they are displayed first. It just doesn’t make sense that they appear in a transfer situation.
"Passengers" is the wrong word; technically it is ALL characters on the ship, so "Passengers and Officers".
(Should in theory include crew as well, but they're not generally treated as individual characters.)
 
Basically, this is the problem (see the comments)...
Code:
void FillScroll()
{
   curScrollNum = -1
   GameInterface.passengers_list.current = 0
   GameInterface.passengers_list.NotUsed = 5
   GameInterface.passengers_list.ImagesGroup.t0 = "EMPTYFACE"
   FillFaceList("passengers_list.ImagesGroup",refShip1,0) // <---------- This serves no purpose, see next
   FillFaceList("passengers_list.ImagesGroup",refShip1,2) // <---------- This is what causes officers to be listed - only line needed
   FillFaceList("passengers_list.ImagesGroup",refShip1,1) // <---------- Also useless, captains are never listed anyway
   GameInterface.passengers_list.BadTex1 = FindFaceGroupNum("passengers_list.ImagesGroup","EMPTYFACE")
}

void RefillScroll()
{
   for (i=0; i<charQuantity; i++) {
     string attributeName = "passengers_list.pic"+(i+1)
     DeleteAttribute(&GameInterface, attributeName)
   }
   charQuantity = 0
   while (GetNotCaptivePassenger(refShip1,charQuantity) >= 0 ) { // < ---------- This is where I can set a flag for officers as well
     charRef = GetCharacter(GetNotCaptivePassenger(refShip1,charQuantity))
     string attrName = "pic"+(charQuantity+1)
     GameInterface.passengers_list.(attrName).img1 = GetFacePicName(charRef)
     GameInterface.passengers_list.(attrName).tex1 = FindFaceGroupNum("passengers_list.ImagesGroup","FACE128_"+charRef.FaceId)
     charQuantity++
   }
   GameInterface.passengers_list.ListSize = charQuantity
   if (bNewInterface) {
     GameInterface.passengers_list.BadPic1 = "emptyface_new"
   }
   else {
     GameInterface.passengers_list.BadPic1 = "emptyface"
   }
}
 
Last edited:
I think the idea must have been to have shore party officers show first, then non-prisoned passengers (e.g. officers) and then prisoners last
(you do need those in the Passengers screen if you don't use the "Visit Deck" option).

Not sure if companions should be shown there at all, nor their officers.

If officers show because they are passengers also, maybe that happens because the same character can't show twice?
Then maybe replace this in PROGRAM\INTERFACE\utilite.c:
Code:
   if(fillCode==2 || fillCode == 3) // passengers; Aconcagua: added 3 (2: all, 3 only non-prisoned ones)
   {
     q = GetPassengersQuantity(chref);
     for(n=0; n<q; n++)
     {
       cn = GetPassenger(chref,n);
       if( cn>=0 && !IsOfficer(&Characters[cn])) {
With this:
Code:
   if(fillCode==2 || fillCode == 3) // passengers; Aconcagua: added 3 (2: all, 3 only non-prisoned ones)
   {
     q = GetPassengersQuantity(chref);
     for(n=0; n<q; n++)
     {
       cn = GetPassenger(chref,n);
       if( cn>=0 && !IsOfficer(&Characters[cn])) {

It doesn't look like that fillCode 3 actually serves its purpose either, does it?
But that appears to never actually be used either.

The addition of "governors" and "fort commandants" also doesn't make so much sense to me right now.... :confused:
 
Code:
 if( cn>=0 && !IsOfficer(&Characters[cn]))
That looks like exactly what I need! Except all passengers are still being listed even if I remove the entire function. Eh, it made me reload my save, then the interface died horribly because the function doesn’t exist. :unsure

Anyway, I might look at that code and see if it can be tweaked a bit. You’re right, case 3 does nowt.
 
Last edited:
Scrap that, the FillFace function simply attaches the faces (although this might still be relevant), it’s the other bit which cycles through all the passengers that is the issue.
 
@Pieter - this might work...
Code:
   if (fillCode==2) {
     q = GetNotCaptivePassengersQuantity(chref);
     for (n=0; n<q; n++)  {
       cn = GetNotCaptivePassenger(chref,n);
       if (cn>=0 && !IsOfficer(&Characters[cn]) && !IsPrisoner(&Characters[cn])) {
         AddFaceGroup(strAccess,"FACE128_"+Characters[cn].faceID);
       }
     }
   }

   if (fillCode == 3) {
     q = GetPassengersQuantity(chref);
     for (n=0; n<q; n++) {
       cn = GetPassenger(chref,n);
       if (cn>=0 && !IsOfficer(&Characters[cn]) && IsPrisoner(&Characters[cn])) {
         AddFaceGroup(strAccess,"FACE128_"+Characters[cn].faceID);
       }
     }
   }
Since the list-filling functions use GetNotCaptivePassenger then it makes perfect sense.
 
Last edited:
Okay, so this is what happens if I make my officer captive. I suppose this could be tweaked in the passenger interface to not be displayed if the “captive” is an officer, but I do wonder if there could be unforeseen consequences of doing this (mutiny? hehe). I also cannot make him an officer unless I release him, but I guess the point is that he would be an officer anyway theoretically-speaking.

As you might have guessed, I had to force the passenger interface to display prisoners, suffice to say that I can now use the prisoner method to not display them in a transfer scenario. Still, I’m thinking to go with completely removing them as a passenger, it feels better that way.
 

Attachments

  • Untitled.jpg
    Untitled.jpg
    179.3 KB · Views: 114
Last edited:
Not having prisoners in the passengers interface breaks the button functionality to ransom them.
I know that is possible through dialog too, but not everyone might use that.
 
I personally hate using dialogue if there is an interface option.

If I use the remove passenger option then upon reinstating them they will appear at the end of the passenger list, which would probably annoy people if they like to organise it (myself included). I don’t think this is an option. The prisoner flag looks like the best option, and actually I’ve noticed that it is used elsewhere (like to stop ships sinking in certain scenarios).

As for ransoming them, are you talking about after capturing a ship? If so, would it be fixable by checking whether or not the second ship is currently a companion? Or do you mean the player’s own list on the character menu?
 
I personally hate using dialogue if there is an interface option.
Dialog is more "realistic". Also more time-consuming to use, of course.
Preferences, preferences. That's why we've got a toggle on it. :cheeky

If I use the remove passenger option then upon reinstating them they will appear at the end of the passenger list, which would probably annoy people if they like to organise it (myself included). I don’t think this is an option.
I'd like prisoners to show up last in the passenger scroll list.
From what I understand, that is how it was meant to work (even if it doesn't) and that sounds fine to me.

As for ransoming them, are you talking about after capturing a ship? If so, would it be fixable by checking whether or not the second ship is currently a companion? Or do you mean the player’s own list on the character menu?
I mean, if you capture an enemy captain, you can ransom him for money either through dialog or from those interface buttons.
If the guy doesn't show up in the Passengers menu anymore, then you also can't press those buttons there anymore either.
My recommendation: Just keep prisoners included. Doesn't do any harm. :shrug
 
There are two separate matters here. One is whether or not they are listed at all, and in the case of passengers.c they will be because the relevant function uses GetPassenger as opposed to GetNotCaptivePassenger. The other issue is their faces, and this could indeed be an problem so I’ll have to think about it. Also, it’s not about real captives but rather setting the prisoner flag on officers which stops them from being listed. As for capturing ships, I need to check into this as well. Also, remember that what I’m concerned with here is companion-to-companion transfers, and it was already not possible to list prisoners because GetNotCaptivePassenger is used - or is that something which should change?
 
Last edited:
In the Passengers interface itself, it should be fine to list officers, passengers and prisoners.
In any Transfer/Ransack interfaces, including prisoners wouldn't really make any sense though,
 
Yep, and what I’m suggesting won’t impact upon either. I think the main thing to worry about is the use of GetPassenger versus GetNotCaptivePassenger.
 
:monkeydance
Code:
void MakeOfficersCaptive(ref refShip1)
{
   for (int i=0; i<GetNotCaptivePassengersQuantity(refShip1); i++) {
     ref refChar = GetCharacter(GetPassenger(refShip1,i))
     if (IsOfficer(refChar)) {
       refChar.prisoned = true
     }
   }
}
void MakeOfficersFreed(ref refShip1)
{
   for (int i=0; i<GetPassengersQuantity(refShip1); i++) {
     ref refChar = GetCharacter(GetPassenger(refShip1,i))
     if (IsOfficer(refChar)) {
       refChar.prisoned = false
     }
   }
}
This works wonderfully in its own right... but even though their pictures do not show, the actual ID is linked to the officers, so that’s who is transferred if clicked. :mad:
 
Last edited:
Because for one it annoys me when I accidentally move one over and have to put them back, it also doesn’t make sense to be able to. It’s can also be a problem if transferring between companions because it’s not so easy for the player to remember which of the passengers are its officers, as they would probably remember their own. I guess another option is to mark a passenger who is an officer with some text or on their image (like how ships have their class showing on the icon or a passenger’s name), this would greatly avoid any confusion.

I actually have a bit of an idea. I’m wondering about the possibility of forcing officers into a captive state, in a story sense. This could allow for a particular type of pirate captain who wants all the plunder for himself and refuses to share anything with his crew. Obviously this would cause severe morale problems and would drastically increase the chances of mutiny, which would present a challenging game for the player. They would have to raid very often and would be very unlikely to find allies, most other pirates would probably hate their guts. A problem for the player could be that they cannot move officers unless they relieve them of their officer role or possibly that wouldn’t be possible either, so they’d have to fire them (which might be refused), or they could pay them a lot of gold to be freed from the captive state. In order to offset the morale problems, food usage could be reduced and its effect on morale increased, and rum intake increased (but the effects being the same, either way increasing morale). Another option is to allow officer mutiny on land, in that one or even all of the officers could decide to turn on the player and attack him! If this were to be done, it would be imperative that officers either do not show up in the passenger list at all or otherwise they are prevented from being moved (which I doubt would be difficult). It’s going beyond the scope of the topic context so if I do put more thought into this then I’ll make a new thread.

Anyway, I’ve at least made a good function for making officers captive and then reversing it. See the above code which I’ve edited. I have placed that into CharacterUtilite.c while referencing the first one at the start of RefillScroll() and the second one at the end. This works perfectly for temporarily setting the flag and thus preventing them from being shown and I now have it in place without a problem. :cool:
 
Last edited:
Back
Top