From ce872ed4e62cc2178a7c7bcb5ca552079d2e72c2 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 1 Jan 2023 12:57:15 -0500 Subject: [PATCH] Fixes issue #299 by ensuring Knuckles's angle normal intersects the linedef before latching --- src/p_map.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/p_map.c b/src/p_map.c index 5c8ccbb19..a0620627c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3477,6 +3477,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)