diff --git a/src/p_enemy.c b/src/p_enemy.c index 7baca2adc..14eea8135 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8309,7 +8309,11 @@ void A_ItemPop(mobj_t *actor) void A_JawzChase(mobj_t *actor) { + const fixed_t currentspeed = R_PointToDist2(0, 0, actor->momx, actor->momy); player_t *player; + fixed_t thrustamount = 0; + fixed_t frictionsafety = (actor->friction == 0) ? 1 : actor->friction; + fixed_t topspeed = actor->movefactor; #ifdef HAVE_BLUA if (LUA_CallAction("A_JawzChase", actor)) return; @@ -8322,20 +8326,102 @@ void A_JawzChase(mobj_t *actor) if (actor->tracer->health) { + const angle_t targetangle = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y); mobj_t *ret; + angle_t angledelta = actor->angle - targetangle; + boolean turnclockwise = true; + + if (G_RaceGametype()) + { + const fixed_t distbarrier = FixedMul(512*mapobjectscale, FRACUNIT + ((gamespeed-1) * (FRACUNIT/4))); + const fixed_t distaway = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); + if (distaway < distbarrier) + { + if (actor->tracer->player) + { + fixed_t speeddifference = abs(topspeed - min(actor->tracer->player->speed, K_GetKartSpeed(actor->tracer->player, false))); + topspeed = topspeed - FixedMul(speeddifference, FRACUNIT-FixedDiv(distaway, distbarrier)); + } + } + } + + if (angledelta != 0) + { + angle_t MAX_JAWZ_TURN = ANGLE_90/15; // We can turn a maximum of 6 degrees per frame at regular max speed + // MAX_JAWZ_TURN gets stronger the slower the top speed of jawz + if (topspeed < actor->movefactor) + { + if (topspeed == 0) + { + MAX_JAWZ_TURN = ANGLE_180; + } + else + { + fixed_t anglemultiplier = FixedDiv(actor->movefactor, topspeed); + MAX_JAWZ_TURN += FixedAngle(FixedMul(AngleFixed(MAX_JAWZ_TURN), anglemultiplier)); + } + } + + if (angledelta > ANGLE_180) + { + angledelta = InvAngle(angledelta); + turnclockwise = false; + } + + if (angledelta > MAX_JAWZ_TURN) + { + angledelta = MAX_JAWZ_TURN; + } + + if (turnclockwise) + { + actor->angle -= angledelta; + } + else + { + actor->angle += angledelta; + } + } + + CONS_Printf("ad: %d\n", angledelta); ret = P_SpawnMobj(actor->tracer->x, actor->tracer->y, actor->tracer->z, MT_PLAYERRETICULE); P_SetTarget(&ret->target, actor->tracer); ret->frame |= ((leveltime % 10) / 2) + 5; ret->color = actor->cvmem; - - P_Thrust(actor, R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y), (7*actor->movefactor)/64); - return; } else P_SetTarget(&actor->tracer, NULL); } + if (!P_IsObjectOnGround(actor)) + { + // No friction in the air + frictionsafety = FRACUNIT; + } + + if (currentspeed >= topspeed) + { + // Thrust as if you were at top speed, slow down naturally + thrustamount = FixedDiv(topspeed, frictionsafety) - topspeed; + } + else + { + const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed; + // Thrust to immediately get to top speed + thrustamount = beatfriction + FixedDiv(topspeed - currentspeed, frictionsafety); + } + + if (!actor->tracer) + { + actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); + } + + P_Thrust(actor, actor->angle, thrustamount); + + if ((actor->tracer != NULL) && (actor->tracer->health > 0)) + return; + if (actor->extravalue1) // Disable looking by setting this return; diff --git a/src/p_mobj.c b/src/p_mobj.c index f9bfc807b..aae777335 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7989,12 +7989,6 @@ void P_MobjThinker(mobj_t *mobj) case MT_JAWZ: { sector_t *sec2; - fixed_t topspeed = mobj->movefactor; - fixed_t distbarrier = 512*mapobjectscale; - fixed_t distaway; - const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy); - fixed_t thrustamount = 0; - fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction; mobj_t *ghost = P_SpawnGhostMobj(mobj); if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player) @@ -8008,47 +8002,7 @@ void P_MobjThinker(mobj_t *mobj) if (leveltime % TICRATE == 0) S_StartSound(mobj, mobj->info->activesound); - distbarrier = FixedMul(distbarrier, FRACUNIT + ((gamespeed-1) * (FRACUNIT/4))); - - if (!P_IsObjectOnGround(mobj)) - { - // No friction in the air - frictionsafety = FRACUNIT; - } - - if (G_RaceGametype() && mobj->tracer) - { - distaway = P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y); - if (distaway < distbarrier) - { - if (mobj->tracer->player) - { - fixed_t speeddifference = abs(topspeed - min(mobj->tracer->player->speed, K_GetKartSpeed(mobj->tracer->player, false))); - topspeed = topspeed - FixedMul(speeddifference, FRACUNIT-FixedDiv(distaway, distbarrier)); - } - } - } - - // Don't thrust at ALL if we're in the barrier range and above top speed, harsher slowdown - if ((currentspeed >= topspeed) && (topspeed == mobj->movefactor)) - { - // Thrust as if you were at top speed, slow down naturally - thrustamount = FixedDiv(topspeed, frictionsafety) - topspeed; - } - else - { - const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed; - // Thrust to immediately get to top speed - thrustamount = beatfriction + FixedDiv(topspeed - currentspeed, frictionsafety); - } - - mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); - P_Thrust(mobj, mobj->angle, thrustamount); - - if (mobj->tracer) - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); - else - mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); + // Movement handling has ALL been moved to A_JawzChase K_DriftDustHandling(mobj);