mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-12-01 00:21:35 +00:00
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.
This commit is contained in:
parent
4750dfd8b6
commit
10fabc3ab7
3 changed files with 87 additions and 37 deletions
|
@ -325,7 +325,8 @@ enum // P_LineAttack flags
|
||||||
{
|
{
|
||||||
LAF_ISMELEEATTACK = 1,
|
LAF_ISMELEEATTACK = 1,
|
||||||
LAF_NORANDOMPUFFZ = 2,
|
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);
|
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);
|
||||||
|
|
|
@ -4096,6 +4096,7 @@ static ETraceStatus CheckForActor(FTraceResults &res, void *userdata)
|
||||||
AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
||||||
DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage)
|
DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage)
|
||||||
{
|
{
|
||||||
|
bool nointeract = !!(flags && LAF_NOINTERACT);
|
||||||
DVector3 direction;
|
DVector3 direction;
|
||||||
double shootz;
|
double shootz;
|
||||||
FTraceResults trace;
|
FTraceResults trace;
|
||||||
|
@ -4185,26 +4186,32 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
||||||
}
|
}
|
||||||
|
|
||||||
int tflags;
|
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;
|
else tflags = TRACE_NoSky | TRACE_Impact;
|
||||||
|
|
||||||
if (!Trace(t1->PosAtZ(shootz), t1->Sector, direction, distance, MF_SHOOTABLE,
|
if (!Trace(t1->PosAtZ(shootz), t1->Sector, direction, distance, MF_SHOOTABLE,
|
||||||
ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace, tflags, CheckForActor, &TData))
|
ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace, tflags, CheckForActor, &TData))
|
||||||
{ // hit nothing
|
{ // hit nothing
|
||||||
if (puffDefaults == NULL)
|
if (!nointeract && puffDefaults && puffDefaults->ActiveSound)
|
||||||
{
|
|
||||||
}
|
|
||||||
else if (puffDefaults->ActiveSound)
|
|
||||||
{ // Play miss sound
|
{ // Play miss sound
|
||||||
S_Sound(t1, CHAN_WEAPON, puffDefaults->ActiveSound, 1, ATTN_NORM);
|
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
|
{ // Spawn the puff anyway
|
||||||
puff = P_SpawnPuff(t1, pufftype, trace.HitPos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget, 2, puffFlags);
|
puff = P_SpawnPuff(t1, pufftype, trace.HitPos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget, 2, puffFlags);
|
||||||
|
|
||||||
|
if (nointeract)
|
||||||
|
{
|
||||||
|
return puff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4212,12 +4219,17 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
||||||
if (trace.HitType != TRACE_HitActor)
|
if (trace.HitType != TRACE_HitActor)
|
||||||
{
|
{
|
||||||
// position a bit closer for puffs
|
// 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);
|
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,
|
puff = P_SpawnPuff(t1, pufftype, DVector3(pos, trace.HitPos.Z - trace.HitVector.Z * 4), trace.SrcAngleFromTarget,
|
||||||
trace.SrcAngleFromTarget - 90, 0, puffFlags);
|
trace.SrcAngleFromTarget - 90, 0, puffFlags);
|
||||||
puff->radius = 1/65536.;
|
puff->radius = 1/65536.;
|
||||||
|
|
||||||
|
if (nointeract)
|
||||||
|
{
|
||||||
|
return puff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// [RH] Spawn a decal
|
// [RH] Spawn a decal
|
||||||
|
@ -4255,14 +4267,6 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
||||||
}
|
}
|
||||||
else
|
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
|
// Hit a thing, so it could be either a puff or blood
|
||||||
DVector3 bleedpos = trace.HitPos;
|
DVector3 bleedpos = trace.HitPos;
|
||||||
// position a bit closer for puffs/blood if using compatibility mode.
|
// 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.
|
// 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->flags & MF_NOBLOOD) ||
|
||||||
(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT)))
|
(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
|
// 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);
|
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.
|
// 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))
|
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 &&
|
if (!bloodsplatter && !axeBlood &&
|
||||||
!(trace.Actor->flags & MF_NOBLOOD) &&
|
!(trace.Actor->flags & MF_NOBLOOD) &&
|
||||||
!(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT)))
|
!(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT)))
|
||||||
|
|
|
@ -1666,6 +1666,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack)
|
||||||
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
|
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
|
||||||
for (i = 0; i < numbullets; i++)
|
for (i = 0; i < numbullets; i++)
|
||||||
{
|
{
|
||||||
|
bool temp = false;
|
||||||
DAngle angle = bangle;
|
DAngle angle = bangle;
|
||||||
DAngle slope = bslope;
|
DAngle slope = bslope;
|
||||||
|
|
||||||
|
@ -1686,6 +1687,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack)
|
||||||
damage *= ((pr_cabullet()%3)+1);
|
damage *= ((pr_cabullet()%3)+1);
|
||||||
|
|
||||||
AActor *puff = P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags);
|
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)
|
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);
|
AActor *proj = P_SpawnMissileXYZ(self->Vec3Offset(x, y, self->GetBobOffset() + Spawnheight), self, puff, missile, false);
|
||||||
if (proj)
|
if (proj)
|
||||||
{
|
{
|
||||||
if (flags & CBAF_PUFFTARGET) proj->target = puff;
|
// FAF_BOTTOM = 1
|
||||||
if (flags & CBAF_PUFFMASTER) proj->master = puff;
|
// Aim for the base of the puff as that's where blood puffs will spawn... roughly.
|
||||||
if (flags & CBAF_PUFFTRACER) proj->tracer = puff;
|
|
||||||
double missilespeed;
|
A_Face(proj, puff, 0., 0., 0., 0., 1);
|
||||||
A_Face(proj, puff, 0., 0.);
|
proj->Vel3DFromAngle(-proj->Angles.Pitch, proj->Speed);
|
||||||
missilespeed = fabs(proj->Angles.Pitch.Cos() * proj->Speed);
|
|
||||||
proj->Vel.Z = proj->Angles.Pitch.Sin() * proj->Speed;
|
if (temp)
|
||||||
proj->VelFromAngle(missilespeed);
|
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,
|
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)
|
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);
|
AActor *proj = P_SpawnPlayerMissile(self, ofs.X, ofs.Y, Spawnheight, missile, angle, nullptr, nullptr, false, true);
|
||||||
if (proj)
|
if (proj)
|
||||||
{
|
{
|
||||||
if (flags & FBF_PUFFTARGET) proj->target = puff;
|
// FAF_BOTTOM = 1
|
||||||
if (flags & FBF_PUFFMASTER) proj->master = puff;
|
// Aim for the base of the puff as that's where blood puffs will spawn... roughly.
|
||||||
if (flags & FBF_PUFFTRACER) proj->tracer = puff;
|
|
||||||
double missilespeed;
|
A_Face(proj, puff, 0., 0., 0., 0., 1);
|
||||||
A_Face(proj, puff, 0., 0.);
|
proj->Vel3DFromAngle(-proj->Angles.Pitch, proj->Speed);
|
||||||
missilespeed = fabs(proj->Angles.Pitch.Cos() * proj->Speed);
|
|
||||||
proj->Vel.Z = proj->Angles.Pitch.Sin() * proj->Speed;
|
if (temp)
|
||||||
proj->VelFromAngle(missilespeed);
|
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))
|
if (!(flags & FBF_NORANDOM))
|
||||||
damage *= ((pr_cwbullet()%3)+1);
|
damage *= ((pr_cwbullet()%3)+1);
|
||||||
|
|
||||||
|
bool temp = false;
|
||||||
AActor *puff = P_LineAttack(self, bangle, range, bslope, damage, NAME_Hitscan, pufftype, laflags);
|
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
|
else
|
||||||
|
@ -1939,8 +1964,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
|
||||||
if (!(flags & FBF_NORANDOM))
|
if (!(flags & FBF_NORANDOM))
|
||||||
damage *= ((pr_cwbullet()%3)+1);
|
damage *= ((pr_cwbullet()%3)+1);
|
||||||
|
|
||||||
|
bool temp = false;
|
||||||
AActor *puff = P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags);
|
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;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue