Add workaround for gremlin'd wall collisions

This commit is contained in:
JugadorXEI 2025-09-21 18:27:32 +02:00 committed by NepDisk
parent 703afe7992
commit 01b2f9d5b0

View file

@ -15,6 +15,8 @@
#include "p_sweep.hpp" #include "p_sweep.hpp"
#include "p_local.h" #include "p_local.h"
#include "g_demo.h"
#include "r_main.h"
consvar_t cv_showgremlins = CVAR_INIT ("showgremlins", "Off", 0, CV_OnOff, NULL); consvar_t cv_showgremlins = CVAR_INIT ("showgremlins", "Off", 0, CV_OnOff, NULL);
@ -62,13 +64,39 @@ line_t* P_SweepTestLines(fixed_t ax, fixed_t ay, fixed_t bx, fixed_t by, fixed_t
} }
} }
g_lines.clear();
if (!collision) 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);
}
g_lines.clear();
return line;
} }
g_lines.clear();
return_normal->x = Fixed {collision->normal.x}; return_normal->x = Fixed {collision->normal.x};
return_normal->y = Fixed {collision->normal.y}; return_normal->y = Fixed {collision->normal.y};