@@ -313,36 +313,54 @@ EXTERN_CVAR (Int, fraglimit)
313
313
314
314
void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOfDeath)
315
315
{
316
- // Handle possible unmorph on death
317
316
bool wasgibbed = (health < GetGibHealth ());
318
317
318
+ // Check to see if unmorph Actors need to be killed as well. Originally this was always
319
+ // called but that puts an unnecessary burden on the modder to determine whether it's
320
+ // a valid call or not.
321
+ if (alternative != nullptr && !(flags & MF_UNMORPHED))
319
322
{
320
323
IFVIRTUAL (AActor, MorphedDeath)
321
324
{
322
- AActor *realthis = NULL ;
323
- int realstyle = 0 ;
324
- int realhealth = 0 ;
325
+ // Return values are no longer used to ensure things stay properly managed.
326
+ AActor* const realMo = alternative ;
327
+ int morphStyle = 0 ;
325
328
326
329
VMValue params[] = { this };
327
- VMReturn returns[3 ];
328
- returns[0 ].PointerAt ((void **)&realthis);
329
- returns[1 ].IntAt (&realstyle);
330
- returns[2 ].IntAt (&realhealth);
331
- VMCall (func, params, 1 , returns, 3 );
332
330
333
- if (realthis && !(realstyle & MORPH_UNDOBYDEATHSAVES))
334
331
{
335
- if (wasgibbed )
332
+ IFVM (Actor, GetMorphStyle )
336
333
{
337
- int realgibhealth = realthis->GetGibHealth ();
338
- if (realthis->health >= realgibhealth)
339
- {
340
- realthis->health = realgibhealth - 1 ; // if morphed was gibbed, so must original be (where allowed)l
341
- }
334
+ VMReturn ret[] = { &morphStyle };
335
+ VMCall (func, params, 1 , ret, 1 );
342
336
}
343
- realthis->CallDie (source, inflictor, dmgflags, MeansOfDeath);
344
337
}
345
338
339
+ VMCall (func, params, 1 , nullptr , 0 );
340
+
341
+ // Kill the dummy Actor if it didn't unmorph, otherwise checking the morph flags. Player pawns need
342
+ // to stay, otherwise they won't respawn correctly.
343
+ if (realMo != nullptr && !(realMo->flags6 & MF6_KILLED)
344
+ && ((alternative != nullptr && player == nullptr ) || (alternative == nullptr && !(morphStyle & MORPH_UNDOBYDEATHSAVES))))
345
+ {
346
+ if (wasgibbed)
347
+ {
348
+ const int realGibHealth = realMo->GetGibHealth ();
349
+ if (realMo->health >= realGibHealth)
350
+ realMo->health = realGibHealth - 1 ; // If morphed was gibbed, so must original be (where allowed).
351
+ }
352
+ else if (realMo->health > 0 )
353
+ {
354
+ realMo->health = 0 ;
355
+ }
356
+
357
+ // Pass appropriate damage information along when it's confirmed to die.
358
+ realMo->DamageTypeReceived = DamageTypeReceived;
359
+ realMo->DamageType = DamageType;
360
+ realMo->special1 = special1;
361
+
362
+ realMo->CallDie (source, inflictor, dmgflags, MeansOfDeath);
363
+ }
346
364
}
347
365
}
348
366
@@ -458,7 +476,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
458
476
++source->player ->spreecount ;
459
477
}
460
478
461
- if (source->player -> morphTics )
479
+ if (source->alternative != nullptr )
462
480
{ // Make a super chicken
463
481
source->GiveInventoryType (PClass::FindActor (NAME_PowerWeaponLevel2));
464
482
}
@@ -1329,7 +1347,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
1329
1347
1330
1348
if (damage >= player->health && !telefragDamage
1331
1349
&& (G_SkillProperty (SKILLP_AutoUseHealth) || deathmatch)
1332
- && !player-> morphTics )
1350
+ && target-> alternative == nullptr )
1333
1351
{ // Try to use some inventory health
1334
1352
P_AutoUseHealth (player, damage - player->health + 1 );
1335
1353
}
@@ -1463,7 +1481,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
1463
1481
// check for special fire damage or ice damage deaths
1464
1482
if (mod == NAME_Fire)
1465
1483
{
1466
- if (player && !player-> morphTics )
1484
+ if (player && target-> alternative == nullptr )
1467
1485
{ // Check for flame death
1468
1486
if (!inflictor ||
1469
1487
((target->health > -50 ) && (damage > 25 )) ||
@@ -1797,7 +1815,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPain
1797
1815
}
1798
1816
if (damage >= player->health
1799
1817
&& (G_SkillProperty (SKILLP_AutoUseHealth) || deathmatch)
1800
- && !player-> morphTics )
1818
+ && target-> alternative == nullptr )
1801
1819
{ // Try to use some inventory health
1802
1820
P_AutoUseHealth (player, damage - player->health +1 );
1803
1821
}
@@ -1827,7 +1845,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPain
1827
1845
else
1828
1846
{
1829
1847
target->special1 = damage;
1830
- if (player && !player-> morphTics )
1848
+ if (player && target-> alternative == nullptr )
1831
1849
{ // Check for flame death
1832
1850
if ((player->poisontype == NAME_Fire) && (target->health > -50 ) && (damage > 25 ))
1833
1851
{
0 commit comments