Code: Select all
//===========================================================================
//
// Common A_Damage handler
//
// A_Damage* (int amount, str damagetype, int flags)
// Damages the specified actor by the specified amount. Negative values heal.
//
//===========================================================================
enum DMSS
{
DMSS_FOILINVUL = 1,
DMSS_AFFECTARMOR = 2,
DMSS_KILL = 4,
DMSS_NOFACTOR = 8,
DMSS_FOILBUDDHA = 16,
DMSS_NOPROTECT = 32,
};
static void DoDamage(AActor *dmgtarget, AActor *self, int amount, FName DamageType, int flags)
{
int dmgFlags = 0;
if (flags & DMSS_FOILINVUL)
dmgFlags += DMG_FOILINVUL;
if (flags & DMSS_FOILBUDDHA)
dmgFlags += DMG_FOILBUDDHA;
if ((flags & DMSS_KILL) || (flags & DMSS_NOFACTOR)) //Kill implies NoFactor
dmgFlags += DMG_NO_FACTOR;
if (!(flags & DMSS_AFFECTARMOR) || (flags & DMSS_KILL)) //Kill overrides AffectArmor
dmgFlags += DMG_NO_ARMOR;
if (flags & DMSS_KILL) //Kill adds the value of the damage done to it. Allows for more controlled extreme death types.
amount += dmgtarget->health;
if (flags & DMSS_NOPROTECT) //Ignore PowerProtection.
dmgFlags += DMG_NO_PROTECT;
if (amount > 0)
P_DamageMobj(dmgtarget, self, self, amount, DamageType, dmgFlags); //Should wind up passing them through just fine.
else if (amount < 0)
{
amount = -amount;
P_GiveBody(dmgtarget, amount);
}
}
//===========================================================================
//
//
//
//===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSelf)
{
ACTION_PARAM_START(3);
ACTION_PARAM_INT(amount, 0);
ACTION_PARAM_NAME(DamageType, 1);
ACTION_PARAM_INT(flags, 2);
DoDamage(self, self, amount, DamageType, flags);
}
//===========================================================================
//
//
//
//===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTarget)
{
ACTION_PARAM_START(3);
ACTION_PARAM_INT(amount, 0);
ACTION_PARAM_NAME(DamageType, 1);
ACTION_PARAM_INT(flags, 2);
if (self->target != NULL) DoDamage(self->target, self, amount, DamageType, flags);
}
//===========================================================================
//
//
//
//===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTracer)
{
ACTION_PARAM_START(3);
ACTION_PARAM_INT(amount, 0);
ACTION_PARAM_NAME(DamageType, 1);
ACTION_PARAM_INT(flags, 2);
if (self->tracer != NULL) DoDamage(self->tracer, self, amount, DamageType, flags);
}
//===========================================================================
//
//
//
//===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageMaster)
{
ACTION_PARAM_START(3);
ACTION_PARAM_INT(amount, 0);
ACTION_PARAM_NAME(DamageType, 1);
ACTION_PARAM_INT(flags, 2);
if (self->master != NULL) DoDamage(self->master, self, amount, DamageType, flags);
}
//===========================================================================
//
//
//
//===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageChildren)
{
ACTION_PARAM_START(3);
ACTION_PARAM_INT(amount, 0);
ACTION_PARAM_NAME(DamageType, 1);
ACTION_PARAM_INT(flags, 2);
TThinkerIterator<AActor> it;
AActor * mo;
while ( (mo = it.Next()) )
{
if (mo->master == self) DoDamage(mo, self, amount, DamageType, flags);
}
}
//===========================================================================
//
//
//
//===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSiblings)
{
ACTION_PARAM_START(3);
ACTION_PARAM_INT(amount, 0);
ACTION_PARAM_NAME(DamageType, 1);
ACTION_PARAM_INT(flags, 2);
TThinkerIterator<AActor> it;
AActor * mo;
if (self->master != NULL)
{
while ((mo = it.Next()))
{
if (mo->master == self->master && mo != self) DoDamage(mo, self, amount, DamageType, flags);
}
}
}