mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
- Only update to waypoints you're in the radius of (applies to players & spb)
- Player direction value uses momentum angle rather than facing angle (fixes weird nextwaypoint/position flickering while drifting) - Raise default radius to 384
This commit is contained in:
parent
4b04423bbe
commit
0fdcc22d93
5 changed files with 148 additions and 16 deletions
30
src/k_kart.c
30
src/k_kart.c
|
|
@ -5488,28 +5488,33 @@ void K_KartPlayerAfterThink(player_t *player)
|
||||||
|
|
||||||
Input Arguments:-
|
Input Arguments:-
|
||||||
player - The player the next waypoint is being found for
|
player - The player the next waypoint is being found for
|
||||||
|
closest - Use closest waypoint algorithm, instead of best touching
|
||||||
|
|
||||||
Return:-
|
Return:-
|
||||||
The waypoint that is the player's next waypoint
|
The waypoint that is the player's next waypoint
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
static waypoint_t *K_GetPlayerNextWaypoint(player_t *player, boolean closest)
|
||||||
{
|
{
|
||||||
waypoint_t *bestwaypoint = NULL;
|
waypoint_t *bestwaypoint = NULL;
|
||||||
if ((player != NULL) && (player->mo != NULL) && (P_MobjWasRemoved(player->mo) == false))
|
if ((player != NULL) && (player->mo != NULL) && (P_MobjWasRemoved(player->mo) == false))
|
||||||
{
|
{
|
||||||
waypoint_t *waypoint = NULL;
|
waypoint_t *waypoint = NULL;
|
||||||
|
|
||||||
waypoint = K_GetClosestWaypointToMobj(player->mo);
|
if (closest)
|
||||||
|
waypoint = K_GetClosestWaypointToMobj(player->mo);
|
||||||
|
else
|
||||||
|
waypoint = K_GetBestWaypointTouchingMobj(player->mo);
|
||||||
|
|
||||||
bestwaypoint = waypoint;
|
bestwaypoint = waypoint;
|
||||||
|
|
||||||
// check the waypoint's location in relation to the player
|
// check the waypoint's location in relation to the player
|
||||||
// If it's generally in front, it's fine, otherwise, use the best next/previous waypoint.
|
// If it's generally in front, it's fine, otherwise, use the best next/previous waypoint.
|
||||||
// EXCEPTION: If our closest waypoint is the finishline AND we're facing towards it, don't do this.
|
// EXCEPTION: If our best waypoint is the finishline AND we're facing towards it, don't do this.
|
||||||
// Otherwise it breaks the distance calculations.
|
// Otherwise it breaks the distance calculations.
|
||||||
if (waypoint != NULL)
|
if (waypoint != NULL)
|
||||||
{
|
{
|
||||||
boolean finishlinehack = false;
|
boolean finishlinehack = false;
|
||||||
angle_t playerangle = player->mo->angle;
|
angle_t playerangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); //player->mo->angle
|
||||||
angle_t angletowaypoint =
|
angle_t angletowaypoint =
|
||||||
R_PointToAngle2(player->mo->x, player->mo->y, waypoint->mobj->x, waypoint->mobj->y);
|
R_PointToAngle2(player->mo->x, player->mo->y, waypoint->mobj->x, waypoint->mobj->y);
|
||||||
angle_t angledelta = playerangle - angletowaypoint;
|
angle_t angledelta = playerangle - angletowaypoint;
|
||||||
|
|
@ -5667,9 +5672,16 @@ static void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
waypoint_t *finishline = K_GetFinishLineWaypoint();
|
waypoint_t *finishline = K_GetFinishLineWaypoint();
|
||||||
waypoint_t *nextwaypoint = K_GetPlayerNextWaypoint(player);
|
waypoint_t *nextwaypoint = K_GetPlayerNextWaypoint(player, false);
|
||||||
|
|
||||||
if ((nextwaypoint != player->nextwaypoint) &&
|
if ((nextwaypoint == NULL) && (player->nextwaypoint == NULL))
|
||||||
|
{
|
||||||
|
// Special case: if player nextwaypoint is still NULL, we want to fix that as soon as possible, so use the closest waypoint instead.
|
||||||
|
nextwaypoint = K_GetPlayerNextWaypoint(player, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((nextwaypoint != NULL) &&
|
||||||
|
(nextwaypoint != player->nextwaypoint) &&
|
||||||
(K_GetWaypointIsShortcut(nextwaypoint) == false) && (K_GetWaypointIsEnabled(nextwaypoint) == true))
|
(K_GetWaypointIsShortcut(nextwaypoint) == false) && (K_GetWaypointIsEnabled(nextwaypoint) == true))
|
||||||
{
|
{
|
||||||
size_t i = 0U;
|
size_t i = 0U;
|
||||||
|
|
@ -5699,7 +5711,11 @@ static void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
player->nextwaypoint = nextwaypoint;
|
if (nextwaypoint != NULL)
|
||||||
|
{
|
||||||
|
// At this point, we don't want to update the waypoint until we touch another.
|
||||||
|
player->nextwaypoint = nextwaypoint;
|
||||||
|
}
|
||||||
|
|
||||||
// nextwaypoint is now the waypoint that is in front of us
|
// nextwaypoint is now the waypoint that is in front of us
|
||||||
if ((player->nextwaypoint != NULL) && (finishline != NULL))
|
if ((player->nextwaypoint != NULL) && (finishline != NULL))
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,76 @@ waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj)
|
||||||
return closestwaypoint;
|
return closestwaypoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
waypoint_t *K_GetBestWaypointTouchingMobj(mobj_t *const mobj)
|
||||||
|
|
||||||
|
See header file for description.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
waypoint_t *K_GetBestWaypointTouchingMobj(mobj_t *const mobj)
|
||||||
|
{
|
||||||
|
waypoint_t *bestwaypoint = NULL;
|
||||||
|
|
||||||
|
if ((mobj == NULL) || P_MobjWasRemoved(mobj))
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "NULL mobj in K_GetBestWaypointTouchingMobj.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t i = 0U;
|
||||||
|
waypoint_t *checkwaypoint = NULL;
|
||||||
|
fixed_t bestdist = INT32_MAX;
|
||||||
|
fixed_t checkdist = INT32_MAX;
|
||||||
|
|
||||||
|
for (i = 0; i < numwaypoints; i++)
|
||||||
|
{
|
||||||
|
checkwaypoint = &waypointheap[i];
|
||||||
|
checkdist = P_AproxDistance(mobj->x - checkwaypoint->mobj->x, mobj->y - checkwaypoint->mobj->y);
|
||||||
|
checkdist = P_AproxDistance(checkdist, mobj->z - checkwaypoint->mobj->z);
|
||||||
|
|
||||||
|
// The mobj has to be touching this waypoint to update to it.
|
||||||
|
if (checkdist <= checkwaypoint->mobj->radius)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
// This kind of algorithm may or may not be more reliable than what's below.
|
||||||
|
// But it's a little heavier, computation-wise.
|
||||||
|
// We'll see if simple closer checks work fine in netgame testing, or if it needs this.
|
||||||
|
boolean success = false;
|
||||||
|
path_t pathtofinish = {};
|
||||||
|
success = K_PathfindToWaypoint(checkwaypoint, finishline, &pathtofinish, false, false);
|
||||||
|
|
||||||
|
// If you're touching more than 1 waypoint, then we use the closest one to the finish line.
|
||||||
|
if (success == true)
|
||||||
|
{
|
||||||
|
// Add euclidean distance to the next waypoint to the distancetofinish
|
||||||
|
UINT32 distancetofinish;
|
||||||
|
UINT32 adddist;
|
||||||
|
|
||||||
|
adddist = ((UINT32)checkdist) >> FRACBITS;
|
||||||
|
|
||||||
|
distancetofinish = pathtofinish.totaldist + adddist;
|
||||||
|
Z_Free(pathtofinish.array);
|
||||||
|
|
||||||
|
if (distancetofinish < bestdist)
|
||||||
|
{
|
||||||
|
bestwaypoint = checkwaypoint;
|
||||||
|
bestdist = checkdist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Simple closest check
|
||||||
|
if (checkdist < bestdist)
|
||||||
|
{
|
||||||
|
bestwaypoint = checkwaypoint;
|
||||||
|
bestdist = checkdist;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestwaypoint;
|
||||||
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
size_t K_GetWaypointHeapIndex(waypoint_t *waypoint)
|
size_t K_GetWaypointHeapIndex(waypoint_t *waypoint)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,20 @@ UINT32 K_GetCircuitLength(void);
|
||||||
waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj);
|
waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj);
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
waypoint_t *K_GetBestWaypointTouchingMobj(mobj_t *const mobj)
|
||||||
|
|
||||||
|
Returns the waypoint closest to the finish line that an mobj is touching
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
mobj - mobj to get the waypoint for.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
The best waypoint for the mobj
|
||||||
|
--------------------------------------------------*/
|
||||||
|
waypoint_t *K_GetBestWaypointTouchingMobj(mobj_t *const mobj);
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
boolean K_PathfindToWaypoint(
|
boolean K_PathfindToWaypoint(
|
||||||
waypoint_t *const sourcewaypoint,
|
waypoint_t *const sourcewaypoint,
|
||||||
|
|
|
||||||
|
|
@ -8511,9 +8511,9 @@ void A_SPBChase(mobj_t *actor)
|
||||||
if (actor->threshold) // Just fired, go straight.
|
if (actor->threshold) // Just fired, go straight.
|
||||||
{
|
{
|
||||||
actor->lastlook = -1;
|
actor->lastlook = -1;
|
||||||
|
actor->cusval = -1;
|
||||||
spbplace = -1;
|
spbplace = -1;
|
||||||
P_InstaThrust(actor, actor->angle, wspeed);
|
P_InstaThrust(actor, actor->angle, wspeed);
|
||||||
actor->flags &= ~MF_NOCLIPTHING; // just in case.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -8539,11 +8539,18 @@ void A_SPBChase(mobj_t *actor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lastlook = last player num targetted
|
||||||
|
// cvmem = stored speed
|
||||||
|
// cusval = next waypoint heap index
|
||||||
|
// extravalue1 = SPB movement mode
|
||||||
|
// extravalue2 = mode misc option
|
||||||
|
|
||||||
if (actor->extravalue1 == 1) // MODE: TARGETING
|
if (actor->extravalue1 == 1) // MODE: TARGETING
|
||||||
{
|
{
|
||||||
|
actor->cusval = -1; // Reset waypoint
|
||||||
|
|
||||||
if (actor->tracer && actor->tracer->health)
|
if (actor->tracer && actor->tracer->health)
|
||||||
{
|
{
|
||||||
|
|
||||||
fixed_t defspeed = wspeed;
|
fixed_t defspeed = wspeed;
|
||||||
fixed_t range = (160*actor->tracer->scale);
|
fixed_t range = (160*actor->tracer->scale);
|
||||||
fixed_t cx = 0, cy =0;
|
fixed_t cx = 0, cy =0;
|
||||||
|
|
@ -8678,6 +8685,7 @@ void A_SPBChase(mobj_t *actor)
|
||||||
else if (actor->extravalue1 == 2) // MODE: WAIT...
|
else if (actor->extravalue1 == 2) // MODE: WAIT...
|
||||||
{
|
{
|
||||||
actor->momx = actor->momy = actor->momz = 0; // Stoooop
|
actor->momx = actor->momy = actor->momz = 0; // Stoooop
|
||||||
|
actor->cusval = -1; // Reset waypoint
|
||||||
|
|
||||||
if (actor->lastlook != -1
|
if (actor->lastlook != -1
|
||||||
&& playeringame[actor->lastlook]
|
&& playeringame[actor->lastlook]
|
||||||
|
|
@ -8703,8 +8711,10 @@ void A_SPBChase(mobj_t *actor)
|
||||||
}
|
}
|
||||||
else // MODE: SEEKING
|
else // MODE: SEEKING
|
||||||
{
|
{
|
||||||
waypoint_t *closestwaypoint = NULL;
|
waypoint_t *lastwaypoint = NULL;
|
||||||
waypoint_t *nextwaypoint = NULL;
|
waypoint_t *bestwaypoint = NULL;
|
||||||
|
waypoint_t *nextwaypoint = NULL;
|
||||||
|
|
||||||
actor->lastlook = -1; // Just make sure this is reset
|
actor->lastlook = -1; // Just make sure this is reset
|
||||||
|
|
||||||
if (!player || !player->mo || player->mo->health <= 0 || player->kartstuff[k_respawn])
|
if (!player || !player->mo || player->mo->health <= 0 || player->kartstuff[k_respawn])
|
||||||
|
|
@ -8719,11 +8729,24 @@ void A_SPBChase(mobj_t *actor)
|
||||||
// Found someone, now get close enough to initiate the slaughter...
|
// Found someone, now get close enough to initiate the slaughter...
|
||||||
P_SetTarget(&actor->tracer, player->mo);
|
P_SetTarget(&actor->tracer, player->mo);
|
||||||
spbplace = bestrank;
|
spbplace = bestrank;
|
||||||
|
|
||||||
dist = P_AproxDistance(P_AproxDistance(actor->x-actor->tracer->x, actor->y-actor->tracer->y), actor->z-actor->tracer->z);
|
dist = P_AproxDistance(P_AproxDistance(actor->x-actor->tracer->x, actor->y-actor->tracer->y), actor->z-actor->tracer->z);
|
||||||
|
|
||||||
closestwaypoint = K_GetClosestWaypointToMobj(actor);
|
// Move along the waypoints until you get close enough
|
||||||
if (closestwaypoint != NULL)
|
if (actor->cusval > -1)
|
||||||
|
{
|
||||||
|
// Previously set nextwaypoint
|
||||||
|
lastwaypoint = K_GetWaypointFromIndex((size_t)actor->cusval);
|
||||||
|
}
|
||||||
|
|
||||||
|
bestwaypoint = K_GetBestWaypointTouchingMobj(actor);
|
||||||
|
|
||||||
|
if (bestwaypoint == NULL && lastwaypoint == NULL)
|
||||||
|
{
|
||||||
|
// We have invalid waypoints all around, so use closest to try and make it non-NULL.
|
||||||
|
bestwaypoint = K_GetClosestWaypointToMobj(actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestwaypoint != NULL)
|
||||||
{
|
{
|
||||||
const boolean huntbackwards = false;
|
const boolean huntbackwards = false;
|
||||||
boolean useshortcuts = false;
|
boolean useshortcuts = false;
|
||||||
|
|
@ -8735,15 +8758,24 @@ void A_SPBChase(mobj_t *actor)
|
||||||
}
|
}
|
||||||
|
|
||||||
nextwaypoint = K_GetNextWaypointToDestination(
|
nextwaypoint = K_GetNextWaypointToDestination(
|
||||||
closestwaypoint, player->nextwaypoint, useshortcuts, huntbackwards);
|
bestwaypoint, player->nextwaypoint, useshortcuts, huntbackwards);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextwaypoint == NULL && lastwaypoint != NULL)
|
||||||
|
{
|
||||||
|
// Restore to the last nextwaypoint
|
||||||
|
nextwaypoint = lastwaypoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextwaypoint != NULL)
|
if (nextwaypoint != NULL)
|
||||||
{
|
{
|
||||||
const fixed_t xywaypointdist = P_AproxDistance(
|
const fixed_t xywaypointdist = P_AproxDistance(
|
||||||
actor->x - nextwaypoint->mobj->x, actor->y - nextwaypoint->mobj->y);
|
actor->x - nextwaypoint->mobj->x, actor->y - nextwaypoint->mobj->y);
|
||||||
|
|
||||||
hang = R_PointToAngle2(actor->x, actor->y, nextwaypoint->mobj->x, nextwaypoint->mobj->y);
|
hang = R_PointToAngle2(actor->x, actor->y, nextwaypoint->mobj->x, nextwaypoint->mobj->y);
|
||||||
vang = R_PointToAngle2(0, actor->z, xywaypointdist, nextwaypoint->mobj->z);
|
vang = R_PointToAngle2(0, actor->z, xywaypointdist, nextwaypoint->mobj->z);
|
||||||
|
|
||||||
|
actor->cusval = (INT32)K_GetWaypointHeapIndex(nextwaypoint);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12289,7 +12289,7 @@ ML_NOCLIMB : Direction not controllable
|
||||||
case MT_WAYPOINT:
|
case MT_WAYPOINT:
|
||||||
{
|
{
|
||||||
size_t line;
|
size_t line;
|
||||||
mobj->radius = 256*FRACUNIT;
|
mobj->radius = 384*FRACUNIT;
|
||||||
// Same reason as for MT_SPINMACEPOINT we can't use the function to find the linedef
|
// Same reason as for MT_SPINMACEPOINT we can't use the function to find the linedef
|
||||||
for (line = 0; line < numlines; line++)
|
for (line = 0; line < numlines; line++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue