diff --git a/src/p_mobj.c b/src/p_mobj.c index 03e7e9f99..96651dd74 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -578,6 +578,8 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, ); } +#define NOCOLLISION ((mobj->flags & MF_NOBLOCKMAP) || (mobj->flags & MF_NOCLIPTHING)) + fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) { I_Assert(mobj != NULL); @@ -608,7 +610,7 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) + if (NOCOLLISION ? R_IsPointInSector(boundsec ? boundsec : sector, testx, testy) : R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) return P_GetZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point @@ -685,7 +687,7 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) + if (NOCOLLISION ? R_IsPointInSector(boundsec ? boundsec : sector, testx, testy) : R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) return P_GetZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point @@ -764,7 +766,7 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) + if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) return P_GetZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point @@ -842,7 +844,7 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == (boundsec ? boundsec : sector)) + if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy)) return P_GetZAt(slope, testx, testy); // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point diff --git a/src/r_main.c b/src/r_main.c index 9541fef41..6dbd8f059 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1026,6 +1026,50 @@ void R_Init(void) framecount = 0; } +// +// R_IsPointInSector +// +boolean R_IsPointInSector(sector_t *sector, fixed_t x, fixed_t y) +{ + size_t i; + size_t passes = 0; + + for (i = 0; i < sector->linecount; i++) + { + line_t *line = sector->lines[i]; + vertex_t *v1, *v2; + + if (line->frontsector == line->backsector) + continue; + + v1 = line->v1; + v2 = line->v2; + + // make sure v1 is below v2 + if (v1->y > v2->y) + { + vertex_t *tmp = v1; + v1 = v2; + v2 = tmp; + } + else if (v1->y == v2->y) // horizontal line, we can't match this + continue; + + if (v1->y < y && y <= v2->y) + { + // if the y axis in inside the line, find the point where we intersect on the x axis... + fixed_t vx = v1->x + (INT64)(v2->x - v1->x) * (y - v1->y) / (v2->y - v1->y); + + // ...and if that point is to the left of the point, count it as inside. + if (vx < x) + passes++; + } + } + + // and odd number of passes means we're inside the polygon. + return passes % 2; +} + // // R_IsPointInSubsector, same as above but returns 0 if not in subsector // diff --git a/src/r_main.h b/src/r_main.h index 523e924d5..3fbc3dd99 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -125,6 +125,7 @@ angle_t R_PlayerSliptideAngle(player_t *player); fixed_t R_ScaleFromGlobalAngle(angle_t visangle); +boolean R_IsPointInSector(sector_t *sector, fixed_t x, fixed_t y); subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y); //