TheAssemblyArmada / Vanilla-Conquer

Vanilla Conquer provides clean, cross-platform builds of the C&C Remastered Collection and the standalone legacy games.
Other
347 stars 52 forks source link

[RA] IsActive != 0 assert is triggered by Scatter code in InfantryClass::Movement_AI() #403

Open mvdhout1992 opened 3 years ago

mvdhout1992 commented 3 years ago

Code comments say scatter after infantry building crew unit is created off a destroyed building.

I can't reliable reproduce it.

Movement_AI() is called by AI() after a check for IsActive != 0, which should make it skip calling Movement_AI() but it still does. Operator delete* sets IsActive() to false so it might be being deleted somewhere in the code called in InfantryClass::AI().

The Movement_AI() code has some other checks for IsActive != 0, and in those checks they just return from the function.

In my debugger it's showing the Doing DoType as DO_EXPLOSION_DEATH() and ID = -1.

Seems like a IsActive !=0 check needs to be added there, as the Movement_AI() code is the last code called by InfantryClass::AI().

Might be an issue with the building crew spawning code too.

mvdhout1992 commented 3 years ago

Looking at the code and memory, because DoType is DO_EXPLOSION_DEATH the Doing_AI() code called probably deleted the unit just before the call to Movement_AI() . then in Movement_AI() it doesn't have the check and instead the assert in ObjectClass::Select() which fails.

It should be clean to add a check in the scatter part in Movement_AI(). I assume the infantry unit is created as building crew from dead building and then dies before the call to InfantryClass::AI().

mvdhout1992 commented 3 years ago

Just checked again and the movement_AI() code just makes sure that if a unit on the same cell as a building they get scattered off it. The actual scatter for building crew is done in the Building destroyed function. UnitClass::Movement_AI() has the same code.

I think this code might have been added for remaster to fix the issue where you can place buildings in infantry and vehicles by building them in a cell just as the units are about to pass into the cell.

So this bug might be caused by remaster code fix for another exploit.