mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-03-08 04:06:25 +00:00
Merge branch 'jumping-finish-line-distance' into 'master'
Finish line waypoint issues See merge request KartKrew/Kart!384
This commit is contained in:
commit
8853a4b8e3
7 changed files with 195 additions and 20 deletions
10
src/k_kart.c
10
src/k_kart.c
|
|
@ -6553,8 +6553,12 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
|||
|
||||
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 <= ANGLE_90)
|
||||
if (abs(AngleDifference(angletonextwaypoint, angletowaypoint)) <= ANGLE_90)
|
||||
{
|
||||
finishlinehack = true;
|
||||
}
|
||||
|
|
@ -6698,6 +6702,7 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
|||
return bestwaypoint;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static boolean K_PlayerCloserToNextWaypoints(waypoint_t *const waypoint, player_t *const player)
|
||||
{
|
||||
boolean nextiscloser = true;
|
||||
|
|
@ -6758,6 +6763,7 @@ static boolean K_PlayerCloserToNextWaypoints(waypoint_t *const waypoint, player_
|
|||
|
||||
return nextiscloser;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||
|
|
@ -6837,6 +6843,7 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
|
|||
|
||||
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
|
||||
|
|
@ -6847,6 +6854,7 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
|
|||
player->distancetofinish += K_GetCircuitLength();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,21 @@ fixed_t K_RespawnOffset(player_t *player, boolean flip)
|
|||
return z;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_FudgeRespawn(player_t *player, const waypoint_t *const waypoint)
|
||||
|
||||
Fudges respawn coordinates to slightly before the waypoint if it would
|
||||
be exactly on a line. See K_GetWaypointIsOnLine.
|
||||
--------------------------------------------------*/
|
||||
static void K_FudgeRespawn(player_t *player, const waypoint_t *const waypoint)
|
||||
{
|
||||
const angle_t from = R_PointToAngle2(waypoint->mobj->x, waypoint->mobj->y,
|
||||
player->mo->x, player->mo->y) >> ANGLETOFINESHIFT;
|
||||
|
||||
player->respawn.pointx += FixedMul(16, FINECOSINE(from));
|
||||
player->respawn.pointy += FixedMul(16, FINESINE(from));
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
|
||||
|
||||
|
|
@ -83,6 +98,11 @@ static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
|
|||
player->respawn.pointz = waypoint->mobj->z;
|
||||
player->respawn.flip = (waypoint->mobj->flags2 & MF2_OBJECTFLIP) ? true : false; // K_RespawnOffset wants a boolean!
|
||||
player->respawn.pointz += K_RespawnOffset(player, player->respawn.flip);
|
||||
|
||||
if (waypoint->onaline)
|
||||
{
|
||||
K_FudgeRespawn(player, waypoint);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -153,6 +153,38 @@ boolean K_GetWaypointIsSpawnpoint(waypoint_t *waypoint)
|
|||
return waypointisspawnpoint;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static boolean K_GetWaypointIsOnLine(waypoint_t *const waypoint)
|
||||
|
||||
Checks if a waypoint is exactly on a line. Moving to an exact point
|
||||
on a line won't count as crossing it. Moving off of that point does.
|
||||
Respawning to a waypoint which is exactly on a line is the easiest
|
||||
way to for this to occur.
|
||||
|
||||
Return:-
|
||||
Whether the waypoint is exactly on a line.
|
||||
--------------------------------------------------*/
|
||||
static boolean K_GetWaypointIsOnLine(waypoint_t *const waypoint)
|
||||
{
|
||||
const fixed_t x = waypoint->mobj->x;
|
||||
const fixed_t y = waypoint->mobj->y;
|
||||
|
||||
line_t *line = P_FindNearestLine(x, y,
|
||||
waypoint->mobj->subsector->sector, -1);
|
||||
|
||||
vertex_t point;
|
||||
|
||||
if (line != NULL)
|
||||
{
|
||||
P_ClosestPointOnLine(x, y, line, &point);
|
||||
|
||||
if (x == point.x && y == point.y)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
INT32 K_GetWaypointNextID(waypoint_t *waypoint)
|
||||
|
||||
|
|
@ -253,6 +285,40 @@ waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj)
|
|||
return closestwaypoint;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_CompareOverlappingWaypoint
|
||||
( waypoint_t *const checkwaypoint,
|
||||
waypoint_t **const bestwaypoint,
|
||||
fixed_t *const bestfindist)
|
||||
|
||||
Solves touching overlapping waypoint radiuses by sorting by distance to
|
||||
finish line.
|
||||
--------------------------------------------------*/
|
||||
static void K_CompareOverlappingWaypoint
|
||||
( waypoint_t *const checkwaypoint,
|
||||
waypoint_t **const bestwaypoint,
|
||||
fixed_t *const bestfindist)
|
||||
{
|
||||
const boolean useshortcuts = false;
|
||||
const boolean huntbackwards = false;
|
||||
boolean pathfindsuccess = false;
|
||||
path_t pathtofinish = {};
|
||||
|
||||
pathfindsuccess =
|
||||
K_PathfindToWaypoint(checkwaypoint, finishline, &pathtofinish, useshortcuts, huntbackwards);
|
||||
|
||||
if (pathfindsuccess == true)
|
||||
{
|
||||
if ((INT32)(pathtofinish.totaldist) < *bestfindist)
|
||||
{
|
||||
*bestwaypoint = checkwaypoint;
|
||||
*bestfindist = pathtofinish.totaldist;
|
||||
}
|
||||
|
||||
Z_Free(pathtofinish.array);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj)
|
||||
|
||||
|
|
@ -292,30 +358,18 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj)
|
|||
|
||||
rad = (checkwaypoint->mobj->radius / FRACUNIT);
|
||||
|
||||
if (closestdist < rad && checkdist < rad && finishline != NULL)
|
||||
// remember: huge radius
|
||||
if (closestdist <= rad && checkdist <= rad && finishline != NULL)
|
||||
{
|
||||
const boolean useshortcuts = false;
|
||||
const boolean huntbackwards = false;
|
||||
boolean pathfindsuccess = false;
|
||||
path_t pathtofinish = {};
|
||||
|
||||
// If the mobj is touching multiple waypoints at once,
|
||||
// then solve ties by taking the one closest to the finish line.
|
||||
// Prevents position from flickering wildly when taking turns.
|
||||
|
||||
pathfindsuccess =
|
||||
K_PathfindToWaypoint(checkwaypoint, finishline, &pathtofinish, useshortcuts, huntbackwards);
|
||||
// For the first couple overlapping, check the previous best too.
|
||||
if (bestfindist == INT32_MAX)
|
||||
K_CompareOverlappingWaypoint(bestwaypoint, &bestwaypoint, &bestfindist);
|
||||
|
||||
if (pathfindsuccess == true)
|
||||
{
|
||||
if ((INT32)(pathtofinish.totaldist) < bestfindist)
|
||||
{
|
||||
bestwaypoint = checkwaypoint;
|
||||
bestfindist = pathtofinish.totaldist;
|
||||
}
|
||||
|
||||
Z_Free(pathtofinish.array);
|
||||
}
|
||||
K_CompareOverlappingWaypoint(checkwaypoint, &bestwaypoint, &bestfindist);
|
||||
}
|
||||
else if (checkdist < closestdist && bestfindist == INT32_MAX)
|
||||
{
|
||||
|
|
@ -1678,6 +1732,12 @@ static waypoint_t *K_SetupWaypoint(mobj_t *const mobj)
|
|||
finishline = thiswaypoint;
|
||||
}
|
||||
|
||||
/* only relevant for respawning */
|
||||
if (K_GetWaypointIsSpawnpoint(thiswaypoint))
|
||||
{
|
||||
thiswaypoint->onaline = K_GetWaypointIsOnLine(thiswaypoint);
|
||||
}
|
||||
|
||||
if (thiswaypoint->numnextwaypoints > 0)
|
||||
{
|
||||
waypoint_t *nextwaypoint = NULL;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
typedef struct waypoint_s
|
||||
{
|
||||
mobj_t *mobj;
|
||||
boolean onaline;
|
||||
struct waypoint_s **nextwaypoints;
|
||||
struct waypoint_s **prevwaypoints;
|
||||
UINT32 *nextwaypointdistances;
|
||||
|
|
|
|||
|
|
@ -259,6 +259,76 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1)
|
|||
return frac;
|
||||
}
|
||||
|
||||
static fixed_t dist2line(const line_t *ld, const fixed_t x, const fixed_t y)
|
||||
{
|
||||
return FixedHypot
|
||||
(
|
||||
ld->v1->x + (ld->dx / 2) - x,
|
||||
ld->v1->y + (ld->dy / 2) - y
|
||||
);
|
||||
}
|
||||
|
||||
static void checknearline
|
||||
( line_t * line,
|
||||
fixed_t * nearest,
|
||||
line_t ** near_line,
|
||||
const fixed_t x,
|
||||
const fixed_t y)
|
||||
{
|
||||
const fixed_t d = dist2line(line, x, y);
|
||||
|
||||
if (d < *nearest)
|
||||
{
|
||||
*nearest = d;
|
||||
*near_line = line;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_FindNearestLine
|
||||
// Returns the nearest line to a point which
|
||||
// is in a sector and/or a specific type.
|
||||
//
|
||||
line_t * P_FindNearestLine
|
||||
( const fixed_t x,
|
||||
const fixed_t y,
|
||||
const sector_t * sector,
|
||||
const INT32 special)
|
||||
{
|
||||
fixed_t nearest = INT32_MAX;
|
||||
line_t *near_line = NULL;
|
||||
size_t i;
|
||||
INT32 line = -1;
|
||||
|
||||
if (special == -1)
|
||||
{
|
||||
if (sector == NULL)
|
||||
sector = R_PointInSubsector(x, y)->sector;
|
||||
|
||||
for (i = 0; i < sector->linecount; ++i)
|
||||
{
|
||||
checknearline(sector->lines[i], &nearest, &near_line, x, y);
|
||||
}
|
||||
}
|
||||
else if (sector != NULL)
|
||||
{
|
||||
for (i = 0; i < sector->linecount; ++i)
|
||||
{
|
||||
if (sector->lines[i]->special == special)
|
||||
checknearline(sector->lines[i], &nearest, &near_line, x, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((line = P_FindSpecialLineFromTag(special, -1, line)) != -1)
|
||||
{
|
||||
checknearline(&lines[line], &nearest, &near_line, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
return near_line;
|
||||
}
|
||||
|
||||
//
|
||||
// P_LineOpening
|
||||
// Sets opentop and openbottom to the window through a two sided line.
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ void P_MakeDivline(line_t *li, divline_t *dl);
|
|||
void P_CameraLineOpening(line_t *plinedef);
|
||||
fixed_t P_InterceptVector(divline_t *v2, divline_t *v1);
|
||||
INT32 P_BoxOnLineSide(fixed_t *tmbox, line_t *ld);
|
||||
line_t * P_FindNearestLine(const fixed_t x, const fixed_t y, const sector_t *, const INT32 special);
|
||||
void P_UnsetPrecipThingPosition(precipmobj_t *thing);
|
||||
void P_SetPrecipitationThingPosition(precipmobj_t *thing);
|
||||
void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y);
|
||||
|
|
|
|||
17
src/p_mobj.c
17
src/p_mobj.c
|
|
@ -11334,6 +11334,18 @@ static boolean P_SetupBooster(mapthing_t* mthing, mobj_t* mobj, boolean strong)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void P_SnapToFinishLine(mobj_t *mobj)
|
||||
{
|
||||
line_t *finishline = P_FindNearestLine(mobj->x, mobj->y,
|
||||
mobj->subsector->sector, 2001); // case 2001: Finish Line
|
||||
if (finishline != NULL)
|
||||
{
|
||||
P_UnsetThingPosition(mobj);
|
||||
P_ClosestPointOnLine(mobj->x, mobj->y, finishline, (vertex_t *)&mobj->x);
|
||||
P_SetThingPosition(mobj);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean *doangle)
|
||||
{
|
||||
boolean override = LUAh_MapThingSpawn(mobj, mthing);
|
||||
|
|
@ -11717,7 +11729,10 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
}
|
||||
if (mthing->args[2] == 1)
|
||||
{
|
||||
mobj->extravalue2 = 1; // args[1] of 1 means the waypoint is at the finish line
|
||||
mobj->extravalue2 = 1; // args[2] of 1 means the waypoint is at the finish line
|
||||
mobj->reactiontime = 0; // Also don't respawn at finish lines
|
||||
|
||||
P_SnapToFinishLine(mobj);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue