This commit is contained in:
Christoph Oelckers 2013-07-01 18:21:12 +02:00
commit db4f6bb8a1
3 changed files with 58 additions and 17 deletions

View file

@ -657,10 +657,37 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
FState *diestate = NULL; FState *diestate = NULL;
int gibhealth = GibHealth();
bool extremelydead = ((health < gibhealth || flags4 & MF4_EXTREMEDEATH) && !(flags4 & MF4_NOEXTREMEDEATH));
// Special check for 'extreme' damage type to ensure that it gets recorded properly as an extreme death for subsequent checks.
if (DamageType == NAME_Extreme)
{
extremelydead = true;
DamageType = NAME_None;
}
// find the appropriate death state. The order is:
//
// 1. If damagetype is not 'none' and death is extreme, try a damage type specific extreme death state
// 2. If no such state is found or death is not extreme try a damage type specific normal death state
// 3. If damagetype is 'ice' and actor is a monster or player, try the generic freeze death (unless prohibited)
// 4. If no state has been found and death is extreme, try the extreme death state
// 5. If no such state is found or death is not extreme try the regular death state.
// 6. If still no state has been found, destroy the actor immediately.
if (DamageType != NAME_None) if (DamageType != NAME_None)
{ {
diestate = FindState (NAME_Death, DamageType, true); if (extremelydead)
{
FName labels[] = { NAME_Death, NAME_Extreme, DamageType };
diestate = FindState(3, labels, true);
}
if (diestate == NULL)
{
diestate = FindState (NAME_Death, DamageType, true);
if (diestate != NULL) extremelydead = false;
}
if (diestate == NULL) if (diestate == NULL)
{ {
if (DamageType == NAME_Ice) if (DamageType == NAME_Ice)
@ -669,6 +696,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
if (!deh.NoAutofreeze && !(flags4 & MF4_NOICEDEATH) && (player || (flags3 & MF3_ISMONSTER))) if (!deh.NoAutofreeze && !(flags4 & MF4_NOICEDEATH) && (player || (flags3 & MF3_ISMONSTER)))
{ {
diestate = FindState(NAME_GenericFreezeDeath); diestate = FindState(NAME_GenericFreezeDeath);
extremelydead = false;
} }
} }
} }
@ -676,8 +704,6 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
if (diestate == NULL) if (diestate == NULL)
{ {
int flags4 = inflictor == NULL ? 0 : inflictor->flags4; int flags4 = inflictor == NULL ? 0 : inflictor->flags4;
int gibhealth = GibHealth();
// Don't pass on a damage type this actor cannot handle. // Don't pass on a damage type this actor cannot handle.
// (most importantly, prevent barrels from passing on ice damage.) // (most importantly, prevent barrels from passing on ice damage.)
@ -687,26 +713,33 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
DamageType = NAME_None; DamageType = NAME_None;
} }
if ((health < gibhealth || flags4 & MF4_EXTREMEDEATH) && !(flags4 & MF4_NOEXTREMEDEATH)) if (extremelydead)
{ // Extreme death { // Extreme death
diestate = FindState (NAME_Death, NAME_Extreme, true); diestate = FindState (NAME_Death, NAME_Extreme, true);
// If a non-player, mark as extremely dead for the crash state.
if (diestate != NULL && player == NULL && health >= gibhealth)
{
health = gibhealth - 1;
}
// For players, mark the appropriate flag.
else if (player != NULL)
{
player->cheats |= CF_EXTREMELYDEAD;
}
} }
if (diestate == NULL) if (diestate == NULL)
{ // Normal death { // Normal death
extremelydead = false;
diestate = FindState (NAME_Death); diestate = FindState (NAME_Death);
} }
} }
if (extremelydead)
{
// We'll only get here if an actual extreme death state was used.
// For players, mark the appropriate flag.
if (player != NULL)
{
player->cheats |= CF_EXTREMELYDEAD;
}
// If a non-player, mark as extremely dead for the crash state.
else if (health >= gibhealth)
{
health = gibhealth - 1;
}
}
if (diestate != NULL) if (diestate != NULL)
{ {
SetState (diestate); SetState (diestate);

View file

@ -5922,7 +5922,15 @@ void AActor::Crash()
if (DamageType != NAME_None) if (DamageType != NAME_None)
{ {
crashstate = FindState(NAME_Crash, DamageType, true); if (health < GibHealth())
{ // Extreme death
FName labels[] = { NAME_Crash, NAME_Extreme, DamageType };
crashstate = FindState (3, labels, true);
}
if (crashstate == NULL)
{ // Normal death
crashstate = FindState(NAME_Crash, DamageType, true);
}
} }
if (crashstate == NULL) if (crashstate == NULL)
{ {

View file

@ -763,7 +763,7 @@ protected:
fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt, fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt,
int usespecials); int usespecials);
friend bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, friend bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower=false); fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower);
friend bool EV_FloorCrushStop (int tag); friend bool EV_FloorCrushStop (int tag);
friend bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed); friend bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed);
private: private:
@ -774,7 +774,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt, fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt,
int usespecials); int usespecials);
bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower); fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower=false);
bool EV_FloorCrushStop (int tag); bool EV_FloorCrushStop (int tag);
bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed); bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed);