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

Fixed CTD At Sea due to "Allied" Quest Enemy

These console commands prevent the crash:
Code:
   RemovePassenger(pchar, CharacterFromID("Enc_Officer_28"));
   Characters[GetCharacterIndex("Mystery_Man_04")].recognized = true; // PB: Ensure they're hostile!
   Characters[GetCharacterIndex("Mystery_Man_05")].recognized = true; // PB: Ensure they're hostile!
   DeleteAttribute(CharacterFromID("Mystery_Man_04"), "passenger");

But I have NO CLUE how that character could have gotten that "passenger" attribute. Quite a mystery indeed.

Also, that savegame behaves quite strangely.
Already noted the missing location labels. But also I cannot set "Battle/Half Sails".
 
The first and ONLY time where the "Mystery_Man_04" character is called is for that sea battle.
So absolutely nothing could have happened to give him that "passenger" attribute. Something truly bizarre must have happened there.

Anyway, since apparently that is possible, I propose making replacing this in PROGRAM\Characters\CharacterUtilite.c:
Code:
// KK -->
bool IsPassenger(ref _refCharacter)
{
   if(!CheckAttribute(_refCharacter,"index"))      return false;                 // MAXIMUS
   if (CheckAttribute(_refCharacter, "passenger"))   return sti(_refCharacter.passenger);

   // PB -->
   int cn;
   ref chr;
   ref pchar = GetMainCharacter();
   for(int i=0; i < GetPassengersQuantity(pchar); i++)
   {
     cn = GetPassenger(pchar, i);
     if (cn < 0)                           continue;           // Skip invalid characters
     chr = GetCharacter(cn);                                   // Reference to the character
     if(!CheckAttribute(chr,"index"))               continue;           // Skip invalid characters
     if(sti(_refCharacter.index) == sti(chr.index))         return true;         // This character is in the captain's passenger list
   }
   // PB <--

   return false;
}
// KK <--
With this:
Code:
// KK -->
bool IsPassenger(ref _refCharacter)
{
   //if(!CheckAttribute(_refCharacter,"index"))      return false;                 // MAXIMUS
   //if (CheckAttribute(_refCharacter, "passenger"))   return sti(_refCharacter.passenger);

   // PB -->
   int cn;
   ref chr;
   ref pchar = GetMainCharacter();
   for(int i=0; i < GetPassengersQuantity(pchar); i++)
   {
     cn = GetPassenger(pchar, i);
     if (cn < 0)                           continue;           // Skip invalid characters
     chr = GetCharacter(cn);                                   // Reference to the character
     if(!CheckAttribute(chr,"index"))               continue;           // Skip invalid characters
     if(sti(_refCharacter.index) == sti(chr.index))         return true;         // This character is in the captain's passenger list
   }
   // PB <--

   return false;
}
// KK <--
That top section is how that function used to work.
The bottom section is an addition of mine because it was possible for characters to truly BE passengers, but for that function to not pick up on that.

I left the old code active, figuring that the reverse should not happen and my approach may be a bit worse for performance.
Since now we have seen that it CAN happen (?!?), we can depreciate the old code completely and just use the new one that does work correctly.
 
I think I may have figured out HOW this completely unrelated character might have become a "passenger" and therefore friendly.

The ChangePassenger function contained some ERRONEOUS code that mixed up its character indices.
So instead of adding and removing attributes to and from the characters it was supposed to, it affected completely unrelated characters instead.
YIKES!

Well, good thing I caught it now so this should not happen in the future.
Maybe I could restore the old "passenger check" now to what it was.
But just to be safe, I'll keep my alternate version instead for the time being.
 
Back
Top