Scriptified ReactToDamage
Allows pain handling to be overridden without needing to override the entirety of DamageMobj.
This commit is contained in:
parent
e0baf7a85c
commit
8071fd1368
2 changed files with 40 additions and 8 deletions
|
|
@ -859,8 +859,9 @@ static inline bool isFakePain(AActor *target, AActor *inflictor, int damage)
|
|||
}
|
||||
|
||||
// [MC] Completely ripped out of DamageMobj to make it less messy.
|
||||
static void ReactToDamage(AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, int originaldamage)
|
||||
static int ReactToDamage(AActor *target, AActor *inflictor, AActor *source, int damage, int mod, int flags, int originaldamage)
|
||||
{
|
||||
FName modName = ENamedName(mod);
|
||||
bool justhit = false;
|
||||
int painchance = 0;
|
||||
FState *woundstate = nullptr;
|
||||
|
|
@ -871,17 +872,17 @@ static void ReactToDamage(AActor *target, AActor *inflictor, AActor *source, int
|
|||
|
||||
// Dead or non-existent entity, do not react. Especially if the damage is cancelled.
|
||||
if (target == nullptr || target->health < 1 || damage < 0)
|
||||
return;
|
||||
return false;
|
||||
|
||||
player_t *player = target->player;
|
||||
if (player && player->mo)
|
||||
{
|
||||
if ((player->cheats & CF_GODMODE2) || (player->mo->flags5 & MF5_NOPAIN) ||
|
||||
((player->cheats & CF_GODMODE) && damage < TELEFRAG_DAMAGE))
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
woundstate = target->FindState(NAME_Wound, mod);
|
||||
woundstate = target->FindState(NAME_Wound, modName);
|
||||
if (woundstate != nullptr)
|
||||
{
|
||||
int woundhealth = target->WoundHealth;
|
||||
|
|
@ -889,7 +890,7 @@ static void ReactToDamage(AActor *target, AActor *inflictor, AActor *source, int
|
|||
if (target->health <= woundhealth)
|
||||
{
|
||||
target->SetState(woundstate);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// [MC] NOPAIN will not stop the actor from waking up if damaged.
|
||||
|
|
@ -904,10 +905,10 @@ static void ReactToDamage(AActor *target, AActor *inflictor, AActor *source, int
|
|||
&& (forcedPain || damage >= target->PainThreshold))
|
||||
{
|
||||
if (inflictor && inflictor->PainType != NAME_None)
|
||||
mod = inflictor->PainType;
|
||||
modName = inflictor->PainType;
|
||||
|
||||
// Not called from ZScript.
|
||||
justhit = TriggerPainChance(target, mod, forcedPain, false);
|
||||
justhit = TriggerPainChance(target, modName, forcedPain, false);
|
||||
}
|
||||
|
||||
if (wakeup && target->player == nullptr) target->reactiontime = 0; // we're awake now...
|
||||
|
|
@ -946,6 +947,36 @@ static void ReactToDamage(AActor *target, AActor *inflictor, AActor *source, int
|
|||
// killough 11/98: Don't attack a friend, unless hit by that friend.
|
||||
if (justhit && (target->target == source || !target->target || !target->IsFriend(target->target)))
|
||||
target->flags |= MF_JUSTHIT; // fight back!
|
||||
|
||||
return justhit;
|
||||
}
|
||||
|
||||
static int CallReactToDamage(AActor* target, AActor* inflictor, AActor* source, int damage, FName mod, int flags, int originaldamage)
|
||||
{
|
||||
int res = false;
|
||||
IFVIRTUALPTR(target, AActor, ReactToDamage)
|
||||
{
|
||||
res = VMCallSingle<int, AActor*, AActor*, AActor*, int, int, int, int>(func, target, inflictor, source, damage, mod.GetIndex(), flags, originaldamage);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = ReactToDamage(target, inflictor, source, damage, mod.GetIndex(), flags, originaldamage);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, ReactToDamage, ReactToDamage)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_OBJECT(inflictor, AActor);
|
||||
PARAM_OBJECT(source, AActor);
|
||||
PARAM_INT(damage);
|
||||
PARAM_NAME(mod);
|
||||
PARAM_INT(flags);
|
||||
PARAM_INT(originaldamage);
|
||||
|
||||
ACTION_RETURN_BOOL(ReactToDamage(self, inflictor, source, damage, mod.GetIndex(), flags, originaldamage));
|
||||
}
|
||||
|
||||
static bool TriggerPainChance(AActor *target, FName mod = NAME_None, bool forcedPain = false, bool zscript = false)
|
||||
|
|
@ -1537,7 +1568,7 @@ static int DoDamageMobj(AActor *target, AActor *inflictor, AActor *source, int d
|
|||
bool needevent = true;
|
||||
int realdamage = DamageMobj(target, inflictor, source, damage, mod, flags, angle, needevent);
|
||||
if (realdamage >= 0) //Keep this check separated. Mods relying upon negative numbers may break otherwise.
|
||||
ReactToDamage(target, inflictor, source, realdamage, mod, flags, damage);
|
||||
CallReactToDamage(target, inflictor, source, realdamage, mod, flags, damage);
|
||||
|
||||
if (realdamage > 0 && needevent)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -826,6 +826,7 @@ class Actor : Thinker native
|
|||
native bool CheckMeleeRange(double range = -1);
|
||||
native bool TriggerPainChance(Name mod, bool forcedPain = false);
|
||||
native virtual int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags = 0, double angle = 0);
|
||||
native virtual bool ReactToDamage(Actor inflictor, Actor source, int damage, Name mod, int flags, int originaldamage);
|
||||
native void PoisonMobj (Actor inflictor, Actor source, int damage, int duration, int period, Name type);
|
||||
native double AimLineAttack(double angle, double distance, out FTranslatedLineTarget pLineTarget = null, double vrange = 0., int flags = 0, Actor target = null, Actor friender = null);
|
||||
native Actor, int LineAttack(double angle, double distance, double pitch, int damage, Name damageType, class<Actor> pufftype, int flags = 0, out FTranslatedLineTarget victim = null, double offsetz = 0., double offsetforward = 0., double offsetside = 0.);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue