mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 23:01:59 +00:00
- Added DavidPH's Poison damage extension but changed it so that the metadata can be removed.
SVN r2450 (trunk)
This commit is contained in:
parent
545a892faa
commit
f430881a54
7 changed files with 106 additions and 7 deletions
12
src/actor.h
12
src/actor.h
|
@ -320,6 +320,8 @@ enum
|
|||
MF6_SHATTERING = 0x00020000, // marks an ice corpse for forced shattering
|
||||
MF6_KILLED = 0x00040000, // Something that was killed (but not necessarily a corpse)
|
||||
MF6_BLOCKEDBYSOLIDACTORS = 0x00080000, // Blocked by solid actors, even if not solid itself
|
||||
MF6_ADDITIVEPOISONDAMAGE = 0x00100000,
|
||||
MF6_ADDITIVEPOISONDURATION = 0x00200000,
|
||||
|
||||
// --- mobj.renderflags ---
|
||||
|
||||
|
@ -505,7 +507,6 @@ enum
|
|||
AMETA_BloodColor, // colorized blood
|
||||
AMETA_GibHealth, // negative health below which this monster dies an extreme death
|
||||
AMETA_WoundHealth, // health needed to enter wound state
|
||||
AMETA_PoisonDamage, // Amount of poison damage
|
||||
AMETA_FastSpeed, // Speed in fast mode
|
||||
AMETA_RDFactor, // Radius damage factor
|
||||
AMETA_CameraHeight, // Height of camera when used as such
|
||||
|
@ -843,6 +844,15 @@ public:
|
|||
AActor *BlockingMobj; // Actor that blocked the last move
|
||||
line_t *BlockingLine; // Line that blocked the last move
|
||||
|
||||
int PoisonDamage; // Damage received per tic from poison.
|
||||
int PoisonDuration; // Duration left for receiving poison damage.
|
||||
int PoisonPeriod; // How often poison damage is applied. (Every X tics.)
|
||||
|
||||
int PoisonDamageReceived; // Damage received per tic from poison.
|
||||
int PoisonDurationReceived; // Duration left for receiving poison damage.
|
||||
int PoisonPeriodReceived; // How often poison damage is applied. (Every X tics.)
|
||||
TObjPtr<AActor> Poisoner; // Last source of received poison damage.
|
||||
|
||||
// a linked list of sectors where this object appears
|
||||
struct msecnode_t *touching_sectorlist; // phares 3/14/98
|
||||
|
||||
|
|
|
@ -1369,6 +1369,34 @@ dopain:
|
|||
target->flags |= MF_JUSTHIT; // fight back!
|
||||
}
|
||||
|
||||
void P_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage, int duration, int period)
|
||||
{
|
||||
int olddamage = target->PoisonDamageReceived;
|
||||
int oldduration = target->PoisonDurationReceived;
|
||||
|
||||
target->Poisoner = source;
|
||||
|
||||
if (inflictor->flags6 & MF6_ADDITIVEPOISONDAMAGE)
|
||||
{
|
||||
target->PoisonDamageReceived += damage;
|
||||
}
|
||||
else
|
||||
{
|
||||
target->PoisonDamageReceived = damage;
|
||||
}
|
||||
|
||||
if (inflictor->flags6 & MF6_ADDITIVEPOISONDURATION)
|
||||
{
|
||||
target->PoisonDurationReceived += duration;
|
||||
}
|
||||
else
|
||||
{
|
||||
target->PoisonDurationReceived = duration;
|
||||
}
|
||||
|
||||
target->PoisonPeriodReceived = period;
|
||||
}
|
||||
|
||||
bool AActor::OkayToSwitchTarget (AActor *other)
|
||||
{
|
||||
if (other == this)
|
||||
|
|
|
@ -480,6 +480,7 @@ extern FBlockNode** blocklinks; // for thing chains
|
|||
//
|
||||
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_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage, int duration, int period);
|
||||
bool P_GiveBody (AActor *actor, int num);
|
||||
bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poison);
|
||||
void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPainSound);
|
||||
|
|
|
@ -1088,6 +1088,13 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
|
|||
P_RipperBlood (tm.thing, thing);
|
||||
}
|
||||
S_Sound (tm.thing, CHAN_BODY, "misc/ripslop", 1, ATTN_IDLE);
|
||||
|
||||
// Do poisoning (if using new style poison)
|
||||
if (tm.thing->PoisonDuration != INT_MIN)
|
||||
{
|
||||
P_PoisonMobj(thing, tm.thing, tm.thing->target, tm.thing->PoisonDamage, tm.thing->PoisonDuration, tm.thing->PoisonPeriod);
|
||||
}
|
||||
|
||||
damage = tm.thing->GetMissileDamage (3, 2);
|
||||
P_DamageMobj (thing, tm.thing, tm.thing->target, damage, tm.thing->DamageType);
|
||||
if (!(tm.thing->flags3 & MF3_BLOODLESSIMPACT))
|
||||
|
@ -1109,6 +1116,13 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Do poisoning (if using new style poison)
|
||||
if (tm.thing->PoisonDuration != INT_MIN)
|
||||
{
|
||||
P_PoisonMobj(thing, tm.thing, tm.thing->target, tm.thing->PoisonDamage, tm.thing->PoisonDuration, tm.thing->PoisonPeriod);
|
||||
}
|
||||
|
||||
// Do damage
|
||||
damage = tm.thing->GetMissileDamage ((tm.thing->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1);
|
||||
if ((damage > 0) || (tm.thing->flags6 & MF6_FORCEPAIN))
|
||||
|
@ -3471,6 +3485,13 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
|
|||
trace.Actor, srcangle, srcpitch);
|
||||
}
|
||||
}
|
||||
|
||||
// Allow puffs to inflict poison damage, so that hitscans can poison, too.
|
||||
if (puffDefaults->PoisonDuration != INT_MIN)
|
||||
{
|
||||
P_PoisonMobj(trace.Actor, puff ? puff : t1, t1, puffDefaults->PoisonDamage, puffDefaults->PoisonDuration, puffDefaults->PoisonPeriod);
|
||||
}
|
||||
|
||||
// [GZ] If MF6_FORCEPAIN is set, we need to call P_DamageMobj even if damage is 0!
|
||||
// Note: The puff may not yet be spawned here so we must check the class defaults, not the actor.
|
||||
if (damage || (puffDefaults->flags6 & MF6_FORCEPAIN))
|
||||
|
@ -3840,6 +3861,10 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color
|
|||
P_TraceBleed (damage, x, y, z, RailHits[i].HitActor, source->angle, pitch);
|
||||
}
|
||||
if (spawnpuff) P_SpawnPuff (source, puffclass, x, y, z, source->angle - ANG90, 1, PF_HITTHING);
|
||||
|
||||
if (puffDefaults && puffDefaults->PoisonDuration != INT_MIN)
|
||||
P_PoisonMobj(RailHits[i].HitActor, thepuff ? thepuff : source, source, puffDefaults->PoisonDamage, puffDefaults->PoisonDuration, puffDefaults->PoisonPeriod);
|
||||
|
||||
P_DamageMobj (RailHits[i].HitActor, thepuff? thepuff:source, source, damage, damagetype, DMG_INFLICTOR_IS_PUFF);
|
||||
}
|
||||
|
||||
|
|
|
@ -346,6 +346,11 @@ void AActor::Serialize (FArchive &arc)
|
|||
WeaveIndexZ = 0;
|
||||
}
|
||||
}
|
||||
if (SaveVersion >= 2450)
|
||||
{
|
||||
arc << PoisonDamageReceived << PoisonDurationReceived << PoisonPeriodReceived << Poisoner;
|
||||
arc << PoisonDamage << PoisonDuration << PoisonPeriod;
|
||||
}
|
||||
|
||||
// Skip past uservar array in old savegames
|
||||
if (SaveVersion < 1933)
|
||||
|
@ -3314,6 +3319,18 @@ void AActor::Tick ()
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for poison damage, but only once per PoisonPeriod tics (or once per second if none).
|
||||
if (PoisonDurationReceived && (level.time % (PoisonPeriodReceived ? PoisonPeriodReceived : TICRATE) == 0))
|
||||
{
|
||||
P_DamageMobj(this, NULL, Poisoner, PoisonDamageReceived, NAME_Poison, 0);
|
||||
|
||||
--PoisonDurationReceived;
|
||||
|
||||
// Must clear damage when duration is done, otherwise it
|
||||
// could be added to with ADDITIVEPOISONDAMAGE.
|
||||
if (!PoisonDurationReceived) PoisonDamageReceived = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// cycle through states, calling action functions at transitions
|
||||
|
@ -5444,10 +5461,10 @@ int AActor::DoSpecialDamage (AActor *target, int damage)
|
|||
{
|
||||
if (target->player)
|
||||
{
|
||||
int poisondamage = GetClass()->Meta.GetMetaInt(AMETA_PoisonDamage);
|
||||
if (poisondamage > 0)
|
||||
// Only do this for old style poison damage.
|
||||
if (PoisonDamage > 0 && PoisonDuration == INT_MIN)
|
||||
{
|
||||
P_PoisonPlayer (target->player, this, this->target, poisondamage);
|
||||
P_PoisonPlayer (target->player, this, this->target, PoisonDamage);
|
||||
damage >>= 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -224,6 +224,8 @@ static FFlagDef ActorFlags[]=
|
|||
DEFINE_FLAG(MF6, JUMPDOWN, AActor, flags6),
|
||||
DEFINE_FLAG(MF6, VULNERABLE, AActor, flags6),
|
||||
DEFINE_FLAG(MF6, NOTRIGGER, AActor, flags6),
|
||||
DEFINE_FLAG(MF6, ADDITIVEPOISONDAMAGE, AActor, flags6),
|
||||
DEFINE_FLAG(MF6, ADDITIVEPOISONDURATION, AActor, flags6),
|
||||
DEFINE_FLAG(MF6, BLOCKEDBYSOLIDACTORS, AActor, flags6),
|
||||
|
||||
// Effect flags
|
||||
|
|
|
@ -999,10 +999,26 @@ DEFINE_PROPERTY(maxdropoffheight, F, Actor)
|
|||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(poisondamage, I, Actor)
|
||||
DEFINE_PROPERTY(poisondamage, Iii, Actor)
|
||||
{
|
||||
PROP_INT_PARM(i, 0);
|
||||
info->Class->Meta.SetMetaInt (AMETA_PoisonDamage, i);
|
||||
PROP_INT_PARM(poisondamage, 0);
|
||||
PROP_INT_PARM(poisonduration, 1);
|
||||
PROP_INT_PARM(poisonperiod, 2);
|
||||
|
||||
defaults->PoisonDamage = poisondamage;
|
||||
if (PROP_PARM_COUNT == 1)
|
||||
{
|
||||
defaults->PoisonDuration = INT_MIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
defaults->PoisonDuration = poisonduration;
|
||||
|
||||
if (PROP_PARM_COUNT > 2)
|
||||
defaults->PoisonPeriod = poisonperiod;
|
||||
else
|
||||
defaults->PoisonPeriod = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
Loading…
Reference in a new issue