Merge branch 'issue299' into 'next'

Fixes issue #299 by ensuring Knuckles's angle normal intersects the linedef before latching

Closes #299

See merge request STJr/SRB2!1906
This commit is contained in:
SSNTails 2025-03-21 18:13:06 +00:00
commit 79c9c9d8f8

View file

@ -3466,6 +3466,53 @@ static void PTR_GlideClimbTraverse(line_t *li)
canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true);
if (!slidemo->player->climbing && canclimb)
{
// When latching on from a glide, ensure that the line segment of Knuckles's movement intersects with the line segment of the linedef.
// Position in front of the player. Think of it like the facing normal.
// Uses 20*FRACUNIT as an arbitrary distance
fixed_t posPlusNormalX = slidemo->x + FixedMul(slidemo->radius + 20*FRACUNIT, FINECOSINE(slidemo->angle >> ANGLETOFINESHIFT));
fixed_t posPlusNormalY = slidemo->y + FixedMul(slidemo->radius + 20*FRACUNIT, FINESINE(slidemo->angle >> ANGLETOFINESHIFT));
INT32 pointOnSides[4];
vector3_t pointVec, lineVec[2];
pointVec.z = 0;
lineVec[0].z = 0;
lineVec[1].z = 0;
// Player's position
pointVec.x = slidemo->x;
pointVec.y = slidemo->y;
lineVec[0].x = li->v1->x;
lineVec[0].y = li->v1->y;
lineVec[1].x = li->v2->x;
lineVec[1].y = li->v2->y;
pointOnSides[0] = FV3_PointOnLineSide(&pointVec, lineVec);
// Player's position + radius + 20*FRACUNIT
pointVec.x = posPlusNormalX;
pointVec.y = posPlusNormalY;
pointOnSides[1] = FV3_PointOnLineSide(&pointVec, lineVec);
// Linedef vertex 1
lineVec[0].x = slidemo->x;
lineVec[0].y = slidemo->y;
lineVec[1].x = posPlusNormalX;
lineVec[1].y = posPlusNormalY;
pointVec.x = li->v1->x;
pointVec.y = li->v1->y;
pointOnSides[2] = FV3_PointOnLineSide(&pointVec, lineVec);
// Linedef vertex 2
pointVec.x = li->v2->x;
pointVec.y = li->v2->y;
pointOnSides[3] = FV3_PointOnLineSide(&pointVec, lineVec);
if (pointOnSides[0] == pointOnSides[1] || pointOnSides[2] == pointOnSides[3])
canclimb = false;
}
if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45)
|| (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135))
&& canclimb)