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
This commit is contained in:
GenericHeroGuy 2025-10-29 23:15:45 +01:00
parent 333b8955c8
commit 29c3c3c55c
16 changed files with 172 additions and 216 deletions

View file

@ -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));

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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
{

View file

@ -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

View file

@ -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)

View file

@ -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);

View file

@ -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);

View file

@ -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
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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<<FRACBITS) - FixedMul(128<<FRACBITS, mapobjectscale) - mobj->height;
z = p->starpostz - 128*mapobjectscale - mobj->height;
else
z = (p->starpostz<<FRACBITS) + FixedMul(128<<FRACBITS, mapobjectscale);
z = p->starpostz + 128*mapobjectscale;
//z = (p->starpostz + 128) << FRACBITS; // reverse gravity exists, pls
mobj->player->starpostflip = 0;

View file

@ -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);

View file

@ -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...
}

View file

@ -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)
{