• 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

Okay, well there are two ways to do a transfer at sea. One of them is to roll up next to a ship, but that is seemingly unneccessary since the ship screen can be used (or I have enabled the transfer button without realising).
Make sure that after the captain swap, there is somehow a call to RefreshBattleInterface (true);
Shouldn’t transfer_main already be dealing with that or am I not passing stuff back to it properly?
 
Shouldn’t transfer_main already be dealing with that or am I not passing stuff back to it properly?
I wasn't sure if it was there or not. Looking at it, it looks like this:
Code:
  // added by KAM after build 11 -->
   // NK bugfix 04-09-10 for some reason not seeing var Mainchar
   ref pc = GetMainCharacter();
   btmp2 = CheckAttribute(pc,"shiptransferinterface.calledfrominterface"); // NK 05-04-14 add checkattr
   if(btmp2) btmp2 = sti(pc.shiptransferinterface.calledfrominterface);
   if (btmp2 == 0)
   {
   // <-- added by KAM after build 11

     RefreshBattleInterface(true);
     if( CheckAttribute(&PeopleOnShip,"IsOnDeck") && sti(PeopleOnShip.IsOnDeck) )
     {
       PeopleOnShip.IsOnDeck = true;
     }

   // added by KAM after build 11 -->
   }
   // <-- added by KAM after build 11
So it IS in there, but there is a condition in place that could prevent it from executing.
Maybe then it doesn't actually execute the way you are using it?
 
Whatever I do it just doesn’t want to work. Sure, I can now get the captain and passenger to swap properly but BattleInterface throws a full-on wobbler about it.
Code:
refShip1 = myCh
refShip2 = enemyCh
indShip1 = GetCompanionIndex(refShip1,0)
indShip2 = GetCompanionIndex(refShip2,0)
numShip1 = GetCompanionNumber(MainChar,indShip1)
numShip2 = GetCompanionNumber(MainChar,indShip2)

void TransferCaptainYes()
{
   int indCompanion = indPassenger
   ref refCompanion = refPassenger

   SetCompanionIndex(MainChar,numShip2,indPassenger)
   ChangePassenger(refShip1,numPassenger,indShip2)
   RemoveOfficersIndex(refShip1,indPassenger)
   IMoveOfficers(refShip2,refPassenger)
   ISetShipAttributes(refPassenger)

   indPassenger = indShip2
   refPassenger = refShip2
   indShip2 = indCompanion
   refShip2 = refCompanion

   TransferCaptainNo()
   RefreshScreen()
}
Either that or I remove the index and references switches, and bail the interface...
Code:
   interfaceResultCommand = RC_INTERFACE_TRANSFER_MAIN_EXIT
   PostEvent("LaunchIAfterFrame",1,"sl","I_SHIP",2)
   EndCancelInterface(false)
Basically, I don’t think transfer_main.c is receiving the right information after I close the screen. Maybe this is why bailing the interface seems to work, because no information is passed on at all that way.
 
Last edited:
It means that when I first do a transfer at sea then I lose command of the ship, and it might feel like shooting me depending on who’s captain. It still belongs to me so I can do the transfer again afterwards, but that’s when I hit a CTD...
Code:
RUNTIME ERROR - file: battle_interface\BattleInterface.c; line: 720
process event stack error
RUNTIME ERROR - file: battle_interface\BattleInterface.c; line: 720
function 'Event' stack error
 
It means that when I first do a transfer at sea then I lose command of the ship, and it might feel like shooting me depending on who’s captain.
Relevant code is in Screwface_Functions.c . Specifically the UpdateAllShipsAtSea function should set the relations between you and your companion ships.
Add a Trace line at the beginning of each of these functions:
RefreshBattleInterface
UpdateAllShipsAtSea
CheckInitialFlagRelations
CheckAllShips

Then do your transfer and see which of them do and don't get called.

Code:
RUNTIME ERROR - file: battle_interface\BattleInterface.c; line: 720
process event stack error
RUNTIME ERROR - file: battle_interface\BattleInterface.c; line: 720
function 'Event' stack error
That line doesn't even exist. That can happen if the game notices "something" is wrong, but cannot quite figure out what.
Very annoying, because then it could almost be anything. :facepalm
 
Well, the strange thing is that I can keep changing the captain all day long long if I can’t see the sea. It’s fine in my cabin.

