Troops that board an assault transport after it has been given its attack order are exempt from being sent out to fight. After a save is loaded that exemption is gone, and they are ordered out of the transport on the next update.
AssaultTransportAIUpdate keeps three parallel arrays for its members, and xfer writes only two of them:
https://github.com/TheSuperHackers/GeneralsGameCode/blob/main/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/AssaultTransportAIUpdate.cpp#L509-L513
m_newMember is left out, so every member loads as an established one. The update then reaches the eject test with the flag clear:
if( contained && isMemberHealthy( member ) && !m_newMember[ i ] )
{
//This contained member is healthy so order him to exit to start fighting!
//New members are exempt!
ai->aiExit( transport, CMD_FROM_AI );
}
m_newOccupantsAreNewMembers is missing for the same reason. It decides whether occupants picked up on the next update count as new, and it is only set back to TRUE at the end of an update, so on the frame the save is loaded a passenger already aboard but not yet in the member list is added as an established member as well.
isAttackPointless reads the same flag, so a transport whose members are all new no longer goes idle either.
Repro:
- Order a China Troop Crawler to attack
- Load fresh troops into it while that order is running, so they are flagged as new
- Save
- Load that save
The new troops pour out of the transport and charge the designated target. Without the save and load they stay aboard.
Measured with a probe on the flags, forcing a value at save time and reading both sides of the transfer, with the member count and member IDs as controls:
|
saved |
loaded |
| new member flags |
11111111 |
00000000 |
| new occupants flag |
1 |
0 |
| member count (control) |
8 |
8 |
The member count survives, so the record is written and read; only these flags are absent from it.
Present in Generals with the same xfer body.
Troops that board an assault transport after it has been given its attack order are exempt from being sent out to fight. After a save is loaded that exemption is gone, and they are ordered out of the transport on the next update.
AssaultTransportAIUpdatekeeps three parallel arrays for its members, andxferwrites only two of them:https://github.com/TheSuperHackers/GeneralsGameCode/blob/main/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/AssaultTransportAIUpdate.cpp#L509-L513
m_newMemberis left out, so every member loads as an established one. The update then reaches the eject test with the flag clear:m_newOccupantsAreNewMembersis missing for the same reason. It decides whether occupants picked up on the next update count as new, and it is only set back to TRUE at the end of an update, so on the frame the save is loaded a passenger already aboard but not yet in the member list is added as an established member as well.isAttackPointlessreads the same flag, so a transport whose members are all new no longer goes idle either.Repro:
The new troops pour out of the transport and charge the designated target. Without the save and load they stay aboard.
Measured with a probe on the flags, forcing a value at save time and reading both sides of the transfer, with the member count and member IDs as controls:
The member count survives, so the record is written and read; only these flags are absent from it.
Present in Generals with the same
xferbody.