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);
		}
	}
}