From cf1c7f9f10ccb29984a4edd59305c3b4241c11d4 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 29 May 2020 11:49:32 -0400 Subject: [PATCH] FULLY fix the respawn finish line exploit, by adding a "P_HitSpecialLines" function --- src/p_map.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/p_maputl.h | 1 + src/p_mobj.c | 1 + 3 files changed, 96 insertions(+) diff --git a/src/p_map.c b/src/p_map.c index 62aed169a..ad0464ffa 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2992,6 +2992,100 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y) return true; } +// +// PTR_GetSpecialLines +// +static boolean PTR_GetSpecialLines(intercept_t *in) +{ + line_t *ld; + + I_Assert(in->isaline); + + ld = in->d.line; + + if (!ld->backsector) + { + return true; + } + + if (P_SpecialIsLinedefCrossType(ld->special)) + { + add_spechit(ld); + } + + return true; +} + +// +// P_HitSpecialLines +// Finds all special lines in the provided path and tries to cross them. +// For zoom tubes and respawning, which noclip but need to cross finish lines. +// +void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_t momy) +{ + fixed_t leadx, leady; + fixed_t trailx, traily; + line_t *ld = NULL; + INT32 side = 0, oldside = 0; + + I_Assert(thing != NULL); +#ifdef PARANOIA + if (P_MobjWasRemoved(thing)) + I_Error("Previously-removed Thing of type %u crashes P_CheckPosition!", thing->type); +#endif + + // reset special lines + numspechitint = 0U; + numspechit = 0U; + + // trace along the three leading corners + if (momx > 0) + { + leadx = thing->x + thing->radius; + trailx = thing->x - thing->radius; + } + else + { + leadx = thing->x - thing->radius; + trailx = thing->x + thing->radius; + } + + if (momy > 0) + { + leady = thing->y + thing->radius; + traily = thing->y - thing->radius; + } + else + { + leady = thing->y - thing->radius; + traily = thing->y + thing->radius; + } + + P_PathTraverse(leadx, leady, leadx + momx, leady + momy, PT_ADDLINES, PTR_GetSpecialLines); + P_PathTraverse(trailx, leady, trailx + momx, leady + momy, PT_ADDLINES, PTR_GetSpecialLines); + P_PathTraverse(leadx, traily, leadx + momx, traily + momy, PT_ADDLINES, PTR_GetSpecialLines); + + spechitint_copyinto(); + + // remove any duplicates that may be in spechitint + spechitint_removedups(); + + // handle any of the special lines that were crossed + while (numspechitint--) + { + ld = &lines[spechitint[numspechitint]]; + side = P_PointOnLineSide(x + momx, y + momy, ld); + oldside = P_PointOnLineSide(x, y, ld); + if (side != oldside) + { + if (ld->special) + { + P_CrossSpecialLine(ld, oldside, thing); + } + } + } +} + // // P_ThingHeightClip // Takes a valid thing and adjusts the thing->floorz, diff --git a/src/p_maputl.h b/src/p_maputl.h index 1fcb68d4c..c8b628780 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -53,6 +53,7 @@ void P_UnsetPrecipThingPosition(precipmobj_t *thing); void P_SetPrecipitationThingPosition(precipmobj_t *thing); void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y); boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y); +void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_t momy); extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; #ifdef ESLOPE diff --git a/src/p_mobj.c b/src/p_mobj.c index 96a1c7a0c..fcf05d12e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3753,6 +3753,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) if ((mobj->tracer && mobj->tracer->type == MT_TUBEWAYPOINT) || (mobj->player->respawnvars.respawnstate == RESPAWNST_MOVE)) { + P_HitSpecialLines(mobj, mobj->x, mobj->y, mobj->momx, mobj->momy); P_UnsetThingPosition(mobj); mobj->x += mobj->momx; mobj->y += mobj->momy;