From ef4ef91fed3fe29eb3b47d8881ae564f57cfd89f Mon Sep 17 00:00:00 2001 From: JugadorXEI Date: Tue, 30 Sep 2025 22:05:35 +0000 Subject: [PATCH] Add workaround for gremlin'd wall collisions --- src/p_map.c | 20 ---------------- src/p_test.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 2a5e30205..c1d0455a0 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4104,8 +4104,6 @@ papercollision: static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result) { - extern consvar_t cv_showgremlins; - fixed_t mmomx = 0, mmomy = 0; fixed_t oldmomx = mo->momx, oldmomy = mo->momy; @@ -4130,24 +4128,6 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result) slidemo = mo; bestslideline = result->line; - if (bestslideline == NULL && cv_showgremlins.value) - { - // debug - mobj_t*x = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK); - x->frame = FF_FULLBRIGHT | FF_ADD; - x->renderflags = RF_ALWAYSONTOP; - x->color = SKINCOLOR_RED; - - CONS_Printf( - "GREMLIN: leveltime=%u x=%f y=%f z=%f angle=%f\n", - leveltime, - FixedToFloat(mo->x), - FixedToFloat(mo->y), - FixedToFloat(mo->z), - AngleToFloat(R_PointToAngle2(0, 0, oldmomx, oldmomy)) - ); - } - if (mo->health <= 0) { tmxmove = mo->momx; diff --git a/src/p_test.cpp b/src/p_test.cpp index 5b9b07e42..2c4ebf57f 100644 --- a/src/p_test.cpp +++ b/src/p_test.cpp @@ -15,6 +15,8 @@ #include "p_sweep.hpp" #include "p_local.h" +#include "g_demo.h" +#include "r_main.h" namespace { @@ -30,6 +32,8 @@ void P_TestLine(line_t* ld) line_t* P_SweepTestLines(fixed_t ax, fixed_t ay, fixed_t bx, fixed_t by, fixed_t r, vector2_t* return_normal) { + extern consvar_t cv_showgremlins; + using namespace srb2::math; using namespace srb2::sweep; @@ -60,13 +64,65 @@ line_t* P_SweepTestLines(fixed_t ax, fixed_t ay, fixed_t bx, fixed_t by, fixed_t } } - g_lines.clear(); - if (!collision) { - return nullptr; + line_t *line = nullptr; + + if (!g_lines.empty() && !G_CompatLevel(0x000E)) + { + // FIXME: This condition is a failsafe! + // SlopeAABBvsLine::vs_slope can sometimes report + // no collision despite P_CheckPosition saying otherwise. + // (Generally related to infinitesimal numbers or overflows.) + // When it reports no collision, that means no line and + // no normals to base the collision off of. + // Here we provide the last line checked and normals based on + // the line and the player's momentum angle. + // But the proper fix would be to make vs_slope work!! + + line = g_lines.back(); + + angle_t lineangle = line->angle; + angle_t mobjangle = R_PointToAngle2(ax, ay, bx, by); + angle_t diff = lineangle - mobjangle; + + lineangle += diff > ANGLE_180 ? -ANGLE_90 : ANGLE_90; + + return_normal->x = FINECOSINE((lineangle >> ANGLETOFINESHIFT) & FINEMASK); + return_normal->y = FINESINE((lineangle >> ANGLETOFINESHIFT) & FINEMASK); + + // Moving the gremlin debug here so that it + // still fires even when the workaround is used. + if (cv_showgremlins.value) + { + mobj_t *mo = g_tm.thing; + + if (mo) + { + mobj_t *x = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK); + x->frame = FF_FULLBRIGHT | FF_ADD; + x->renderflags = RF_ALWAYSONTOP; + x->color = SKINCOLOR_RED; + + CONS_Printf( + "GREMLIN: leveltime=%u x=%f y=%f z=%f momx=%f momy=%f momz=%f\n", + leveltime, + FixedToFloat(mo->x), + FixedToFloat(mo->y), + FixedToFloat(mo->z), + FixedToFloat(mo->momx), + FixedToFloat(mo->momy), + FixedToFloat(mo->momz) + ); + } + } + } + + g_lines.clear(); + return line; } + g_lines.clear(); return_normal->x = Fixed {collision->normal.x}; return_normal->y = Fixed {collision->normal.y};