• 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 Boarding: Inconsistent Crashes Related to Looting

Traces cost nothing, so if I don't know what I'm doing, I just put them EVERYWHERE.
Then when a crash occurs, you can see which Trace is the last one that was logged and then at least you know the problem is somewhere between that one and the next Trace you added.

What kind of DirectSail would there be during boarding???
 
I’m seeing errors pop up when boarding starts relating to CCCdirectsail.c. I think it’s this bit...
Code:
string GetMapIslandzone(string Island)
{
   ...
   float ix = MakeFloat(worldMap.islands.(Island).position.rx);
   float iz = MakeFloat(worldMap.islands.(Island).position.rz);
The position can’t be found, which is probably due to being at 0,0. It could be that changing position triggers a check to see if there’s an island nearby to direct-sail to, which obviously there is not one in the middle of the map. So maybe one of two things is happening: either it is trying to update during boarding, which it can’t do, or references are lost because functions were abruptly dropped. I personally find it a bit barmy that direct-sail would even kick in during a battle, and I’ve been booted out of a battle many times due to it. It would probably make sense to disable it in any event where the player is not allowed to return to the map.

So yeah, if direct-sail is trying to kick in then it’d make sense that repairs are as well. So indeed, fixing one may not fix the other.
 
Error.log entries, you mean? Can you show what you get?

There is all sorts of code in place to prevent DirectSail updates when they're not wanted.
That's all at the top of PROGRAM\CCCdirectsail.c .
 
Hmm... it must be teleporting me right when a fleet disengages, otherwise it wouldn’t happen.

It basically couldn’t reference the position as quoted above. I’ll post it next time I board something.

But anyway, I think it goes a bit like this...

nextenemy = FindClosestShipofRel()

Since the ship is placed at 0,0 then would there even be any enemies nearby, unless by pure fluke?

If no enemies are near, it calls GetMapIslandZone(pchar.location) and hence the above.

And I guess it can’t find the location because there simply isn’t one during boarding.

And then it probably tries to repair the ship, just to utterly confound the situation. :unsure

I’ve whacked an abordage break under DirectSailCheck() in CCCDirectSail.c.
 
Last edited:
I’ve put traces in lots of places involving DirectSail and repairing the sails... none of them are being called.

On the other hand, this here...

itemsbox.c
Code:
if (!bFromCharacterScreen) { // KK
   locCameraSleep(true);
   SetTimeScale(0);

   Log_SetActiveAction("Nothing");
   BLIVisible(false);
   SendMessage(&IActions,"ll",LI_SET_VISIBLE,false);

   LayerFreeze("realize",bSeaActive && !ownDeckStarted() && !LAi_IsBoardingProcess());
   LayerFreeze("execute",true);
   bool bShow = ownDeckStarted();
   if(!bShow) bShow = LAi_IsBoardingProcess();
   LayerFreeze("sea_realize",!bSeaActive && bShow);
   LayerFreeze("sea_execute",true);
}
Is definitely a big part of the problem (the layer freezes, I think... look at the boarding clause and read on). Also this...

LogInterface.c
Code:
void BI_GetMsgIconRoot()
{
   aref arTmp;
   aref pARef[4];
   int i,idx,cn;
   ref mchr = GetMainCharacter();

   idx = 0;
   if(bSeaActive && !bAbordageStarted) // <----- [ This is being triggered during boarding! ]
   {
     for (i = 0; i < COMPANION_MAX; i++)
     {
       cn = GetCompanionIndex(mchr, i);
       if(cn<0) {continue;}
       Characters[cn].MessageIcons = true;
       makearef(arTmp,Characters[cn].MessageIcons);
       pARef[idx] = arTmp;
       idx++;
     }
     SendMessage(&BattleInterface,"le", BI_MSG_SET_MSG_ICONS, &pARef);
   }
   else // <----- [ Therefore, this clause fails to execute if the above passes, and BOOM! ]
   {
     for (i = 0; i < OFFICER_MAX; i++)
     {
       cn = GetOfficersIndex(mchr, i);
       if(cn<0) {continue;}
       Characters[cn].MessageIcons = true;
       makearef(arTmp,Characters[cn].MessageIcons);
       pARef[idx] = arTmp;
       idx++;
     }
     SendMessage(&objLandInterface,"le", MSG_BATTLE_LAND_SET_MSGICONS, &pARef);
   }
}
I removed the first piece of code and I have had no crashes whatsoever since. The items box screen is also much more stable. I then removed the second piece of code whilst keeping the first commented and the same crash happened as I looted the next body (this was during the same boarding process and without reloading, I was fine looting everything until that point), but again none since putting it back so it is surely related.

Seemingly the second piece is required for some reason, if it fails to execute then the crash happens. This is actually most likely what is happening because the first if statement has a clause for boarding, but it still executes and I imagine this is because boarding is technically not active while the items box is open, so there is a good chance that the first clause will run (thus the else statement obviously won’t).

If there isn’t much going on in the background then there may be a good chance that by the time the code comes to be executed the items box has properly closed and the check passes successfully because boarding is active again. If, however, there is a lot going on, particularly if there is a large sea battle taking place, the code will execute more slowly and at the time the above function is executed boarding is not active because the items box is still running - so it crashes. I have noticed that the crash occurs much more frequently during the larger battles; at first I thought it might be more to do with larger ships, but I now think it’s about processing speed.

It is also worth noting that after removing the first piece of code, no sails appear in the backdrop after looting. [example of this]

In conclusion, I believe that removing the first piece of code entirely, or possibly just the freeze entries, will fix the problem.

Actually, I have a serious problem now with my save game. I think I have saved some of the changes I made during debugging, I really cannot see how removing code from the items box interface will cause a buffer overflow when docking into a port, but that’s what is happening now. I reckon that is because I removed the code from loginterface.c and saved my game with those changes in place, so now it’s buggered. Nope, removing the freeze entries results in a bugger overflaw when docking to land, which is probably because icon statuses are not being reset properly.
User Rised Exception
C:\PROJECTS\DRIVE_V2\ENGINE\SOURCES\s_stack.cpp line 47
stack overflaw
When it crashes as I go to port, this is what I see at the very end of compile.log from a trace...
Loot Crash Check: LogInterface.c - BI_GetMsgIconRoot()
Error.log is pretty much constantly throwing this up...
RUNTIME ERROR - file: battle_interface\loginterface.c; line: 533
invalid index 4 [size:4]
RUNTIME ERROR - file: battle_interface\loginterface.c; line: 533
process event stack error
This one, too...
RUNTIME ERROR - file: sea_ai\AIShip.c; line: 5490
invalid index -1 [size:1000]
RUNTIME ERROR - file: sea_ai\AIShip.c; line: 5490
invalid array index
RUNTIME ERROR - file: sea_ai\AIShip.c; line: 5490
function 'SwapCabinChests' stack error
So I heartily recommend not messing about with the BI_GetMsgIconRoot() function unless you really know what you’re doing. ;)

