Account for portals when spawning missiles in A_FireBullets/A_CustomBulletAttack

This also gives the caller the information whether the LineAttack
hitscan passed through a portal regardless of whether it actually hit an
actor or not as a nice bonus.
This commit is contained in:
Cacodemon345 2021-05-20 13:51:15 +06:00 committed by Christoph Oelckers
parent 98a9729da2
commit 9a860ae445
3 changed files with 33 additions and 7 deletions

View file

@ -4604,7 +4604,7 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
}
P_GeometryLineAttack(trace, t1, damage, damageType);
if (victim != NULL) victim->unlinked = trace.unlinked;
// position a bit closer for puffs
if (nointeract || trace.HitType != TRACE_HitWall || ((trace.Line->special != Line_Horizon) || spawnSky))

View file

@ -55,6 +55,7 @@ extend class Actor
double bangle;
double bslope = 0.;
int laflags = (flags & CBAF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
FTranslatedLineTarget t;
if (ref != NULL || (flags & CBAF_AIMFACING))
{
@ -89,7 +90,7 @@ extend class Actor
if (!(flags & CBAF_NORANDOM))
damage *= random[cwbullet](1, 3);
let puff = LineAttack(pangle, range, slope, damage, 'Hitscan', pufftype, laflags);
let puff = LineAttack(pangle, range, slope, damage, 'Hitscan', pufftype, laflags, t);
if (missile != null && pufftype != null)
{
double ang = pangle - 90;
@ -104,11 +105,19 @@ extend class Actor
bool temp = (puff == null);
if (!puff)
{
puff = LineAttack(pangle, range, slope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT);
puff = LineAttack(pangle, range, slope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT, t);
}
if (puff)
{
AimBulletMissile(proj, puff, flags, temp, true);
if (t.unlinked)
{
// Arbitary portals will make angle and pitch calculations unreliable.
// So use the angle and pitch we passed instead.
proj.Angle = pangle;
proj.Pitch = bslope;
proj.Vel3DFromAngle(proj.Speed, proj.Angle, proj.Pitch);
}
}
}
}

View file

@ -89,6 +89,7 @@ class StateProvider : Inventory
double bangle;
double bslope = 0.;
int laflags = (flags & FBF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
FTranslatedLineTarget t;
if ((flags & FBF_USEAMMO) && weapon && stateinfo != null && stateinfo.mStateType == STATE_Psprite)
{
@ -117,7 +118,7 @@ class StateProvider : Inventory
if (!(flags & FBF_NORANDOM))
damage *= random[cabullet](1, 3);
let puff = LineAttack(bangle, range, bslope, damage, 'Hitscan', pufftype, laflags);
let puff = LineAttack(bangle, range, bslope, damage, 'Hitscan', pufftype, laflags, t);
if (missile != null)
{
@ -130,9 +131,17 @@ class StateProvider : Inventory
if (!puff)
{
temp = true;
puff = LineAttack(bangle, range, bslope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT);
puff = LineAttack(bangle, range, bslope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT, t);
}
AimBulletMissile(proj, puff, flags, temp, false);
if (t.unlinked)
{
// Arbitary portals will make angle and pitch calculations unreliable.
// So use the angle and pitch we passed instead.
proj.Angle = bangle;
proj.Pitch = bslope;
proj.Vel3DFromAngle(proj.Speed, proj.Angle, proj.Pitch);
}
}
}
}
@ -161,7 +170,7 @@ class StateProvider : Inventory
if (!(flags & FBF_NORANDOM))
damage *= random[cabullet](1, 3);
let puff = LineAttack(pangle, range, slope, damage, 'Hitscan', pufftype, laflags);
let puff = LineAttack(pangle, range, slope, damage, 'Hitscan', pufftype, laflags, t);
if (missile != null)
{
@ -174,9 +183,17 @@ class StateProvider : Inventory
if (!puff)
{
temp = true;
puff = LineAttack(bangle, range, bslope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT);
puff = LineAttack(bangle, range, bslope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT, t);
}
AimBulletMissile(proj, puff, flags, temp, false);
if (t.unlinked)
{
// Arbitary portals will make angle and pitch calculations unreliable.
// So use the angle and pitch we passed instead.
proj.Angle = bangle;
proj.Pitch = bslope;
proj.Vel3DFromAngle(proj.Speed, proj.Angle, proj.Pitch);
}
}
}
}