From 10fabc3ab7feb06c3435ad8bd0837ef9171331e1 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sun, 19 Jun 2016 10:59:00 -0500 Subject: [PATCH] Cleaned up code. Puffs no longer need ALWAYSPUFF. - A_CustomBulletAttack and A_FireBullets will perform a second P_LineAttack to get a puff which only returns to the previous function after a tracer. --- src/p_local.h | 3 +- src/p_map.cpp | 51 ++++++++++++++-------- src/thingdef/thingdef_codeptr.cpp | 70 ++++++++++++++++++++++--------- 3 files changed, 87 insertions(+), 37 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index ac6b264d9..42b4da7e7 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -325,7 +325,8 @@ enum // P_LineAttack flags { LAF_ISMELEEATTACK = 1, LAF_NORANDOMPUFFZ = 2, - LAF_NOIMPACTDECAL = 4 + LAF_NOIMPACTDECAL = 4, + LAF_NOINTERACT = 8, }; AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL); diff --git a/src/p_map.cpp b/src/p_map.cpp index 2fe41b17b..d63bf18b6 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4096,6 +4096,7 @@ static ETraceStatus CheckForActor(FTraceResults &res, void *userdata) AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage) { + bool nointeract = !!(flags && LAF_NOINTERACT); DVector3 direction; double shootz; FTraceResults trace; @@ -4185,26 +4186,32 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, } int tflags; - if (puffDefaults != NULL && puffDefaults->flags6 & MF6_NOTRIGGER) tflags = TRACE_NoSky; + if (nointeract || (puffDefaults && puffDefaults->flags6 & MF6_NOTRIGGER)) tflags = TRACE_NoSky; else tflags = TRACE_NoSky | TRACE_Impact; if (!Trace(t1->PosAtZ(shootz), t1->Sector, direction, distance, MF_SHOOTABLE, ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace, tflags, CheckForActor, &TData)) { // hit nothing - if (puffDefaults == NULL) - { - } - else if (puffDefaults->ActiveSound) + if (!nointeract && puffDefaults && puffDefaults->ActiveSound) { // Play miss sound S_Sound(t1, CHAN_WEAPON, puffDefaults->ActiveSound, 1, ATTN_NORM); } - if (puffDefaults != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF) + + // [MC] LAF_NOINTERACT guarantees puff spawning and returns it directly to the calling function. + // No damage caused, no sounds played, no blood splatters. + + if (nointeract || (puffDefaults && puffDefaults->flags3 & MF3_ALWAYSPUFF)) { // Spawn the puff anyway puff = P_SpawnPuff(t1, pufftype, trace.HitPos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget, 2, puffFlags); + + if (nointeract) + { + return puff; + } } else { - return NULL; + return nullptr; } } else @@ -4212,12 +4219,17 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, if (trace.HitType != TRACE_HitActor) { // position a bit closer for puffs - if (trace.HitType != TRACE_HitWall || ((trace.Line->special != Line_Horizon) || spawnSky)) + if (nointeract || trace.HitType != TRACE_HitWall || ((trace.Line->special != Line_Horizon) || spawnSky)) { DVector2 pos = P_GetOffsetPosition(trace.HitPos.X, trace.HitPos.Y, -trace.HitVector.X * 4, -trace.HitVector.Y * 4); puff = P_SpawnPuff(t1, pufftype, DVector3(pos, trace.HitPos.Z - trace.HitVector.Z * 4), trace.SrcAngleFromTarget, trace.SrcAngleFromTarget - 90, 0, puffFlags); puff->radius = 1/65536.; + + if (nointeract) + { + return puff; + } } // [RH] Spawn a decal @@ -4255,14 +4267,6 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, } else { - bool bloodsplatter = (t1->flags5 & MF5_BLOODSPLATTER) || - (t1->player != NULL && t1->player->ReadyWeapon != NULL && - (t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD)); - - bool axeBlood = (t1->player != NULL && - t1->player->ReadyWeapon != NULL && - (t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD)); - // Hit a thing, so it could be either a puff or blood DVector3 bleedpos = trace.HitPos; // position a bit closer for puffs/blood if using compatibility mode. @@ -4275,7 +4279,7 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, } // Spawn bullet puffs or blood spots, depending on target type. - if ((puffDefaults != NULL && puffDefaults->flags3 & MF3_PUFFONACTORS) || + if (nointeract || (puffDefaults && puffDefaults->flags3 & MF3_PUFFONACTORS) || (trace.Actor->flags & MF_NOBLOOD) || (trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT))) { @@ -4284,6 +4288,11 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, // We must pass the unreplaced puff type here puff = P_SpawnPuff(t1, pufftype, bleedpos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget - 90, 2, puffFlags | PF_HITTHING, trace.Actor); + + if (nointeract) + { + return puff; + } } // Allow puffs to inflict poison damage, so that hitscans can poison, too. @@ -4320,6 +4329,14 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, } if (!(puffDefaults != NULL && puffDefaults->flags3&MF3_BLOODLESSIMPACT)) { + bool bloodsplatter = (t1->flags5 & MF5_BLOODSPLATTER) || + (t1->player != nullptr && t1->player->ReadyWeapon != nullptr && + (t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD)); + + bool axeBlood = (t1->player != nullptr && + t1->player->ReadyWeapon != nullptr && + (t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD)); + if (!bloodsplatter && !axeBlood && !(trace.Actor->flags & MF_NOBLOOD) && !(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT))) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index f3118c3dd..10d0d4498 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1666,6 +1666,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); for (i = 0; i < numbullets; i++) { + bool temp = false; DAngle angle = bangle; DAngle slope = bslope; @@ -1686,6 +1687,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) damage *= ((pr_cabullet()%3)+1); AActor *puff = P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags); + if (!puff) + { + temp = true; + puff = P_LineAttack(self, bangle, range, bslope, 0, NAME_Hitscan, pufftype, laflags | LAF_NOINTERACT); + } if (puff && missile) { @@ -1694,14 +1700,20 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) AActor *proj = P_SpawnMissileXYZ(self->Vec3Offset(x, y, self->GetBobOffset() + Spawnheight), self, puff, missile, false); if (proj) { - if (flags & CBAF_PUFFTARGET) proj->target = puff; - if (flags & CBAF_PUFFMASTER) proj->master = puff; - if (flags & CBAF_PUFFTRACER) proj->tracer = puff; - double missilespeed; - A_Face(proj, puff, 0., 0.); - missilespeed = fabs(proj->Angles.Pitch.Cos() * proj->Speed); - proj->Vel.Z = proj->Angles.Pitch.Sin() * proj->Speed; - proj->VelFromAngle(missilespeed); + // FAF_BOTTOM = 1 + // Aim for the base of the puff as that's where blood puffs will spawn... roughly. + + A_Face(proj, puff, 0., 0., 0., 0., 1); + proj->Vel3DFromAngle(-proj->Angles.Pitch, proj->Speed); + + if (temp) + puff->Destroy(); + else + { + if (flags & CBAF_PUFFTARGET) proj->target = puff; + if (flags & CBAF_PUFFMASTER) proj->master = puff; + if (flags & CBAF_PUFFTRACER) proj->tracer = puff; + } } } } @@ -1837,7 +1849,7 @@ enum FB_Flags FBF_PUFFTRACER = 256, }; -static void FireBulletMissile(AActor *self, PClassActor *missile, AActor *puff, DAngle angle, double Spawnheight, double Spawnofs_xy, int flags) +static void FireBulletMissile(AActor *self, PClassActor *missile, AActor *puff, DAngle angle, double Spawnheight, double Spawnofs_xy, int flags, bool temp) { if (self && missile && puff) { @@ -1847,14 +1859,20 @@ static void FireBulletMissile(AActor *self, PClassActor *missile, AActor *puff, AActor *proj = P_SpawnPlayerMissile(self, ofs.X, ofs.Y, Spawnheight, missile, angle, nullptr, nullptr, false, true); if (proj) { - if (flags & FBF_PUFFTARGET) proj->target = puff; - if (flags & FBF_PUFFMASTER) proj->master = puff; - if (flags & FBF_PUFFTRACER) proj->tracer = puff; - double missilespeed; - A_Face(proj, puff, 0., 0.); - missilespeed = fabs(proj->Angles.Pitch.Cos() * proj->Speed); - proj->Vel.Z = proj->Angles.Pitch.Sin() * proj->Speed; - proj->VelFromAngle(missilespeed); + // FAF_BOTTOM = 1 + // Aim for the base of the puff as that's where blood puffs will spawn... roughly. + + A_Face(proj, puff, 0., 0., 0., 0., 1); + proj->Vel3DFromAngle(-proj->Angles.Pitch, proj->Speed); + + if (temp) + puff->Destroy(); + else + { + if (flags & FBF_PUFFTARGET) proj->target = puff; + if (flags & FBF_PUFFMASTER) proj->master = puff; + if (flags & FBF_PUFFTRACER) proj->tracer = puff; + } } } } @@ -1910,8 +1928,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) if (!(flags & FBF_NORANDOM)) damage *= ((pr_cwbullet()%3)+1); + bool temp = false; AActor *puff = P_LineAttack(self, bangle, range, bslope, damage, NAME_Hitscan, pufftype, laflags); - FireBulletMissile(self, missile, puff, bangle, Spawnheight, Spawnofs_xy, flags); + + if (!puff) + { + temp = true; + puff = P_LineAttack(self, bangle, range, bslope, 0, NAME_Hitscan, pufftype, laflags | LAF_NOINTERACT); + } + FireBulletMissile(self, missile, puff, bangle, Spawnheight, Spawnofs_xy, flags, temp); } else @@ -1939,8 +1964,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) if (!(flags & FBF_NORANDOM)) damage *= ((pr_cwbullet()%3)+1); + bool temp = false; AActor *puff = P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags); - FireBulletMissile(self, missile, puff, angle, Spawnheight, Spawnofs_xy, flags); + + if (!puff) + { + temp = true; + puff = P_LineAttack(self, bangle, range, bslope, 0, NAME_Hitscan, pufftype, laflags | LAF_NOINTERACT); + } + FireBulletMissile(self, missile, puff, angle, Spawnheight, Spawnofs_xy, flags, temp); } } return 0;