I guess that bit of code, and therefore the entire problem, has something to do with the ship and officer icons, whichever are to be shown at the given time. Obviously we don’t want the icons for companions showing during boarding, but maybe that’s actually what it’s trying to do? :shrug
 
Last edited:
Nailed it. :fiddler

itemsbox.c

REPLACE: LayerFreeze()
Code:
   if (!bFromCharacterScreen) {
      ...
      LayerFreeze("realize",true)
      ...
      LayerFreeze("sea_realize",true)
      ...
LogInterface.c

ADD: !LAi_IsBoardingProcess()
Code:
void BI_GetMsgIconRoot()
{
   ...
   if(bSeaActive && !bAbordageStarted && !LAi_IsBoardingProcess())
   {
      for (i = 0; i < COMPANION_MAX; i++)
      {
         ...
This look very, very promising. Not even a minor error message. :cheeky
 
Last edited:
I’m gonna go plunder lots of Frenchies. If I get one single crash then I will seriously freak out.
 
Right then, I think this has fixed it. I know for sure that the changes to the freeze parameters stops the boarding crashes dead in its tracks, I’ve repeated the process over and again; the problem I was having with doing that is how the icons are reset and something was causing a crash upon switching to land (and sometimes from deck to sea). I’m mooring without a problem now, but I am still seeing this...
RUNTIME ERROR - file: battle_interface\loginterface.c; line: 531
invalid index 4 [size:4]
RUNTIME ERROR - file: battle_interface\loginterface.c; line: 531
process event stack error
What I think is happening here is that the wrong clause is being triggered, hence the index being invalid. If the player is switching to land then it doesn’t seem to be an issue, but if it gets it wrong at sea or during boarding then it will most likely crash. I guess !LAi_IsBoardingProcess() is good enough for one purpose, but it looks like another catch is needed for the land interface because the player is probably still at sea when the function is triggered, only by milliseconds of course. Again, this is about processing speed; the faster things are going the better chance it will execute at the right time, but I have noticed how after docking to port there is atrocious lag so maybe the function needs to be called differently.

Anyway, so long as that error remains minor then I’m a very happy man. :yes
 
Lag when entering a location is because of the new Leveling System.
Definitely less than ideal.
 
Normally when I experience serious stuttering I immediately check the error log, but since that won’t produce any errors then it’s just one of those “nature of the beast” things we have to put up with. :rolleyes:
 
There are some settings at the top of Levelling.c that give you some control over that process.
You should be able to decrease the stutter with that I think.
 
Probably best not to point me to code which says DO NOT CHANGE. xD Hah, I see the lines you mean though.
 
Probably best not to point me to code which says DO NOT CHANGE. xD
I didn't know it said that. Anyway, you're welcome to ignore that note.
Ideally the person who made all that code should be involved in changing it, but @Levis vanished again.
So go right ahead and see what it does. :doff
 
It’s not really that big a deal anyway since I spend most of my time at sea, I’m only really docked if I’m selling my trophies.
 
I’ve just accumulated 500kb worth of logs over a good 3 hours.

I sunk around 30 ships and captured maybe half as many.

I now have over 100 good rapiers in my weapons locker.

Not one single crash. I declare this fixed.

:monkeydance
 
Nailed it. :fiddler

itemsbox.c

REPLACE: LayerFreeze()
Code:
   if (!bFromCharacterScreen) {
      ...
      LayerFreeze("realize",true)
      ...
      LayerFreeze("sea_realize",true)
      ...
LogInterface.c

ADD: !LAi_IsBoardingProcess()
Code:
void BI_GetMsgIconRoot()
{
   ...
   if(bSeaActive && !bAbordageStarted && !LAi_IsBoardingProcess())
   {
      for (i = 0; i < COMPANION_MAX; i++)
      {
         ...
This look very, very promising. Not even a minor error message. :cheeky
Can you upload both of those files, please?
I am not entirely clear on how I should implement those changes.
 
Back
Top