Skip to content

Commit

Permalink
Reapply "Improvements to death and cheat handling"
Browse files Browse the repository at this point in the history
This reverts commit c7bba2a.
  • Loading branch information
Boondorl authored and madame-rachelle committed Apr 20, 2024
1 parent 949cd5b commit bcd6c61
Show file tree
Hide file tree
Showing 25 changed files with 873 additions and 744 deletions.
2 changes: 1 addition & 1 deletion src/g_level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1711,7 +1711,7 @@ int FLevelLocals::FinishTravel ()
pawn->flags2 &= ~MF2_BLASTED;
if (oldpawn != nullptr)
{
StaticPointerSubstitution (oldpawn, pawn);
PlayerPointerSubstitution (oldpawn, pawn, true);
oldpawn->Destroy();
}
if (pawndup != NULL)
Expand Down
2 changes: 1 addition & 1 deletion src/g_statusbar/sbar_mugshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ FGameTexture *FMugShot::GetFace(player_t *player, const char *default_face, int
if (CurrentState != NULL)
{
int skin = player->userinfo.GetSkin();
const char *skin_face = (stateflags & FMugShot::CUSTOM) ? nullptr : (player->morphTics ? (GetDefaultByType(player->MorphedPlayerClass))->NameVar(NAME_Face).GetChars() : Skins[skin].Face.GetChars());
const char *skin_face = (stateflags & FMugShot::CUSTOM) ? nullptr : (player->mo->alternative != nullptr ? (GetDefaultByType(player->MorphedPlayerClass))->NameVar(NAME_Face).GetChars() : Skins[skin].Face.GetChars());
return CurrentState->GetCurrentFrameTexture(default_face, skin_face, level, angle);
}
return NULL;
Expand Down
9 changes: 6 additions & 3 deletions src/m_cheat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,10 +626,13 @@ class DSuicider : public DThinker
double plyrdmgfact = Pawn->DamageFactor;
Pawn->DamageFactor = 1.;
P_DamageMobj (Pawn, Pawn, Pawn, TELEFRAG_DAMAGE, NAME_Suicide);
Pawn->DamageFactor = plyrdmgfact;
if (Pawn->health <= 0)
if (Pawn != nullptr)
{
Pawn->flags &= ~MF_SHOOTABLE;
Pawn->DamageFactor = plyrdmgfact;
if (Pawn->health <= 0)
{
Pawn->flags &= ~MF_SHOOTABLE;
}
}
Destroy();
}
Expand Down
2 changes: 1 addition & 1 deletion src/p_saveg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,7 @@ void FLevelLocals::UnSnapshotLevel(bool hubLoad)
// If this isn't the unmorphed original copy of a player, destroy it, because it's extra.
for (i = 0; i < MAXPLAYERS; ++i)
{
if (PlayerInGame(i) && Players[i]->morphTics && Players[i]->mo->alternative == pawn)
if (PlayerInGame(i) && Players[i]->mo->alternative == pawn)
{
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/playsim/a_morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ bool P_MorphActor(AActor *activator, AActor *victim, PClassActor *ptype, PClassA

bool P_UnmorphActor(AActor *activator, AActor *morphed, int flags, bool force)
{
IFVIRTUALPTR(morphed, AActor, UnMorph)
IFVIRTUALPTR(morphed, AActor, Unmorph)
{
VMValue params[] = { morphed, activator, flags, force };
int retval;
Expand Down
2 changes: 2 additions & 0 deletions src/playsim/a_morph.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ enum
MORPH_UNDOBYTIMEOUT = 0x00001000, // Player unmorphs once countdown expires
MORPH_UNDOALWAYS = 0x00002000, // Powerups must always unmorph, no matter what.
MORPH_TRANSFERTRANSLATION = 0x00004000, // Transfer translation from the original actor to the morphed one
MORPH_KEEPARMOR = 0x00008000, // Don't lose current armor value when morphing.
MORPH_IGNOREINVULN = 0x00010000, // Completely ignore invulnerability status on players.

MORPH_STANDARDUNDOING = MORPH_UNDOBYTOMEOFPOWER | MORPH_UNDOBYCHAOSDEVICE | MORPH_UNDOBYTIMEOUT,
};
Expand Down
4 changes: 2 additions & 2 deletions src/playsim/actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1747,8 +1747,8 @@ struct FTranslatedLineTarget
bool unlinked; // found by a trace that went through an unlinked portal.
};


void StaticPointerSubstitution(AActor* old, AActor* notOld);
void PlayerPointerSubstitution(AActor* oldPlayer, AActor* newPlayer, bool removeOld);
int MorphPointerSubstitution(AActor* from, AActor* to);

#define S_FREETARGMOBJ 1

Expand Down
2 changes: 1 addition & 1 deletion src/playsim/p_enemy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3139,7 +3139,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Pain)
PARAM_SELF_PROLOGUE(AActor);

// [RH] Vary player pain sounds depending on health (ala Quake2)
if (self->player && self->player->morphTics == 0)
if (self->player && self->alternative == nullptr)
{
const char *pain_amount;
FSoundID sfx_id = NO_SOUND;
Expand Down
62 changes: 40 additions & 22 deletions src/playsim/p_interaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,36 +313,54 @@ EXTERN_CVAR (Int, fraglimit)

void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOfDeath)
{
// Handle possible unmorph on death
bool wasgibbed = (health < GetGibHealth());

// Check to see if unmorph Actors need to be killed as well. Originally this was always
// called but that puts an unnecessary burden on the modder to determine whether it's
// a valid call or not.
if (alternative != nullptr && !(flags & MF_UNMORPHED))
{
IFVIRTUAL(AActor, MorphedDeath)
{
AActor *realthis = NULL;
int realstyle = 0;
int realhealth = 0;
// Return values are no longer used to ensure things stay properly managed.
AActor* const realMo = alternative;
int morphStyle = 0;

VMValue params[] = { this };
VMReturn returns[3];
returns[0].PointerAt((void**)&realthis);
returns[1].IntAt(&realstyle);
returns[2].IntAt(&realhealth);
VMCall(func, params, 1, returns, 3);

if (realthis && !(realstyle & MORPH_UNDOBYDEATHSAVES))
{
if (wasgibbed)
IFVM(Actor, GetMorphStyle)
{
int realgibhealth = realthis->GetGibHealth();
if (realthis->health >= realgibhealth)
{
realthis->health = realgibhealth - 1; // if morphed was gibbed, so must original be (where allowed)l
}
VMReturn ret[] = { &morphStyle };
VMCall(func, params, 1, ret, 1);
}
realthis->CallDie(source, inflictor, dmgflags, MeansOfDeath);
}

VMCall(func, params, 1, nullptr, 0);

// Kill the dummy Actor if it didn't unmorph, otherwise checking the morph flags. Player pawns need
// to stay, otherwise they won't respawn correctly.
if (realMo != nullptr && !(realMo->flags6 & MF6_KILLED)
&& ((alternative != nullptr && player == nullptr) || (alternative == nullptr && !(morphStyle & MORPH_UNDOBYDEATHSAVES))))
{
if (wasgibbed)
{
const int realGibHealth = realMo->GetGibHealth();
if (realMo->health >= realGibHealth)
realMo->health = realGibHealth - 1; // If morphed was gibbed, so must original be (where allowed).
}
else if (realMo->health > 0)
{
realMo->health = 0;
}

// Pass appropriate damage information along when it's confirmed to die.
realMo->DamageTypeReceived = DamageTypeReceived;
realMo->DamageType = DamageType;
realMo->special1 = special1;

realMo->CallDie(source, inflictor, dmgflags, MeansOfDeath);
}
}
}

Expand Down Expand Up @@ -458,7 +476,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
++source->player->spreecount;
}

if (source->player->morphTics)
if (source->alternative != nullptr)
{ // Make a super chicken
source->GiveInventoryType (PClass::FindActor(NAME_PowerWeaponLevel2));
}
Expand Down Expand Up @@ -1329,7 +1347,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da

if (damage >= player->health && !telefragDamage
&& (G_SkillProperty(SKILLP_AutoUseHealth) || deathmatch)
&& !player->morphTics)
&& target->alternative == nullptr)
{ // Try to use some inventory health
P_AutoUseHealth (player, damage - player->health + 1);
}
Expand Down Expand Up @@ -1463,7 +1481,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
// check for special fire damage or ice damage deaths
if (mod == NAME_Fire)
{
if (player && !player->morphTics)
if (player && target->alternative == nullptr)
{ // Check for flame death
if (!inflictor ||
((target->health > -50) && (damage > 25)) ||
Expand Down Expand Up @@ -1797,7 +1815,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPain
}
if (damage >= player->health
&& (G_SkillProperty(SKILLP_AutoUseHealth) || deathmatch)
&& !player->morphTics)
&& target->alternative == nullptr)
{ // Try to use some inventory health
P_AutoUseHealth(player, damage - player->health+1);
}
Expand Down Expand Up @@ -1827,7 +1845,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPain
else
{
target->special1 = damage;
if (player && !player->morphTics)
if (player && target->alternative == nullptr)
{ // Check for flame death
if ((player->poisontype == NAME_Fire) && (target->health > -50) && (damage > 25))
{
Expand Down

0 comments on commit bcd6c61

Please sign in to comment.