From 29c3c3c55c319bfa49c287ddadef53351feee472 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Wed, 29 Oct 2025 23:15:45 +0100 Subject: [PATCH] Waypoint jank? What waypoint jank? * Finish line sight check? Gone * Corpses updating their waypoint and respawn? Gone * Respawning on the finish line causing lap cheats? Gone * bigwaypointgap now kills you in just HALF A SECOND --- src/d_netcmd.c | 6 +- src/d_player.h | 6 +- src/doomdef.h | 4 ++ src/k_hud.c | 9 +-- src/k_kart.c | 170 +++++++++++++------------------------------- src/k_kart.h | 4 +- src/k_waypoint.cpp | 64 ++++++++++++++++- src/k_waypoint.h | 10 ++- src/lua_playerlib.c | 12 ++-- src/p_inter.c | 6 +- src/p_local.h | 2 +- src/p_maputl.c | 3 +- src/p_mobj.c | 42 +++++------ src/p_sight.c | 7 -- src/p_spec.c | 41 ++--------- src/p_telept.c | 2 +- 16 files changed, 172 insertions(+), 216 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b7da0c81c..43dcf6618 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -6077,9 +6077,9 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum) fixed_t y = READFIXED(*cp); fixed_t z = READFIXED(*cp); - player->starpostx = x>>FRACBITS; - player->starposty = y>>FRACBITS; - player->starpostz = z>>FRACBITS; + player->starpostx = x; + player->starposty = y; + player->starpostz = z; CV_CheaterWarning(targetPlayer, va("temporary checkpoint created at %d, %d, %d", x / FRACUNIT, y / FRACUNIT, z / FRACUNIT)); diff --git a/src/d_player.h b/src/d_player.h index b3b3ae748..a69aad896 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -794,9 +794,9 @@ struct player_t UINT8 latestlap; // Starpost information - INT16 starpostx; - INT16 starposty; - INT16 starpostz; + fixed_t starpostx; + fixed_t starposty; + fixed_t starpostz; angle_t starpostangle; // Angle that the starpost is facing - you respawn facing this way INT32 starpostnum; // The number of the last starpost you hit tic_t starposttime; // NOIRE: The time of the last cheatcheck you hit diff --git a/src/doomdef.h b/src/doomdef.h index c32408c1d..b707eb214 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -438,6 +438,10 @@ UINT32 quickncasehash (const char *p, size_t n) #define CLAMP(x, min_val, max_val) ((x) < (min_val) ? (min_val) : ((x) > (max_val) ? (max_val) : (x))) #endif +#ifndef u32_delta +#define u32_delta(x, y) ((x) > (y) ? (x) - (y) : (y) - (x)) +#endif + // Max gamepad/joysticks that can be detected/used. #define MAX_JOYSTICKS 4 diff --git a/src/k_hud.c b/src/k_hud.c index 0baf9a2f8..30985c4ab 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -5751,12 +5751,13 @@ static void K_DrawWaypointDebugger(void) if (stplyr->bigwaypointgap) { - V_DrawString(8, 146, 0, va("Auto Respawn Timer: %d", stplyr->bigwaypointgap)); + V_DrawString(8, 130, 0, va("Auto Respawn Timer: %d", stplyr->bigwaypointgap)); } - V_DrawString(8, 156, 0, va("Current Waypoint ID: %d", K_GetWaypointID(stplyr->currentwaypoint))); - V_DrawString(8, 166, 0, va("Next Waypoint ID: %d", K_GetWaypointID(stplyr->nextwaypoint))); - V_DrawString(8, 176, 0, va("Finishline Distance: %d", stplyr->distancetofinish)); + V_DrawString(8, 140, 0, va("Current Waypoint ID: %d", K_GetWaypointID(stplyr->currentwaypoint))); + V_DrawString(8, 150, 0, va("Next Waypoint ID: %d", K_GetWaypointID(stplyr->nextwaypoint))); + V_DrawString(8, 160, 0, va("Finishline Distance: %d", stplyr->distancetofinish)); + V_DrawString(8, 170, 0, va("Waypoint DtF: %d", stplyr->currentwaypoint ? stplyr->currentwaypoint->distancetofinish : -1)); } static void K_DrawClusterDebugger(void) diff --git a/src/k_kart.c b/src/k_kart.c index 4828e0fb8..226949569 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7775,6 +7775,38 @@ static int clostVal(fixed_t arr[], int N, fixed_t K) return res; } +static boolean safesector(sector_t *sector, boolean flip) +{ + // does the sector special even affect us? + if (sector->flags & MSF_FLIPSPECIAL_FLOOR && !(sector->flags & MSF_TRIGGERSPECIAL_HEADBUMP || !flip)) + return true; + if (sector->flags & MSF_FLIPSPECIAL_CEILING && !(sector->flags & MSF_TRIGGERSPECIAL_HEADBUMP || flip)) + return true; + + switch (sector->damagetype) + { + case SD_GENERIC: + case SD_DEATHPIT: + case SD_INSTAKILL: + case SD_LAVA: + { + //CONS_Printf("Dangerous sector!!!!\n"); + return false; + } + default: + break; + } + + if (sector->offroad) + { + //CONS_Printf("Offroad Sector!!!!\n"); + return false; + } + + //CONS_Printf("Sector safe, allow respawn!!!!\n"); + return true; +} + // Decides if respawning at this position is safe, used for nu waypoints. boolean K_SafeRespawnPosition(mobj_t * mo) { @@ -7955,29 +7987,7 @@ boolean K_SafeRespawnPosition(mobj_t * mo) // Check if rover is bad based on both its terrain, and sector specials. if (result.bestrover) { - switch (result.bestrover->master->frontsector->damagetype) - { - case SD_GENERIC: - case SD_DEATHPIT: - case SD_INSTAKILL: - case SD_LAVA: - { - //CONS_Printf("Dangerous rover!!!!\n"); - return false; - } - default: - break; - } - - if (result.bestrover->master->frontsector->offroad) - { - //CONS_Printf("Offroad rover!!!!\n"); - return false; - } - - //CONS_Printf("Rover safe, allow respawn!!!!\n"); - return true; - + return safesector(result.bestrover->master->frontsector, flip); } else { @@ -7992,29 +8002,7 @@ boolean K_SafeRespawnPosition(mobj_t * mo) // Check if po is bad based on both its terrain, and sector specials. if (result.bestpo) { - switch (result.bestpo->lines[0]->backsector->damagetype) - { - case SD_GENERIC: - case SD_DEATHPIT: - case SD_INSTAKILL: - case SD_LAVA: - { - //CONS_Printf("Dangerous polyobj!!!!\n"); - return false; - } - default: - break; - } - - if (result.bestpo->lines[0]->backsector->offroad) - { - //CONS_Printf("Offroad polyobj!!!!\n"); - return false; - } - - //CONS_Printf("Polyobj safe, allow respawn!!!!\n"); - return true; - + return safesector(result.bestpo->lines[0]->backsector, flip); } else { @@ -8025,30 +8013,7 @@ boolean K_SafeRespawnPosition(mobj_t * mo) // if everything else is not closest check sector else if (result.result == RESPAWNRS_SECTOR) { - // Check if sector is bad based on both its terrain, and sector specials. - - switch (result.cursec->damagetype) - { - case SD_GENERIC: - case SD_DEATHPIT: - case SD_INSTAKILL: - case SD_LAVA: - { - //CONS_Printf("Dangerous sector!!!!\n"); - return false; - } - default: - break; - } - - if (result.cursec->offroad) - { - //CONS_Printf("Offroad Sector!!!!\n"); - return false; - } - - //CONS_Printf("Sector safe, allow respawn!!!!\n"); - return true; + return safesector(result.cursec, flip); } CONS_Printf("Nep Fucked up, yell at him! BYPASSED ALL\n"); @@ -8519,11 +8484,6 @@ static void K_UpdateDistanceFromFinishLine(player_t *player) } } -static UINT32 u32_delta(UINT32 x, UINT32 y) -{ - return x > y ? x - y : y - x; -} - /*-------------------------------------------------- * static void K_FudgeRespawn(player_t *player, const waypoint_t *const waypoint) * @@ -8703,25 +8663,25 @@ void K_SetRespawnAtNextWaypoint(player_t * player) // Please don't spawn after the line. player->pflags |= PF_TRUSTWAYPOINTS; player->starposttime = player->realtime; - player->starpostz = currentwaypoint->mobj->z >> FRACBITS; + player->starpostz = currentwaypoint->mobj->z; player->starpostflip = (currentwaypoint->mobj->flags2 & MF2_OBJECTFLIP); player->starpostangle = player->mo->angle; // Then do x and y - player->starpostx = currentwaypoint->mobj->x >> FRACBITS; - player->starposty = currentwaypoint->mobj->y >> FRACBITS; + player->starpostx = currentwaypoint->mobj->x; + player->starposty = currentwaypoint->mobj->y; return; } player->pflags |= PF_TRUSTWAYPOINTS; player->starposttime = player->realtime; - player->starpostz = safewaypoint->mobj->z >> FRACBITS; + player->starpostz = safewaypoint->mobj->z; player->starpostflip = (safewaypoint->mobj->flags2 & MF2_OBJECTFLIP); player->starpostangle = respawnangle; // Then do x and y - player->starpostx = safewaypoint->mobj->x >> FRACBITS; - player->starposty = safewaypoint->mobj->y >> FRACBITS; + player->starpostx = safewaypoint->mobj->x; + player->starposty = safewaypoint->mobj->y; } else { @@ -8730,36 +8690,6 @@ void K_SetRespawnAtNextWaypoint(player_t * player) } } -static boolean K_MobjIsOnLine(mobj_t *const mobj) -{ - const fixed_t x = mobj->x; - const fixed_t y = mobj->y; - - line_t *line = P_FindNearestLine(x, y, - 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; -} - -static void K_MobjFudgeRespawn(player_t *player, const mobj_t *const mobj) -{ - const angle_t from = R_PointToAngle2(mobj->x, mobj->y, - player->mo->x, player->mo->y) >> ANGLETOFINESHIFT; - - player->starpostx += FixedMul(25, FINECOSINE(from)); - player->starposty += FixedMul(25, FINESINE(from)); -} - /*-------------------------------------------------- static void K_UpdatePlayerWaypoints(player_t *const player) @@ -8773,7 +8703,7 @@ static void K_MobjFudgeRespawn(player_t *player, const mobj_t *const mobj) --------------------------------------------------*/ static void K_UpdatePlayerWaypoints(player_t *const player) { - if (player->pflags & PF_FREEZEWAYPOINTS) + if (player->pflags & PF_FREEZEWAYPOINTS || player->playerstate != PST_LIVE) { player->pflags &= ~PF_FREEZEWAYPOINTS; return; @@ -8784,6 +8714,8 @@ static void K_UpdatePlayerWaypoints(player_t *const player) waypoint_t *const old_currentwaypoint = player->currentwaypoint; waypoint_t *const old_nextwaypoint = player->nextwaypoint; + const UINT32 prevwpdtf = player->currentwaypoint ? player->currentwaypoint->distancetofinish : UINT32_MAX; + boolean updaterespawn = K_SetPlayerNextWaypoint(player); // Update prev value (used for grief prevention code) @@ -8791,7 +8723,8 @@ static void K_UpdatePlayerWaypoints(player_t *const player) K_UpdateDistanceFromFinishLine(player); UINT32 delta = u32_delta(player->distancetofinish, player->distancetofinishprev); - if (delta > distance_threshold && + UINT32 wpdelta = prevwpdtf != UINT32_MAX && player->currentwaypoint != NULL ? u32_delta(prevwpdtf, player->currentwaypoint->distancetofinish) : 0; + if ((/*delta > distance_threshold || */wpdelta > K_GetCircuitLength()/2) && !player->respawn && // Respawning should be a full reset. old_currentwaypoint != NULL && // So should touching the first waypoint ever. player->laps != 0 && // POSITION rooms may have unorthodox waypoints to guide bots. @@ -8852,18 +8785,13 @@ static void K_UpdatePlayerWaypoints(player_t *const player) { // Set time, z, flip and angle first. player->starposttime = player->realtime; - player->starpostz = player->mo->z >> FRACBITS; + player->starpostz = player->mo->z; player->starpostflip = (player->mo->eflags & MFE_VERTICALFLIP) ? true : false; player->starpostangle = player->mo->angle; // Then do x and y - player->starpostx = player->mo->x >> FRACBITS; - player->starposty = player->mo->y >> FRACBITS; - - if (K_MobjIsOnLine(player->mo)) - { - K_MobjFudgeRespawn(player, player->mo); - } + player->starpostx = player->mo->x; + player->starposty = player->mo->y; } else { diff --git a/src/k_kart.h b/src/k_kart.h index 68f39da58..22ad14eba 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -34,8 +34,8 @@ Make sure this matches the actual number of states #define BASEINVINTIME (10 * TICRATE) -#define AUTORESPAWN_TIME (10 * TICRATE) -#define AUTORESPAWN_THRESHOLD (7 * TICRATE) +#define AUTORESPAWN_TIME (TICRATE/2) +#define AUTORESPAWN_THRESHOLD (TICRATE/4) #define FLAMESTOREMAX TICRATE*2 diff --git a/src/k_waypoint.cpp b/src/k_waypoint.cpp index 751aa427d..1af6dd99a 100644 --- a/src/k_waypoint.cpp +++ b/src/k_waypoint.cpp @@ -347,6 +347,9 @@ waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj) { checkwaypoint = &waypointheap[i]; + if (!K_GetWaypointIsEnabled(checkwaypoint)) + continue; + checkdist = P_AproxDistance( (mobj->x / FRACUNIT) - (checkwaypoint->mobj->x / FRACUNIT), (mobj->y / FRACUNIT) - (checkwaypoint->mobj->y / FRACUNIT)); @@ -363,6 +366,45 @@ waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj) return closestwaypoint; } +// finds the closest waypoint on the same side of the finish line as the mobj +waypoint_t *K_GetSpawnWaypointForMobj(const mobj_t *mobj) +{ + waypoint_t *closestwaypoint = NULL; + fixed_t closestdist = INT32_MAX; + line_t *finish = P_FindNearestLine(finishline->mobj->x, finishline->mobj->y, nullptr, 2001); // erm... NULL? thanks hanagumi hall + INT32 myside = P_PointOnLineSide(mobj->x, mobj->y, finish); + I_Assert(mobj != NULL); + + for (size_t i = 0; i < numwaypoints; i++) + { + waypoint_t *checkwaypoint = &waypointheap[i]; + + if (!K_GetWaypointIsEnabled(checkwaypoint) + || checkwaypoint == finishline + || myside != P_PointOnLineSide(checkwaypoint->mobj->x, checkwaypoint->mobj->y, finish)) + continue; + + fixed_t checkdist = P_AproxDistance( + (mobj->x / FRACUNIT) - (checkwaypoint->mobj->x / FRACUNIT), + (mobj->y / FRACUNIT) - (checkwaypoint->mobj->y / FRACUNIT)); + checkdist = P_AproxDistance(checkdist, (mobj->z / FRACUNIT) - (checkwaypoint->mobj->z / FRACUNIT)); + + if (checkdist < closestdist) + { + closestwaypoint = checkwaypoint; + closestdist = checkdist; + } + } + + return closestwaypoint; +} + +UINT32 K_GetWaypointSnapThreshold(void) +{ + const UINT8 lapspersection = mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE ? 1 : mapheaderinfo[gamemap-1]->lapspersection; + return circuitlength - (circuitlength / (3 + lapspersection)); +} + /*-------------------------------------------------- static void K_CompareOverlappingWaypoint ( waypoint_t *const checkwaypoint, @@ -422,6 +464,7 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj, waypoint_t *const hint) fixed_t closestdist = INT32_MAX; fixed_t checkdist = INT32_MAX; fixed_t bestfindist = INT32_MAX; + UINT32 threshold = K_GetWaypointSnapThreshold(); auto sort_waypoint = [&](waypoint_t *const checkwaypoint) { @@ -431,7 +474,8 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj, waypoint_t *const hint) } // do not path over the finish line. just don't. - if (checkwaypoint == finishline) + if (checkwaypoint == finishline || + (hint != NULL && u32_delta(hint->distancetofinish, checkwaypoint->distancetofinish) > threshold)) return; checkdist = P_AproxDistance( @@ -2053,6 +2097,22 @@ static UINT32 K_SetupCircuitLength(void) } } + // TODO: just traverse the circuit in reverse to set dtf. much less costly. + // i've had enough of this spaghetti + if (circuitlength == 0) + return circuitlength; + + for (size_t i = 0; i < numwaypoints; i++) + { + waypoint_t *wp = &waypointheap[i]; + path_t bestcircuitpath = {0}; + K_PathfindToWaypoint(wp, finishline, &bestcircuitpath, false, false); + if (K_GetWaypointIsEnabled(wp) && wp != finishline && bestcircuitpath.totaldist == 0) + CONS_Alert(CONS_WARNING, "Waypoint %d is a dead end\n", K_GetWaypointID(wp)); + wp->distancetofinish = bestcircuitpath.totaldist; + Z_Free(bestcircuitpath.array); + } + return circuitlength; } @@ -2228,7 +2288,7 @@ static waypoint_t *K_SetupWaypoint(mobj_t *const mobj) // Set drift settings. if (mobj->watertop) { - thiswaypoint->driftsettings = mobj->watertop; + thiswaypoint->driftsettings = (driftSetting_e)mobj->watertop; } if (thiswaypoint->numnextwaypoints > 0) diff --git a/src/k_waypoint.h b/src/k_waypoint.h index c9b618089..bf7351cb2 100644 --- a/src/k_waypoint.h +++ b/src/k_waypoint.h @@ -32,19 +32,20 @@ typedef enum { DRIFT_PWRSLIDE_R, DRIFT_RIGHT, DRIFT_END -} driftSetting_e; +} ATTRPACK driftSetting_e; struct waypoint_t { mobj_t *mobj; - boolean onaline; waypoint_t **nextwaypoints; waypoint_t **prevwaypoints; UINT32 *nextwaypointdistances; UINT32 *prevwaypointdistances; size_t numnextwaypoints; size_t numprevwaypoints; - UINT32 driftsettings; + UINT32 distancetofinish; + driftSetting_e driftsettings; + boolean onaline; }; @@ -240,6 +241,9 @@ INT32 K_GetTrackComplexity(void); --------------------------------------------------*/ waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj); +waypoint_t *K_GetSpawnWaypointForMobj(const mobj_t *mobj); + +UINT32 K_GetWaypointSnapThreshold(void); /*-------------------------------------------------- waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj, waypoint_t *const hint); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index faed54549..bda1fee17 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -1137,13 +1137,13 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->checkskip); break; case player_starpostx: - lua_pushfixed(L, plr->starpostx); + lua_pushfixed(L, plr->starpostx >> (lua_compatmode ? 16 : 0)); break; case player_starposty: - lua_pushfixed(L, plr->starposty); + lua_pushfixed(L, plr->starposty >> (lua_compatmode ? 16 : 0)); break; case player_starpostz: - lua_pushfixed(L, plr->starpostz); + lua_pushfixed(L, plr->starpostz >> (lua_compatmode ? 16 : 0)); break; case player_starpostangle: lua_pushangle(L, plr->starpostangle); @@ -1825,13 +1825,13 @@ static int player_set(lua_State *L) plr->checkskip = (INT32)luaL_checkinteger(L, 3); break; case player_starpostx: - plr->starpostx = luaL_checkfixed(L, 3); + plr->starpostx = luaL_checkfixed(L, 3) << (lua_compatmode ? 16 : 0); break; case player_starposty: - plr->starposty = luaL_checkfixed(L, 3); + plr->starposty = luaL_checkfixed(L, 3) << (lua_compatmode ? 16 : 0); break; case player_starpostz: - plr->starpostz = luaL_checkfixed(L, 3); + plr->starpostz = luaL_checkfixed(L, 3) << (lua_compatmode ? 16 : 0); break; case player_starpostangle: plr->starpostangle = luaL_checkangle(L, 3); diff --git a/src/p_inter.c b/src/p_inter.c index a6d57c670..0cb66ce6a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -980,9 +980,9 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) // Save the player's time and position. player->starposttime = player->realtime; //this makes race mode's timers work correctly whilst not affecting sp -x //player->starposttime = leveltime; - player->starpostx = toucher->x>>FRACBITS; - player->starposty = toucher->y>>FRACBITS; - player->starpostz = post->z>>FRACBITS; + player->starpostx = toucher->x; + player->starposty = toucher->y; + player->starpostz = post->z; player->starpostangle = post->angle; player->starpostflip = post->spawnpoint->options & MTF_OBJECTFLIP; // store flipping } diff --git a/src/p_local.h b/src/p_local.h index 2e69088ee..25299261f 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -630,7 +630,7 @@ extern INT32 ceilmovesound; #define CARRYFACTOR (FRACUNIT-ORIG_FRICTION) void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, - INT16 starpostx, INT16 starposty, INT16 starpostz, + fixed_t starpostx, fixed_t starposty, fixed_t starpostz, INT32 starpostnum, tic_t starposttime, angle_t starpostangle, fixed_t starpostscale, angle_t drawangle, INT32 flags2); boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, boolean flash, boolean dontstopmove); diff --git a/src/p_maputl.c b/src/p_maputl.c index 0c03f61f1..80cdba87a 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -263,7 +263,8 @@ line_t * P_FindNearestLine } else { - while ((line = P_FindSpecialLineFromTag(special, -1, line)) != -1) + // if all linedefs are exhausted, this returns numlines... + while (line = P_FindSpecialLineFromTag(special, -1, line), line != -1 && line != (INT32)numlines) { checknearline(&lines[line], &nearest, &near_line, x, y); } diff --git a/src/p_mobj.c b/src/p_mobj.c index bd86b2d4c..7dc1e28cd 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12565,6 +12565,10 @@ void P_AfterPlayerSpawn(INT32 playernum) if (CheckForReverseGravity) P_CheckGravity(mobj, false); + + // set the player's starting waypoint + if (!K_UsingLegacyCheckpoints()) + p->currentwaypoint = K_GetSpawnWaypointForMobj(p->mo); } // spawn it at a playerspawn mapthing @@ -12575,7 +12579,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) fixed_t z; sector_t *sector; - fixed_t floor, ceiling; + fixed_t floor, ceiling, ceilingspawn; player_t *p = &players[playernum]; mobj_t *mobj = p->mo; @@ -12586,10 +12590,6 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; angle = FixedAngle(mthing->angle*FRACUNIT); - - p->starpostx = mthing->x >> FRACBITS; - p->starposty = mthing->y >> FRACBITS; - p->starpostangle = FixedAngle(mthing->angle*FRACUNIT); } //spawn at the origin as a desperation move if there is no mapthing @@ -12602,29 +12602,21 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) ceiling = sector->c_slope ? P_GetSlopeZAt(sector->c_slope, x, y) : sector->ceilingheight; + ceilingspawn = ceiling - mobjinfo[MT_PLAYER].height; if (mthing) { - fixed_t offset = udmf ? mthing->z << FRACBITS : 0; + fixed_t offset = udmf ? mthing->z << FRACBITS : (mthing->options >> ZSHIFT) << FRACBITS; + + if (p->respawn) + offset += 128*mapobjectscale; // Setting the spawnpoint's args[0] will make the player start on the ceiling // Objectflip inverts if (!!(mthing->args[0]) ^ !!(mthing->options & MTF_OBJECTFLIP)) - { - z = ceiling - mobjinfo[MT_PLAYER].height - offset; - if (mthing->options >> ZSHIFT) - z -= ((mthing->options >> ZSHIFT) << FRACBITS); - if (p->respawn) - z -= 128*mapobjectscale; - } + z = ceilingspawn - offset; else - { z = floor + offset; - if (mthing->options >> ZSHIFT) - z += ((mthing->options >> ZSHIFT) << FRACBITS); - if (p->respawn) - z += 128*mapobjectscale; - } if (mthing->options & MTF_OBJECTFLIP) // flip the player! { @@ -12640,8 +12632,8 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) if (z < floor) z = floor; - else if (z > ceiling - mobjinfo[MT_PLAYER].height) - z = ceiling - mobjinfo[MT_PLAYER].height; + else if (z > ceilingspawn) + z = ceilingspawn; mobj->floorz = floor; mobj->ceilingz = ceiling; @@ -12671,8 +12663,8 @@ void P_MovePlayerToStarpost(INT32 playernum) I_Assert(mobj != NULL); P_UnsetThingPosition(mobj); - mobj->x = p->starpostx << FRACBITS; - mobj->y = p->starposty << FRACBITS; + mobj->x = p->starpostx; + mobj->y = p->starposty; P_SetThingPosition(mobj); sector = R_PointInSubsector(mobj->x, mobj->y)->sector; @@ -12684,9 +12676,9 @@ void P_MovePlayerToStarpost(INT32 playernum) sector->ceilingheight; if (mobj->player->starpostflip) - z = (p->starpostz<height; + z = p->starpostz - 128*mapobjectscale - mobj->height; else - z = (p->starpostz<starpostz + 128*mapobjectscale; //z = (p->starpostz + 128) << FRACBITS; // reverse gravity exists, pls mobj->player->starpostflip = 0; diff --git a/src/p_sight.c b/src/p_sight.c index 2f4522be2..0c2262ae8 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -397,13 +397,6 @@ static boolean P_CanWaypointTraverse(seg_t *seg, divline_t *divl, register los_t return false; } - if (line->special == 2001) - { - // Don't allow through the finish linedef. - // Causes some janky behavior. - return false; - } - // calculate fractional intercept (how far along we are divided by how far we are from t2) frac = P_InterceptVector(&los->strace, divl); diff --git a/src/p_spec.c b/src/p_spec.c index b4108f042..f233307d6 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1896,30 +1896,6 @@ void P_SwitchWeather(preciptype_t newWeather) P_SpawnPrecipitation(); } -static boolean isfinish(waypoint_t *check) -{ - size_t i; - waypoint_t *finish = K_GetFinishLineWaypoint(); - - if (check == NULL) - return false; - if (check == finish) - return true; - - for (i = 0; i < check->numnextwaypoints; i++) - { - if (check->nextwaypoints[i] == finish) - return true; - } - for (i = 0; i < check->numprevwaypoints; i++) - { - if (check->prevwaypoints[i] == finish) - return true; - } - - return false; -} - // fix the player's current waypoint after crossing the finish line // get them off the finish line waypoint ASAP! static void K_FixupFinishWaypoint(player_t *player, boolean reverse) @@ -1928,12 +1904,8 @@ static void K_FixupFinishWaypoint(player_t *player, boolean reverse) fixed_t closest = INT32_MAX; waypoint_t *finish = K_GetFinishLineWaypoint(), *snapto = NULL; - // now did we actually cross the REAL finish line? - // this is important for sprint maps - if (!isfinish(player->currentwaypoint) && !isfinish(player->nextwaypoint)) - return; - - //CONS_Printf("fixed up %td\n", player - players); + if (player->currentwaypoint == NULL || mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE) + return; // why bother? if (reverse) { @@ -1956,7 +1928,8 @@ static void K_FixupFinishWaypoint(player_t *player, boolean reverse) } } - if (snapto) + // this deals with lapspersection... somehow... + if (snapto != NULL && u32_delta(player->currentwaypoint->distancetofinish, snapto->distancetofinish) > K_GetWaypointSnapThreshold()) { player->currentwaypoint = snapto; player->nextwaypoint = NULL; // don't forget to update position after this :^) @@ -2010,9 +1983,9 @@ static void K_HandleLapIncrement(player_t *player) { // SRB2Kart 281118 // Save the player's time and position. - player->starpostx = player->mo->x>>FRACBITS; - player->starposty = player->mo->y>>FRACBITS; - player->starpostz = player->mo->floorz>>FRACBITS; + player->starpostx = player->mo->x; + player->starposty = player->mo->y; + player->starpostz = player->mo->floorz; player->starpostflip = player->mo->flags2 & MF2_OBJECTFLIP; // store flipping player->starpostangle = player->mo->angle; //R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); torn; a momentum-based guess is less likely to be wrong in general, but when it IS wrong, it fucks you over entirely... } diff --git a/src/p_telept.c b/src/p_telept.c index 9a16a8376..73be04e7f 100644 --- a/src/p_telept.c +++ b/src/p_telept.c @@ -32,7 +32,7 @@ */ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, - INT16 starpostx, INT16 starposty, INT16 starpostz, + fixed_t starpostx, fixed_t starposty, fixed_t starpostz, INT32 starpostnum, tic_t starposttime, angle_t starpostangle, fixed_t starpostscale, angle_t drawangle, INT32 flags2) {