Fixed Thing_ProjectileAimed being broken.

- It was calling the fallback aiming in the wrong place when it should have been outside the speed check.
- Credit to _mental_ for the base code, but no gotos involved.
This commit is contained in:
Major Cooke 2019-01-06 12:27:14 -06:00 committed by Christoph Oelckers
parent 83ce72db48
commit 7666997580

View file

@ -163,16 +163,30 @@ bool P_Thing_Move (int tid, AActor *source, int mapspot, bool fog)
return false; return false;
} }
//==========================================================================
//
// VelIntercept
//
//==========================================================================
void InterceptDefaultAim(AActor *mobj, AActor *targ, DVector3 aim, double speed)
{
if (mobj == nullptr || targ == nullptr) return;
mobj->Angles.Yaw = mobj->AngleTo(targ);
mobj->Vel = aim.Resized(speed);
}
// [MC] Was part of P_Thing_Projectile, now its own function for use in ZScript. // [MC] Was part of P_Thing_Projectile, now its own function for use in ZScript.
// Aims mobj at targ based on speed and targ's velocity. // Aims mobj at targ based on speed and targ's velocity.
void VelIntercept(AActor *targ, AActor *mobj, double speed, bool aimpitch = false, bool oldvel = false) static void VelIntercept(AActor *targ, AActor *mobj, double speed, bool aimpitch = false, bool oldvel = false, bool leadtarget = true)
{ {
if (targ == nullptr || mobj == nullptr) return; if (targ == nullptr || mobj == nullptr) return;
if (speed > 0 && !targ->Vel.isZero())
{
DVector3 aim = mobj->Vec3To(targ); DVector3 aim = mobj->Vec3To(targ);
aim.Z += targ->Height / 2; aim.Z += targ->Height / 2;
if (leadtarget && speed > 0 && !targ->Vel.isZero())
{
// Aiming at the target's position some time in the future // Aiming at the target's position some time in the future
// is basically just an application of the law of sines: // is basically just an application of the law of sines:
// a/sin(A) = b/sin(B) // a/sin(A) = b/sin(B)
@ -180,7 +194,6 @@ void VelIntercept(AActor *targ, AActor *mobj, double speed, bool aimpitch = fals
// with the math. I don't think I would have thought of using // with the math. I don't think I would have thought of using
// trig alone had I been left to solve it by myself. // trig alone had I been left to solve it by myself.
bool nolead = false;
DVector3 tvel = targ->Vel; DVector3 tvel = targ->Vel;
if (!(targ->flags & MF_NOGRAVITY) && targ->waterlevel < 3) if (!(targ->flags & MF_NOGRAVITY) && targ->waterlevel < 3)
{ // If the target is subject to gravity and not underwater, { // If the target is subject to gravity and not underwater,
@ -188,10 +201,13 @@ void VelIntercept(AActor *targ, AActor *mobj, double speed, bool aimpitch = fals
// even if we did consider the vertical component of the target's // even if we did consider the vertical component of the target's
// velocity, we would still miss more often than not. // velocity, we would still miss more often than not.
tvel.Z = 0.0; tvel.Z = 0.0;
nolead = !!(targ->Vel.X == 0 && targ->Vel.Y == 0);
} if (targ->Vel.X == 0 && targ->Vel.Y == 0)
if (!nolead)
{ {
InterceptDefaultAim(mobj, targ, aim, speed);
return;
}
}
double dist = aim.Length(); double dist = aim.Length();
double targspeed = tvel.Length(); double targspeed = tvel.Length();
double ydotx = -aim | tvel; double ydotx = -aim | tvel;
@ -224,9 +240,7 @@ void VelIntercept(AActor *targ, AActor *mobj, double speed, bool aimpitch = fals
} }
else else
{ {
mobj->Angles.Yaw = mobj->AngleTo(targ); InterceptDefaultAim(mobj, targ, aim, speed);
mobj->Vel = aim.Resized(speed);
}
} }
} }
@ -325,10 +339,8 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam
if (targ != nullptr) if (targ != nullptr)
{ {
if (leadTarget) VelIntercept(targ, mobj, speed, false, false, leadTarget);
{
VelIntercept(targ, mobj, speed);
}
if (mobj->flags2 & MF2_SEEKERMISSILE) if (mobj->flags2 & MF2_SEEKERMISSILE)
{ {
mobj->tracer = targ; mobj->tracer = targ;