I think the problem is that while the ship attributes are being set on the new companion, the interface itself is failing to update this on the spot, hence the captain’s slot not changing. So I decided to force the captain’s index to match the passenger after setting the ship attributes and that just causes problems with the battle interface. I don’t understand why the captain has such a hard time being kicked out of his slot, this simply doesn’t happen with officers. :unsure

The only trace is RefreshBattleInterface().
That line doesn't even exist. That can happen if the game notices "something" is wrong, but cannot quite figure out what.
Since it’s a stack error, maybe it’s actually referring to the function line itself rather than the code within the function? Normally this means the wrong variable type was sent, right? So I’m thinking that maybe I have a reference in place of an index or vice-versa.
 
Last edited:
So you added all the trace lines I suggested and only the Refresh one showed?
Then it must somehow be called with 'false' instead of 'true'.
 
Yep, seemingly none of the others were called.

On the plus-side, I just boarded about six ships and looted them all. :)
 
Those other ones not being called does explain your weird effects.
They should and need to be called.
 
Any idea why they might not be? Since I’ve just managed to swap a companion into an empty slot on the main transfer screen, I can’t be doing too much wrong. I’m guessing it’s to do with a) the manner in which an interface is updated prior to being exited, and b) the information it passes on when it is exited.

Wait, hold on... now it’s doing the same kind of thing with swapping the slots, same error actually. :(

This is what I’m doing to swap them over, it looks simple enough...
Code:
aref arFromChar,arToChar
makearef(arFromChar,refShip1.ship)
makearef(arToChar,refShip2.ship)
CopyAttributes(arToChar,arFromChar)
SetCompanionIndex(PChar,SlotNum1,-1)
SetCompanionIndex(PChar,SlotNum2,indShip1)
ref OldShip = GetCharacter(GetCompanionIndex(PChar,SlotNum1))
DeleteAttribute(OldShip,"ship")
OldShip.ship.type = SHIP_NOTUSED_TYPE_NAME
IDoExit(RC_INTERFACE_KAM_SHIPTRANSFER_EXIT)
Funnily enough, the ship images don’t update which is why I boot the interface out again.

Okay, this appears to have fixed the slot swapping...
Code:
if (CheckAttribute(PChar,"shiptransferinterface")) {
  DeleteAttribute(PChar,"shiptransferinterface")
}
if (CheckAttribute(PChar,"InterfaceParam")) {
  DeleteAttribute(PChar,"InterfaceParam")
}
interfaceResultCommand = RC_INTERFACE_KAM_SHIPTRANSFER_EXIT
PostEvent("LaunchIAfterFrame",1,"sl","I_SHIP",2)
EndCancelInterface(false)
At least it didn’t crash this time after doing it 3 or 4 times. Transferring the captain, that’s still bugging out.
 
Last edited:
The only reason I can think of why those various functions don't get called is because RefreshBattleInterface gets called with argument 'false' instead of 'true'.
 
Since BattleInterface.c keeps throwing an error at line #720 then clearly there is an issue with refreshing.
How could a bool even have a stack error? Maybe it was sent a reference, as an integer would pass as true.

Anyway, I’ve placed a trace at ProcessCancelExit() in transfer_main.c and it’s not even being called.
Redirecting the interface to transfer_officers.c may be an issue. I reverted it, now the ship is being sunk.
So I removed the code which forces the captain’s ship reference and index, it’s again crashing like usual.

Basically, the only way I can sort this at the moment is by preventing captain changes if isEntity(&Sea). :(
Code:
// LDH Some notes on using the full copyattributes code that's commented out below and used in SeaAI_SwapShipsAttributes() - 10May09
// We have no problems swapping ships if there is no sea, for example, if we're in the shipyard or tavern.
// We can't swap ships if called from land and the sea is active, for example if we're on the dock.
// We don't have problems swapping ships if we do it from the battle interface swap icon when we're beside the other ship.
// Swapping ships after boarding works, it uses SeaAI_SwapShipsAttributes() which has full copyattributes.
// We have the same problem doing repairs on blots.  It only works if the sea is not active.
// It's likely the engine has pointers into the data and if we change the data the engine's pointers are wrong and it crashes.
// The real problem appears to be deleting blots, although they seem to copy fine in SwapProcessAtLand().
On a side-note, that bit about repairing blots looks interesting - do you suppose it could be related to the loot boarding crash?
 
Last edited:
Back
Top