Skip to content

Commit 188818d

Browse files
ZivDeroRampastring
andcommitted
Make sure that we don't accidentally reset a dead spawn to be reloading if it as killed by Limbo()
Co-authored-by: Rampastring <rampastring@outlook.com>
1 parent 534e5ae commit 188818d

1 file changed

Lines changed: 14 additions & 3 deletions

File tree

src/new/spawnmanager/spawnmanager.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,10 @@ SpawnManagerClass::SpawnManagerClass(TechnoClass* owner, const AircraftTypeClass
192192

193193
if (spawnee != nullptr)
194194
{
195+
control->Status = SpawnControlStatus::Idle;
195196
control->IsSpawnedMissile = RocketTypeClass::From_AircraftType(SpawnType) != nullptr;
196197
control->Spawnee->Limbo();
197198
Extension::Fetch<AircraftClassExtension>(control->Spawnee)->SpawnOwner = Owner;
198-
control->Status = SpawnControlStatus::Idle;
199199
control->ReloadTimer = 0;
200200
SpawnControls.Add(control);
201201
}
@@ -535,9 +535,16 @@ void SpawnManagerClass::AI()
535535

536536
if (owner_coord == spawnee_coord && std::abs(spawnee->Coord.Z - Owner->Coord.Z) < 20)
537537
{
538-
spawnee->Limbo();
538+
/**
539+
* WARNING: Limbo() can destroy the unit in certain situations. If that happens, we
540+
* don't want to set the status to Reloading, as that will cause a nullptr crash later
541+
* when attempting to reload a non-existing spawnee
542+
* (Detach picks up the destruction and sets the control status to Dead).
543+
* Do not touch the order of the statements here or all hell breaks loose!
544+
*/
539545
control->Status = SpawnControlStatus::Reloading;
540546
control->ReloadTimer = ReloadRate;
547+
spawnee->Limbo();
541548
}
542549
else
543550
{
@@ -583,11 +590,11 @@ void SpawnManagerClass::AI()
583590
/**
584591
* Create a new spawn and set it to idle.
585592
*/
593+
control->Status = SpawnControlStatus::Idle;
586594
control->Spawnee = static_cast<AircraftClass*>(SpawnType->Create_One_Of(Owner->Owning_House()));
587595
control->IsSpawnedMissile = RocketTypeClass::From_AircraftType(SpawnType) != nullptr;
588596
control->Spawnee->Limbo();
589597
Extension::Fetch<AircraftClassExtension>(control->Spawnee)->SpawnOwner = Owner;
590-
control->Status = SpawnControlStatus::Idle;
591598
break;
592599
}
593600
}
@@ -872,6 +879,10 @@ void SpawnManagerClass::Detach(TARGET target)
872879
const auto control = SpawnControls[i];
873880
if (control->Spawnee == target)
874881
{
882+
/**
883+
* Only remove spawnees that are suicidal or have strength below zero.
884+
* Otherwise, it is a spawnee that landed on us and was limbo'ed for reloading.
885+
*/
875886
if (control->Spawnee->Strength <= 0 || control->Spawnee->IsKamikaze || control->IsSpawnedMissile)
876887
{
877888
control->Spawnee = nullptr;

0 commit comments

Comments
 (0)