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;
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)
{
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 (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)))
{
diestate = FindState(NAME_GenericFreezeDeath);
extremelydead = false;
}
}
}
@ -677,8 +705,6 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
{
int flags4 = inflictor == NULL ? 0 : inflictor->flags4;
int gibhealth = GibHealth();
// Don't pass on a damage type this actor cannot handle.
// (most importantly, prevent barrels from passing on ice damage.)
// Massacre must be preserved though.
@ -687,26 +713,33 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
DamageType = NAME_None;
}
if ((health < gibhealth || flags4 & MF4_EXTREMEDEATH) && !(flags4 & MF4_NOEXTREMEDEATH))
if (extremelydead)
{ // Extreme death
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)
{ // Normal death
extremelydead = false;
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)
{
SetState (diestate);

View File

@ -5922,7 +5922,15 @@ void AActor::Crash()
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)
{

View File

@ -763,7 +763,7 @@ protected:
fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt,
int usespecials);
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_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed);
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,
int usespecials);
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_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed);