mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Don't allow nextwaypoint to be past finish linedef
This commit is contained in:
parent
cb580031ca
commit
0053cda35c
4 changed files with 98 additions and 107 deletions
121
src/k_kart.c
121
src/k_kart.c
|
|
@ -8848,6 +8848,7 @@ void K_KartPlayerAfterThink(player_t *player)
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
||||||
{
|
{
|
||||||
|
waypoint_t *finishline = K_GetFinishLineWaypoint();
|
||||||
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))
|
||||||
|
|
@ -8864,13 +8865,15 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
||||||
// Otherwise it breaks the distance calculations.
|
// Otherwise it breaks the distance calculations.
|
||||||
if (waypoint != NULL)
|
if (waypoint != NULL)
|
||||||
{
|
{
|
||||||
boolean finishlinehack = false;
|
|
||||||
angle_t playerangle = player->mo->angle;
|
angle_t playerangle = player->mo->angle;
|
||||||
angle_t momangle = K_MomentumAngle(player->mo);
|
angle_t momangle = K_MomentumAngle(player->mo);
|
||||||
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 = ANGLE_MAX;
|
angle_t angledelta = ANGLE_180;
|
||||||
angle_t momdelta = ANGLE_MAX;
|
angle_t momdelta = ANGLE_180;
|
||||||
|
|
||||||
|
// Remove WRONG WAY flag.
|
||||||
|
player->pflags &= ~PF_WRONGWAY;
|
||||||
|
|
||||||
angledelta = playerangle - angletowaypoint;
|
angledelta = playerangle - angletowaypoint;
|
||||||
if (angledelta > ANGLE_180)
|
if (angledelta > ANGLE_180)
|
||||||
|
|
@ -8884,31 +8887,15 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
||||||
momdelta = InvAngle(momdelta);
|
momdelta = InvAngle(momdelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bestwaypoint == K_GetFinishLineWaypoint())
|
|
||||||
{
|
|
||||||
waypoint_t *nextwaypoint = waypoint->nextwaypoints[0];
|
|
||||||
angle_t angletonextwaypoint =
|
|
||||||
R_PointToAngle2(waypoint->mobj->x, waypoint->mobj->y, nextwaypoint->mobj->x, nextwaypoint->mobj->y);
|
|
||||||
|
|
||||||
// facing towards the finishline
|
|
||||||
if (AngleDelta(angletonextwaypoint, angletowaypoint) <= ANGLE_90)
|
|
||||||
{
|
|
||||||
finishlinehack = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We're using a lot of angle calculations here, because only using facing angle or only using momentum angle both have downsides.
|
// We're using a lot of angle calculations here, because only using facing angle or only using momentum angle both have downsides.
|
||||||
// nextwaypoints will be picked if you're facing OR moving forward.
|
// nextwaypoints will be picked if you're facing OR moving forward.
|
||||||
// prevwaypoints will be picked if you're facing AND moving backward.
|
// prevwaypoints will be picked if you're facing AND moving backward.
|
||||||
if (
|
|
||||||
#if 0
|
#if 0
|
||||||
(angledelta > ANGLE_45 || momdelta > ANGLE_45) &&
|
if (angledelta > ANGLE_45 || momdelta > ANGLE_45)
|
||||||
#endif
|
#endif
|
||||||
(finishlinehack == false)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
angle_t nextbestdelta = ANGLE_MAX;
|
angle_t nextbestdelta = ANGLE_90;
|
||||||
angle_t nextbestmomdelta = ANGLE_MAX;
|
angle_t nextbestmomdelta = ANGLE_90;
|
||||||
size_t i = 0U;
|
size_t i = 0U;
|
||||||
|
|
||||||
if ((waypoint->nextwaypoints != NULL) && (waypoint->numnextwaypoints > 0U))
|
if ((waypoint->nextwaypoints != NULL) && (waypoint->numnextwaypoints > 0U))
|
||||||
|
|
@ -8952,10 +8939,13 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
||||||
|
|
||||||
if (angledelta < nextbestdelta || momdelta < nextbestmomdelta)
|
if (angledelta < nextbestdelta || momdelta < nextbestmomdelta)
|
||||||
{
|
{
|
||||||
if (P_TraceBlockingLines(player->mo, waypoint->nextwaypoints[i]->mobj) == false)
|
if (waypoint->nextwaypoints[i] != finishline) // Allow finish line.
|
||||||
{
|
{
|
||||||
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
if (P_TraceWaypointTraversal(player->mo, waypoint->nextwaypoints[i]->mobj) == false)
|
||||||
continue;
|
{
|
||||||
|
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bestwaypoint = waypoint->nextwaypoints[i];
|
bestwaypoint = waypoint->nextwaypoints[i];
|
||||||
|
|
@ -8969,8 +8959,6 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
||||||
nextbestmomdelta = momdelta;
|
nextbestmomdelta = momdelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove wrong way flag if we're using nextwaypoints
|
|
||||||
player->pflags &= ~PF_WRONGWAY;
|
|
||||||
updaterespawn = true;
|
updaterespawn = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9004,7 +8992,7 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
||||||
|
|
||||||
if (angledelta < nextbestdelta && momdelta < nextbestmomdelta)
|
if (angledelta < nextbestdelta && momdelta < nextbestmomdelta)
|
||||||
{
|
{
|
||||||
if (P_TraceBlockingLines(player->mo, waypoint->prevwaypoints[i]->mobj) == false)
|
if (P_TraceWaypointTraversal(player->mo, waypoint->prevwaypoints[i]->mobj) == false)
|
||||||
{
|
{
|
||||||
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -9044,69 +9032,6 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
||||||
return bestwaypoint;
|
return bestwaypoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static boolean K_PlayerCloserToNextWaypoints(waypoint_t *const waypoint, player_t *const player)
|
|
||||||
{
|
|
||||||
boolean nextiscloser = true;
|
|
||||||
|
|
||||||
if ((waypoint != NULL) && (player != NULL) && (player->mo != NULL))
|
|
||||||
{
|
|
||||||
size_t i = 0U;
|
|
||||||
waypoint_t *currentwpcheck = NULL;
|
|
||||||
angle_t angletoplayer = ANGLE_MAX;
|
|
||||||
angle_t currentanglecheck = ANGLE_MAX;
|
|
||||||
angle_t bestangle = ANGLE_MAX;
|
|
||||||
|
|
||||||
angletoplayer = R_PointToAngle2(waypoint->mobj->x, waypoint->mobj->y,
|
|
||||||
player->mo->x, player->mo->y);
|
|
||||||
|
|
||||||
for (i = 0U; i < waypoint->numnextwaypoints; i++)
|
|
||||||
{
|
|
||||||
currentwpcheck = waypoint->nextwaypoints[i];
|
|
||||||
currentanglecheck = R_PointToAngle2(
|
|
||||||
waypoint->mobj->x, waypoint->mobj->y, currentwpcheck->mobj->x, currentwpcheck->mobj->y);
|
|
||||||
|
|
||||||
// Get delta angle
|
|
||||||
currentanglecheck = currentanglecheck - angletoplayer;
|
|
||||||
|
|
||||||
if (currentanglecheck > ANGLE_180)
|
|
||||||
{
|
|
||||||
currentanglecheck = InvAngle(currentanglecheck);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentanglecheck < bestangle)
|
|
||||||
{
|
|
||||||
bestangle = currentanglecheck;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0U; i < waypoint->numprevwaypoints; i++)
|
|
||||||
{
|
|
||||||
currentwpcheck = waypoint->prevwaypoints[i];
|
|
||||||
currentanglecheck = R_PointToAngle2(
|
|
||||||
waypoint->mobj->x, waypoint->mobj->y, currentwpcheck->mobj->x, currentwpcheck->mobj->y);
|
|
||||||
|
|
||||||
// Get delta angle
|
|
||||||
currentanglecheck = currentanglecheck - angletoplayer;
|
|
||||||
|
|
||||||
if (currentanglecheck > ANGLE_180)
|
|
||||||
{
|
|
||||||
currentanglecheck = InvAngle(currentanglecheck);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentanglecheck < bestangle)
|
|
||||||
{
|
|
||||||
bestangle = currentanglecheck;
|
|
||||||
nextiscloser = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nextiscloser;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
void K_UpdateDistanceFromFinishLine(player_t *const player)
|
void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||||
|
|
||||||
|
|
@ -9302,21 +9227,7 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||||
if ((mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE) == 0U)
|
if ((mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE) == 0U)
|
||||||
{
|
{
|
||||||
const UINT8 numfulllapsleft = ((UINT8)numlaps - player->laps);
|
const UINT8 numfulllapsleft = ((UINT8)numlaps - player->laps);
|
||||||
|
|
||||||
player->distancetofinish += numfulllapsleft * K_GetCircuitLength();
|
player->distancetofinish += numfulllapsleft * K_GetCircuitLength();
|
||||||
|
|
||||||
#if 0
|
|
||||||
// An additional HACK, to fix looking backwards towards the finish line
|
|
||||||
// If the player's next waypoint is the finishline and the angle distance from player to
|
|
||||||
// connectin waypoints implies they're closer to a next waypoint, add a full track distance
|
|
||||||
if (player->nextwaypoint == finishline)
|
|
||||||
{
|
|
||||||
if (K_PlayerCloserToNextWaypoints(player->nextwaypoint, player) == true)
|
|
||||||
{
|
|
||||||
player->distancetofinish += K_GetCircuitLength();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -361,7 +361,7 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj)
|
||||||
// remember: huge radius
|
// remember: huge radius
|
||||||
if (closestdist <= rad && checkdist <= rad && finishline != NULL)
|
if (closestdist <= rad && checkdist <= rad && finishline != NULL)
|
||||||
{
|
{
|
||||||
if (!P_TraceBlockingLines(mobj, checkwaypoint->mobj))
|
if (!P_TraceBlockingLines(mobj, checkwaypoint->mobj)) // Intentionally not P_TraceWaypointTraversal
|
||||||
{
|
{
|
||||||
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -379,7 +379,7 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj)
|
||||||
}
|
}
|
||||||
else if (checkdist < closestdist && bestfindist == INT32_MAX)
|
else if (checkdist < closestdist && bestfindist == INT32_MAX)
|
||||||
{
|
{
|
||||||
if (!P_TraceBlockingLines(mobj, checkwaypoint->mobj))
|
if (!P_TraceBlockingLines(mobj, checkwaypoint->mobj)) // Intentionally not P_TraceWaypointTraversal
|
||||||
{
|
{
|
||||||
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
// Save sight checks when all of the other checks pass, so we only do it if we have to
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -456,6 +456,7 @@ void P_BounceMove(mobj_t *mo, TryMoveResult_t *result);
|
||||||
boolean P_CheckSight(mobj_t *t1, mobj_t *t2);
|
boolean P_CheckSight(mobj_t *t1, mobj_t *t2);
|
||||||
boolean P_TraceBlockingLines(mobj_t *t1, mobj_t *t2);
|
boolean P_TraceBlockingLines(mobj_t *t1, mobj_t *t2);
|
||||||
boolean P_TraceBotTraversal(mobj_t *t1, mobj_t *t2);
|
boolean P_TraceBotTraversal(mobj_t *t1, mobj_t *t2);
|
||||||
|
boolean P_TraceWaypointTraversal(mobj_t *t1, mobj_t *t2);
|
||||||
void P_CheckHoopPosition(mobj_t *hoopthing, fixed_t x, fixed_t y, fixed_t z, fixed_t radius);
|
void P_CheckHoopPosition(mobj_t *hoopthing, fixed_t x, fixed_t y, fixed_t z, fixed_t radius);
|
||||||
|
|
||||||
boolean P_CheckSector(sector_t *sector, boolean crunch);
|
boolean P_CheckSector(sector_t *sector, boolean crunch);
|
||||||
|
|
|
||||||
|
|
@ -392,6 +392,26 @@ static boolean P_CanBotTraverse(seg_t *seg, divline_t *divl, register los_t *los
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean P_CanWaypointTraverse(seg_t *seg, divline_t *divl, register los_t *los)
|
||||||
|
{
|
||||||
|
line_t *line = seg->linedef;
|
||||||
|
|
||||||
|
if (P_CanTraceBlockingLine(seg, divl, los) == false)
|
||||||
|
{
|
||||||
|
// Blocked, so obviously can't traverse either.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line->special == 2001)
|
||||||
|
{
|
||||||
|
// Don't allow through the finish linedef.
|
||||||
|
// Causes some janky behavior.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_CrossSubsector
|
// P_CrossSubsector
|
||||||
//
|
//
|
||||||
|
|
@ -780,3 +800,62 @@ boolean P_TraceBotTraversal(mobj_t *t1, mobj_t *t2)
|
||||||
return P_CrossBSPNode((INT32)numnodes - 1, &los, &funcs);
|
return P_CrossBSPNode((INT32)numnodes - 1, &los, &funcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean P_TraceWaypointTraversal(mobj_t *t1, mobj_t *t2)
|
||||||
|
{
|
||||||
|
const sector_t *s1, *s2;
|
||||||
|
size_t pnum;
|
||||||
|
los_t los;
|
||||||
|
los_funcs_t funcs;
|
||||||
|
|
||||||
|
// First check for trivial rejection.
|
||||||
|
if (!t1 || !t2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
I_Assert(!P_MobjWasRemoved(t1));
|
||||||
|
I_Assert(!P_MobjWasRemoved(t2));
|
||||||
|
|
||||||
|
if (!t1->subsector || !t2->subsector
|
||||||
|
|| !t1->subsector->sector || !t2->subsector->sector)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
s1 = t1->subsector->sector;
|
||||||
|
s2 = t2->subsector->sector;
|
||||||
|
pnum = (s1-sectors)*numsectors + (s2-sectors);
|
||||||
|
|
||||||
|
if (rejectmatrix != NULL)
|
||||||
|
{
|
||||||
|
// Check in REJECT table.
|
||||||
|
if (rejectmatrix[pnum>>3] & (1 << (pnum&7))) // can't possibly be connected
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// killough 11/98: shortcut for melee situations
|
||||||
|
// same subsector? obviously visible
|
||||||
|
// haleyjd 02/23/06: can't do this if there are polyobjects in the subsec
|
||||||
|
if (!t1->subsector->polyList &&
|
||||||
|
t1->subsector == t2->subsector)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
validcount++;
|
||||||
|
|
||||||
|
los.strace.dx = (los.t2x = t2->x) - (los.strace.x = t1->x);
|
||||||
|
los.strace.dy = (los.t2y = t2->y) - (los.strace.y = t1->y);
|
||||||
|
|
||||||
|
if (t1->x > t2->x)
|
||||||
|
los.bbox[BOXRIGHT] = t1->x, los.bbox[BOXLEFT] = t2->x;
|
||||||
|
else
|
||||||
|
los.bbox[BOXRIGHT] = t2->x, los.bbox[BOXLEFT] = t1->x;
|
||||||
|
|
||||||
|
if (t1->y > t2->y)
|
||||||
|
los.bbox[BOXTOP] = t1->y, los.bbox[BOXBOTTOM] = t2->y;
|
||||||
|
else
|
||||||
|
los.bbox[BOXTOP] = t2->y, los.bbox[BOXBOTTOM] = t1->y;
|
||||||
|
|
||||||
|
los.compareThing = t1;
|
||||||
|
los.alreadyHates = false;
|
||||||
|
|
||||||
|
funcs.validate = &P_CanWaypointTraverse;
|
||||||
|
|
||||||
|
// the head node is the last node output
|
||||||
|
return P_CrossBSPNode((INT32)numnodes - 1, &los, &funcs);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue