mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-27 22:33:17 +00:00
- Applied a modified version of FDARI's patch to prevent giving health to dead things:
* P_GiveBody() now takes a max parameter so that it can also do the bulk of the work AHealth::TryPickup() previously did. * Setting an actor's health to 0 or below with SetActorProperty will now kill the actor properly. SVN r3438 (trunk)
This commit is contained in:
parent
6290ea4fcb
commit
977b2caa30
3 changed files with 48 additions and 69 deletions
|
@ -180,34 +180,43 @@ AInventory *AAmmo::CreateTossable()
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool P_GiveBody (AActor *actor, int num)
|
bool P_GiveBody (AActor *actor, int num, int max)
|
||||||
{
|
{
|
||||||
int max;
|
if (actor->health <= 0 || (actor->player != NULL && actor->player->playerstate == PST_DEAD))
|
||||||
|
{ // Do not heal dead things.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
player_t *player = actor->player;
|
player_t *player = actor->player;
|
||||||
|
|
||||||
num = clamp(num, -65536, 65536); // prevent overflows for bad values
|
num = clamp(num, -65536, 65536); // prevent overflows for bad values
|
||||||
if (player != NULL)
|
if (player != NULL)
|
||||||
{
|
{
|
||||||
max = static_cast<APlayerPawn*>(actor)->GetMaxHealth() + player->mo->stamina;
|
// Max is 0 by default, preserving default behavior for P_GiveBody()
|
||||||
// [MH] First step in predictable generic morph effects
|
// calls while supporting AHealth.
|
||||||
if (player->morphTics)
|
if (max <= 0)
|
||||||
{
|
{
|
||||||
if (player->MorphStyle & MORPH_FULLHEALTH)
|
max = static_cast<APlayerPawn*>(actor)->GetMaxHealth() + player->mo->stamina;
|
||||||
{
|
// [MH] First step in predictable generic morph effects
|
||||||
if (!(player->MorphStyle & MORPH_ADDSTAMINA))
|
if (player->morphTics)
|
||||||
|
{
|
||||||
|
if (player->MorphStyle & MORPH_FULLHEALTH)
|
||||||
{
|
{
|
||||||
max -= player->mo->stamina;
|
if (!(player->MorphStyle & MORPH_ADDSTAMINA))
|
||||||
|
{
|
||||||
|
max -= player->mo->stamina;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else // old health behaviour
|
||||||
else // old health behaviour
|
|
||||||
{
|
|
||||||
max = MAXMORPHHEALTH;
|
|
||||||
if (player->MorphStyle & MORPH_ADDSTAMINA)
|
|
||||||
{
|
{
|
||||||
max += player->mo->stamina;
|
max = MAXMORPHHEALTH;
|
||||||
|
if (player->MorphStyle & MORPH_ADDSTAMINA)
|
||||||
|
{
|
||||||
|
max += player->mo->stamina;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// [RH] For Strife: A negative body sets you up with a percentage
|
// [RH] For Strife: A negative body sets you up with a percentage
|
||||||
// of your full health.
|
// of your full health.
|
||||||
if (num < 0)
|
if (num < 0)
|
||||||
|
@ -236,6 +245,8 @@ bool P_GiveBody (AActor *actor, int num)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Parameter value for max is ignored on monsters, preserving original
|
||||||
|
// behaviour on AHealth as well as on existing calls to P_GiveBody().
|
||||||
max = actor->SpawnHealth();
|
max = actor->SpawnHealth();
|
||||||
if (num < 0)
|
if (num < 0)
|
||||||
{
|
{
|
||||||
|
@ -1475,58 +1486,16 @@ const char *AHealth::PickupMessage ()
|
||||||
|
|
||||||
bool AHealth::TryPickup (AActor *&other)
|
bool AHealth::TryPickup (AActor *&other)
|
||||||
{
|
{
|
||||||
player_t *player = other->player;
|
PrevHealth = other->player != NULL ? other->player->health : other->health;
|
||||||
int max = MaxAmount;
|
|
||||||
|
// P_GiveBody adds one new feature, applied only if it is possible to pick up negative health:
|
||||||
if (player != NULL)
|
// Negative values are treated as positive percentages, ie Amount -100 means 100% health, ignoring max amount.
|
||||||
|
if (P_GiveBody(other, Amount, MaxAmount))
|
||||||
{
|
{
|
||||||
PrevHealth = other->player->health;
|
GoAwayAndDie();
|
||||||
if (max == 0)
|
return true;
|
||||||
{
|
|
||||||
max = static_cast<APlayerPawn*>(other)->GetMaxHealth() + player->mo->stamina;
|
|
||||||
// [MH] First step in predictable generic morph effects
|
|
||||||
if (player->morphTics)
|
|
||||||
{
|
|
||||||
if (player->MorphStyle & MORPH_FULLHEALTH)
|
|
||||||
{
|
|
||||||
if (!(player->MorphStyle & MORPH_ADDSTAMINA))
|
|
||||||
{
|
|
||||||
max -= player->mo->stamina;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // old health behaviour
|
|
||||||
{
|
|
||||||
max = MAXMORPHHEALTH;
|
|
||||||
if (player->MorphStyle & MORPH_ADDSTAMINA)
|
|
||||||
{
|
|
||||||
max += player->mo->stamina;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (player->health >= max)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
player->health += Amount;
|
|
||||||
if (player->health > max)
|
|
||||||
{
|
|
||||||
player->health = max;
|
|
||||||
}
|
|
||||||
player->mo->health = player->health;
|
|
||||||
}
|
}
|
||||||
else
|
return false;
|
||||||
{
|
|
||||||
PrevHealth = INT_MAX;
|
|
||||||
if (P_GiveBody(other, Amount))
|
|
||||||
{
|
|
||||||
GoAwayAndDie ();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
GoAwayAndDie ();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_CLASS (AHealthPickup)
|
IMPLEMENT_CLASS (AHealthPickup)
|
||||||
|
|
|
@ -2874,11 +2874,21 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
|
||||||
switch (property)
|
switch (property)
|
||||||
{
|
{
|
||||||
case APROP_Health:
|
case APROP_Health:
|
||||||
|
// Don't alter the health of dead things.
|
||||||
|
if (actor->health <= 0 || (actor->player != NULL && actor->player->playerstate == PST_DEAD))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
actor->health = value;
|
actor->health = value;
|
||||||
if (actor->player != NULL)
|
if (actor->player != NULL)
|
||||||
{
|
{
|
||||||
actor->player->health = value;
|
actor->player->health = value;
|
||||||
}
|
}
|
||||||
|
// If the health is set to a non-positive value, properly kill the actor.
|
||||||
|
if (value <= 0)
|
||||||
|
{
|
||||||
|
actor->Die(activator, activator);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case APROP_Speed:
|
case APROP_Speed:
|
||||||
|
|
|
@ -484,7 +484,7 @@ extern FBlockNode** blocklinks; // for thing chains
|
||||||
void P_TouchSpecialThing (AActor *special, AActor *toucher);
|
void P_TouchSpecialThing (AActor *special, AActor *toucher);
|
||||||
void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0);
|
void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0);
|
||||||
void P_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage, int duration, int period, FName type);
|
void P_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage, int duration, int period, FName type);
|
||||||
bool P_GiveBody (AActor *actor, int num);
|
bool P_GiveBody (AActor *actor, int num, int max=0);
|
||||||
bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poison);
|
bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poison);
|
||||||
void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPainSound);
|
void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPainSound);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue