diff --git a/src/p_local.h b/src/p_local.h index 3aff45bf0..e42dc960d 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -94,7 +94,7 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer=false); void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move); int P_FaceMobj (AActor *source, AActor *target, angle_t *delta); -bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax); +bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise = false); enum EPuffFlags { diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 613054652..dbb3f38b7 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1543,11 +1543,12 @@ bool AActor::CanSeek(AActor *target) const // //---------------------------------------------------------------------------- -bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax) +bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise) { int dir; + int dist; angle_t delta; - angle_t angle, pitch; + angle_t angle; AActor *target; target = actor->tracer; @@ -1577,30 +1578,55 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax) { // Turn counter clockwise actor->angle -= delta; } - angle = actor->angle >> ANGLETOFINESHIFT; - pitch = 0; + angle = actor->angle>>ANGLETOFINESHIFT; + + if (!precise) + { + actor->velx = FixedMul (actor->Speed, finecosine[angle]); + actor->vely = FixedMul (actor->Speed, finesine[angle]); - if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) - { // Need to seek vertically - double dist = MAX(1.0, FVector2(target->x - actor->x, target->y - actor->y).Length()); - // Aim at a player's eyes and at the middle of the actor for everything else. - fixed_t aimheight = target->height/2; - if (target->IsKindOf(RUNTIME_CLASS(APlayerPawn))) + if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) { - aimheight = static_cast(target)->ViewHeight; + if (actor->z + actor->height < target->z || + target->z + target->height < actor->z) + { // Need to seek vertically + dist = P_AproxDistance (target->x - actor->x, target->y - actor->y); + dist = dist / actor->Speed; + if (dist < 1) + { + dist = 1; + } + actor->velz = ((target->z+target->height/2) - (actor->z+actor->height/2)) / dist; + } } - pitch = R_PointToAngle2(0, actor->z + actor->height/2, xs_CRoundToInt(dist), target->z + aimheight); - pitch >>= ANGLETOFINESHIFT; + } + else + { + angle_t pitch; + if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) + { // Need to seek vertically + double dist = MAX(1.0, FVector2(target->x - actor->x, target->y - actor->y).Length()); + // Aim at a player's eyes and at the middle of the actor for everything else. + fixed_t aimheight = target->height/2; + if (target->IsKindOf(RUNTIME_CLASS(APlayerPawn))) + { + aimheight = static_cast(target)->ViewHeight; + } + pitch = R_PointToAngle2(0, actor->z + actor->height/2, xs_CRoundToInt(dist), target->z + aimheight); + pitch >>= ANGLETOFINESHIFT; + } + + fixed_t xyscale = FixedMul(actor->Speed, finecosine[pitch]); + actor->velz = FixedMul(actor->Speed, finesine[pitch]); + actor->velx = FixedMul(xyscale, finecosine[angle]); + actor->vely = FixedMul(xyscale, finesine[angle]); } - fixed_t xyscale = FixedMul(actor->Speed, finecosine[pitch]); - actor->velz = FixedMul(actor->Speed, finesine[pitch]); - actor->velx = FixedMul(xyscale, finecosine[angle]); - actor->vely = FixedMul(xyscale, finesine[angle]); return true; } + // // P_XYMovement // diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 45038d83f..6d066684b 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -346,6 +346,7 @@ static FRandom pr_seekermissile ("SeekerMissile"); enum { SMF_LOOK = 1, + SMF_PRECISE = 2, }; DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SeekerMissile) { @@ -360,7 +361,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SeekerMissile) { self->tracer = P_RoughMonsterSearch (self, distance); } - P_SeekerMissile(self, clamp(ang1, 0, 90) * ANGLE_1, clamp(ang2, 0, 90) * ANGLE_1); + P_SeekerMissile(self, clamp(ang1, 0, 90) * ANGLE_1, clamp(ang2, 0, 90) * ANGLE_1, !!(flags & SMF_PRECISE)); } //========================================================================== diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 0e1f8f903..0fd613a72 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -79,6 +79,7 @@ const int BF_AFFECTBOSSES = 4; // Flags for A_SeekerMissile const int SMF_LOOK = 1; +const int SMF_PRECISE = 2; // Activation flags enum