mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-05-03 15:32:45 +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())
|
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
|
// facing towards the finishline
|
||||||
if (angledelta <= ANGLE_90)
|
if (abs(AngleDifference(angletonextwaypoint, angletowaypoint)) <= ANGLE_90)
|
||||||
{
|
{
|
||||||
finishlinehack = true;
|
finishlinehack = true;
|
||||||
}
|
}
|
||||||
|
|
@ -6698,6 +6702,7 @@ 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)
|
static boolean K_PlayerCloserToNextWaypoints(waypoint_t *const waypoint, player_t *const player)
|
||||||
{
|
{
|
||||||
boolean nextiscloser = true;
|
boolean nextiscloser = true;
|
||||||
|
|
@ -6758,6 +6763,7 @@ static boolean K_PlayerCloserToNextWaypoints(waypoint_t *const waypoint, player_
|
||||||
|
|
||||||
return nextiscloser;
|
return nextiscloser;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
void K_UpdateDistanceFromFinishLine(player_t *const player)
|
void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||||
|
|
@ -6837,6 +6843,7 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||||
|
|
||||||
player->distancetofinish += numfulllapsleft * K_GetCircuitLength();
|
player->distancetofinish += numfulllapsleft * K_GetCircuitLength();
|
||||||
|
|
||||||
|
#if 0
|
||||||
// An additional HACK, to fix looking backwards towards the finish line
|
// 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
|
// 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
|
// 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();
|
player->distancetofinish += K_GetCircuitLength();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,21 @@ fixed_t K_RespawnOffset(player_t *player, boolean flip)
|
||||||
return z;
|
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)
|
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.pointz = waypoint->mobj->z;
|
||||||
player->respawn.flip = (waypoint->mobj->flags2 & MF2_OBJECTFLIP) ? true : false; // K_RespawnOffset wants a boolean!
|
player->respawn.flip = (waypoint->mobj->flags2 & MF2_OBJECTFLIP) ? true : false; // K_RespawnOffset wants a boolean!
|
||||||
player->respawn.pointz += K_RespawnOffset(player, player->respawn.flip);
|
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;
|
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)
|
INT32 K_GetWaypointNextID(waypoint_t *waypoint)
|
||||||
|
|
||||||
|
|
@ -253,6 +285,40 @@ waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj)
|
||||||
return closestwaypoint;
|
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)
|
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);
|
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,
|
// If the mobj is touching multiple waypoints at once,
|
||||||
// then solve ties by taking the one closest to the finish line.
|
// then solve ties by taking the one closest to the finish line.
|
||||||
// Prevents position from flickering wildly when taking turns.
|
// Prevents position from flickering wildly when taking turns.
|
||||||
|
|
||||||
pathfindsuccess =
|
// For the first couple overlapping, check the previous best too.
|
||||||
K_PathfindToWaypoint(checkwaypoint, finishline, &pathtofinish, useshortcuts, huntbackwards);
|
if (bestfindist == INT32_MAX)
|
||||||
|
K_CompareOverlappingWaypoint(bestwaypoint, &bestwaypoint, &bestfindist);
|
||||||
|
|
||||||
if (pathfindsuccess == true)
|
K_CompareOverlappingWaypoint(checkwaypoint, &bestwaypoint, &bestfindist);
|
||||||
{
|
|
||||||
if ((INT32)(pathtofinish.totaldist) < bestfindist)
|
|
||||||
{
|
|
||||||
bestwaypoint = checkwaypoint;
|
|
||||||
bestfindist = pathtofinish.totaldist;
|
|
||||||
}
|
|
||||||
|
|
||||||
Z_Free(pathtofinish.array);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (checkdist < closestdist && bestfindist == INT32_MAX)
|
else if (checkdist < closestdist && bestfindist == INT32_MAX)
|
||||||
{
|
{
|
||||||
|
|
@ -1678,6 +1732,12 @@ static waypoint_t *K_SetupWaypoint(mobj_t *const mobj)
|
||||||
finishline = thiswaypoint;
|
finishline = thiswaypoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* only relevant for respawning */
|
||||||
|
if (K_GetWaypointIsSpawnpoint(thiswaypoint))
|
||||||
|
{
|
||||||
|
thiswaypoint->onaline = K_GetWaypointIsOnLine(thiswaypoint);
|
||||||
|
}
|
||||||
|
|
||||||
if (thiswaypoint->numnextwaypoints > 0)
|
if (thiswaypoint->numnextwaypoints > 0)
|
||||||
{
|
{
|
||||||
waypoint_t *nextwaypoint = NULL;
|
waypoint_t *nextwaypoint = NULL;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
typedef struct waypoint_s
|
typedef struct waypoint_s
|
||||||
{
|
{
|
||||||
mobj_t *mobj;
|
mobj_t *mobj;
|
||||||
|
boolean onaline;
|
||||||
struct waypoint_s **nextwaypoints;
|
struct waypoint_s **nextwaypoints;
|
||||||
struct waypoint_s **prevwaypoints;
|
struct waypoint_s **prevwaypoints;
|
||||||
UINT32 *nextwaypointdistances;
|
UINT32 *nextwaypointdistances;
|
||||||
|
|
|
||||||
|
|
@ -259,6 +259,76 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1)
|
||||||
return frac;
|
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
|
// P_LineOpening
|
||||||
// Sets opentop and openbottom to the window through a two sided line.
|
// 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);
|
void P_CameraLineOpening(line_t *plinedef);
|
||||||
fixed_t P_InterceptVector(divline_t *v2, divline_t *v1);
|
fixed_t P_InterceptVector(divline_t *v2, divline_t *v1);
|
||||||
INT32 P_BoxOnLineSide(fixed_t *tmbox, line_t *ld);
|
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_UnsetPrecipThingPosition(precipmobj_t *thing);
|
||||||
void P_SetPrecipitationThingPosition(precipmobj_t *thing);
|
void P_SetPrecipitationThingPosition(precipmobj_t *thing);
|
||||||
void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y);
|
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;
|
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)
|
static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean *doangle)
|
||||||
{
|
{
|
||||||
boolean override = LUAh_MapThingSpawn(mobj, mthing);
|
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)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue