mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-28 23:21:58 +00:00
Starting over, beginning with cleaning up floorz/ceilingz functions
This commit is contained in:
parent
a8a92a57a7
commit
d166a1509d
2 changed files with 38 additions and 196 deletions
|
@ -308,21 +308,19 @@ void P_PushableThinker(mobj_t *mobj);
|
|||
void P_SceneryThinker(mobj_t *mobj);
|
||||
|
||||
|
||||
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);
|
||||
fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
|
||||
#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(mobj, sector, NULL, x, y, line, false, false)
|
||||
#define P_GetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(mobj, sector, NULL, x, y, line, true, false)
|
||||
#define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false)
|
||||
#define P_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false)
|
||||
#define P_GetSpecialBottomZ(mobj, src, bound) P_MobjFloorZ(mobj, src, bound, mobj->x, mobj->y, NULL, src != bound, true)
|
||||
#define P_GetSpecialTopZ(mobj, src, bound) P_MobjCeilingZ(mobj, src, bound, mobj->x, mobj->y, NULL, src == bound, true)
|
||||
fixed_t P_MobjFloorZ(sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, fixed_t radius, line_t *line, boolean lowest, boolean perfect);
|
||||
fixed_t P_MobjCeilingZ(sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, fixed_t radius, line_t *line, boolean lowest, boolean perfect);
|
||||
#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(sector, NULL, x, y, mobj->radius, line, false, false)
|
||||
#define P_GetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(sector, NULL, x, y, mobj->radius, line, true, false)
|
||||
#define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(sectors + fof->secnum, sector, x, y, mobj->radius, line, false, false)
|
||||
#define P_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(sectors + fof->secnum, sector, x, y, mobj->radius, line, true, false)
|
||||
#define P_GetSpecialBottomZ(mobj, src, bound) P_MobjFloorZ(src, bound, mobj->x, mobj->y, mobj->radius, NULL, src != bound, true)
|
||||
#define P_GetSpecialTopZ(mobj, src, bound) P_MobjCeilingZ(src, bound, mobj->x, mobj->y, mobj->radius, NULL, src == bound, true)
|
||||
|
||||
fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
|
||||
fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
|
||||
#define P_CameraGetFloorZ(mobj, sector, x, y, line) P_CameraFloorZ(mobj, sector, NULL, x, y, line, false, false)
|
||||
#define P_CameraGetCeilingZ(mobj, sector, x, y, line) P_CameraCeilingZ(mobj, sector, NULL, x, y, line, true, false)
|
||||
#define P_CameraGetFOFTopZ(mobj, sector, fof, x, y, line) P_CameraCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false)
|
||||
#define P_CameraGetFOFBottomZ(mobj, sector, fof, x, y, line) P_CameraFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false)
|
||||
#define P_CameraGetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(sector, NULL, x, y, mobj->radius, line, false, false)
|
||||
#define P_CameraGetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(sector, NULL, x, y, mobj->radius, line, true, false)
|
||||
#define P_CameraGetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(sectors + fof->secnum, sector, x, y, mobj->radius, line, false, false)
|
||||
#define P_CameraGetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(sectors + fof->secnum, sector, x, y, mobj->radius, line, true, false)
|
||||
|
||||
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover);
|
||||
boolean P_CheckDeathPitCollide(mobj_t *mo);
|
||||
|
|
208
src/p_mobj.c
208
src/p_mobj.c
|
@ -1092,9 +1092,8 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line,
|
|||
);
|
||||
}
|
||||
|
||||
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)
|
||||
fixed_t P_MobjFloorZ(sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, fixed_t radius, line_t *line, boolean lowest, boolean perfect)
|
||||
{
|
||||
I_Assert(mobj != NULL);
|
||||
I_Assert(sector != NULL);
|
||||
|
||||
if (sector->f_slope) {
|
||||
|
@ -1103,14 +1102,14 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
|
|||
|
||||
// Get the corner of the object that should be the highest on the slope
|
||||
if (slope->d.x < 0)
|
||||
testx = mobj->radius;
|
||||
testx = radius;
|
||||
else
|
||||
testx = -mobj->radius;
|
||||
testx = -radius;
|
||||
|
||||
if (slope->d.y < 0)
|
||||
testy = mobj->radius;
|
||||
testy = radius;
|
||||
else
|
||||
testy = -mobj->radius;
|
||||
testy = -radius;
|
||||
|
||||
if ((slope->zdelta > 0) ^ !!(lowest)) {
|
||||
testx = -testx;
|
||||
|
@ -1136,10 +1135,10 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
|
|||
else
|
||||
finalheight = INT32_MIN;
|
||||
|
||||
bbox[BOXLEFT] = x-mobj->radius;
|
||||
bbox[BOXRIGHT] = x+mobj->radius;
|
||||
bbox[BOXTOP] = y+mobj->radius;
|
||||
bbox[BOXBOTTOM] = y-mobj->radius;
|
||||
bbox[BOXLEFT] = x-radius;
|
||||
bbox[BOXRIGHT] = x+radius;
|
||||
bbox[BOXTOP] = y+radius;
|
||||
bbox[BOXBOTTOM] = y-radius;
|
||||
for (i = 0; i < boundsec->linecount; i++) {
|
||||
ld = boundsec->lines[i];
|
||||
|
||||
|
@ -1151,9 +1150,9 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
|
|||
continue;
|
||||
|
||||
if (lowest)
|
||||
finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true));
|
||||
finalheight = min(finalheight, HighestOnLine(radius, x, y, ld, slope, true));
|
||||
else
|
||||
finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false));
|
||||
finalheight = max(finalheight, HighestOnLine(radius, x, y, ld, slope, false));
|
||||
}
|
||||
|
||||
return finalheight;
|
||||
|
@ -1164,14 +1163,13 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
|
|||
if (line == NULL)
|
||||
return P_GetSlopeZAt(slope, x, y);
|
||||
|
||||
return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
|
||||
return HighestOnLine(radius, x, y, line, slope, lowest);
|
||||
} else // Well, that makes it easy. Just get the floor height
|
||||
return sector->floorheight;
|
||||
}
|
||||
|
||||
fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect)
|
||||
fixed_t P_MobjCeilingZ(sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, fixed_t radius, line_t *line, boolean lowest, boolean perfect)
|
||||
{
|
||||
I_Assert(mobj != NULL);
|
||||
I_Assert(sector != NULL);
|
||||
|
||||
if (sector->c_slope) {
|
||||
|
@ -1180,14 +1178,14 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed
|
|||
|
||||
// Get the corner of the object that should be the highest on the slope
|
||||
if (slope->d.x < 0)
|
||||
testx = mobj->radius;
|
||||
testx = radius;
|
||||
else
|
||||
testx = -mobj->radius;
|
||||
testx = -radius;
|
||||
|
||||
if (slope->d.y < 0)
|
||||
testy = mobj->radius;
|
||||
testy = radius;
|
||||
else
|
||||
testy = -mobj->radius;
|
||||
testy = -radius;
|
||||
|
||||
if ((slope->zdelta > 0) ^ !!(lowest)) {
|
||||
testx = -testx;
|
||||
|
@ -1213,10 +1211,10 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed
|
|||
else
|
||||
finalheight = INT32_MIN;
|
||||
|
||||
bbox[BOXLEFT] = x-mobj->radius;
|
||||
bbox[BOXRIGHT] = x+mobj->radius;
|
||||
bbox[BOXTOP] = y+mobj->radius;
|
||||
bbox[BOXBOTTOM] = y-mobj->radius;
|
||||
bbox[BOXLEFT] = x-radius;
|
||||
bbox[BOXRIGHT] = x+radius;
|
||||
bbox[BOXTOP] = y+radius;
|
||||
bbox[BOXBOTTOM] = y-radius;
|
||||
for (i = 0; i < boundsec->linecount; i++) {
|
||||
ld = boundsec->lines[i];
|
||||
|
||||
|
@ -1228,9 +1226,9 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed
|
|||
continue;
|
||||
|
||||
if (lowest)
|
||||
finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true));
|
||||
finalheight = min(finalheight, HighestOnLine(radius, x, y, ld, slope, true));
|
||||
else
|
||||
finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false));
|
||||
finalheight = max(finalheight, HighestOnLine(radius, x, y, ld, slope, false));
|
||||
}
|
||||
|
||||
return finalheight;
|
||||
|
@ -1241,165 +1239,11 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed
|
|||
if (line == NULL)
|
||||
return P_GetSlopeZAt(slope, x, y);
|
||||
|
||||
return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
|
||||
return HighestOnLine(radius, x, y, line, slope, lowest);
|
||||
} else // Well, that makes it easy. Just get the ceiling height
|
||||
return sector->ceilingheight;
|
||||
}
|
||||
|
||||
// Now do the same as all above, but for cameras because apparently cameras are special?
|
||||
fixed_t P_CameraFloorZ(camera_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);
|
||||
I_Assert(sector != NULL);
|
||||
|
||||
if (sector->f_slope) {
|
||||
fixed_t testx, testy;
|
||||
pslope_t *slope = sector->f_slope;
|
||||
|
||||
// Get the corner of the object that should be the highest on the slope
|
||||
if (slope->d.x < 0)
|
||||
testx = mobj->radius;
|
||||
else
|
||||
testx = -mobj->radius;
|
||||
|
||||
if (slope->d.y < 0)
|
||||
testy = mobj->radius;
|
||||
else
|
||||
testy = -mobj->radius;
|
||||
|
||||
if ((slope->zdelta > 0) ^ !!(lowest)) {
|
||||
testx = -testx;
|
||||
testy = -testy;
|
||||
}
|
||||
|
||||
testx += x;
|
||||
testy += y;
|
||||
|
||||
// If the highest point is in the sector, then we have it easy! Just get the Z at that point
|
||||
if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy))
|
||||
return P_GetSlopeZAt(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
|
||||
if (perfect) {
|
||||
size_t i;
|
||||
line_t *ld;
|
||||
fixed_t bbox[4];
|
||||
fixed_t finalheight;
|
||||
|
||||
if (lowest)
|
||||
finalheight = INT32_MAX;
|
||||
else
|
||||
finalheight = INT32_MIN;
|
||||
|
||||
bbox[BOXLEFT] = x-mobj->radius;
|
||||
bbox[BOXRIGHT] = x+mobj->radius;
|
||||
bbox[BOXTOP] = y+mobj->radius;
|
||||
bbox[BOXBOTTOM] = y-mobj->radius;
|
||||
for (i = 0; i < boundsec->linecount; i++) {
|
||||
ld = boundsec->lines[i];
|
||||
|
||||
if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT]
|
||||
|| bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
|
||||
continue;
|
||||
|
||||
if (P_BoxOnLineSide(bbox, ld) != -1)
|
||||
continue;
|
||||
|
||||
if (lowest)
|
||||
finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true));
|
||||
else
|
||||
finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false));
|
||||
}
|
||||
|
||||
return finalheight;
|
||||
}
|
||||
|
||||
// If we're just testing for base sector location (no collision line), just go for the center's spot...
|
||||
// It'll get fixed when we test for collision anyway, and the final result can't be lower than this
|
||||
if (line == NULL)
|
||||
return P_GetSlopeZAt(slope, x, y);
|
||||
|
||||
return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
|
||||
} else // Well, that makes it easy. Just get the floor height
|
||||
return sector->floorheight;
|
||||
}
|
||||
|
||||
fixed_t P_CameraCeilingZ(camera_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);
|
||||
I_Assert(sector != NULL);
|
||||
|
||||
if (sector->c_slope) {
|
||||
fixed_t testx, testy;
|
||||
pslope_t *slope = sector->c_slope;
|
||||
|
||||
// Get the corner of the object that should be the highest on the slope
|
||||
if (slope->d.x < 0)
|
||||
testx = mobj->radius;
|
||||
else
|
||||
testx = -mobj->radius;
|
||||
|
||||
if (slope->d.y < 0)
|
||||
testy = mobj->radius;
|
||||
else
|
||||
testy = -mobj->radius;
|
||||
|
||||
if ((slope->zdelta > 0) ^ !!(lowest)) {
|
||||
testx = -testx;
|
||||
testy = -testy;
|
||||
}
|
||||
|
||||
testx += x;
|
||||
testy += y;
|
||||
|
||||
// If the highest point is in the sector, then we have it easy! Just get the Z at that point
|
||||
if (R_IsPointInSector(boundsec ? boundsec : sector, testx, testy))
|
||||
return P_GetSlopeZAt(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
|
||||
if (perfect) {
|
||||
size_t i;
|
||||
line_t *ld;
|
||||
fixed_t bbox[4];
|
||||
fixed_t finalheight;
|
||||
|
||||
if (lowest)
|
||||
finalheight = INT32_MAX;
|
||||
else
|
||||
finalheight = INT32_MIN;
|
||||
|
||||
bbox[BOXLEFT] = x-mobj->radius;
|
||||
bbox[BOXRIGHT] = x+mobj->radius;
|
||||
bbox[BOXTOP] = y+mobj->radius;
|
||||
bbox[BOXBOTTOM] = y-mobj->radius;
|
||||
for (i = 0; i < boundsec->linecount; i++) {
|
||||
ld = boundsec->lines[i];
|
||||
|
||||
if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT]
|
||||
|| bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
|
||||
continue;
|
||||
|
||||
if (P_BoxOnLineSide(bbox, ld) != -1)
|
||||
continue;
|
||||
|
||||
if (lowest)
|
||||
finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true));
|
||||
else
|
||||
finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false));
|
||||
}
|
||||
|
||||
return finalheight;
|
||||
}
|
||||
|
||||
// If we're just testing for base sector location (no collision line), just go for the center's spot...
|
||||
// It'll get fixed when we test for collision anyway, and the final result can't be lower than this
|
||||
if (line == NULL)
|
||||
return P_GetSlopeZAt(slope, x, y);
|
||||
|
||||
return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
|
||||
} else // Well, that makes it easy. Just get the ceiling height
|
||||
return sector->ceilingheight;
|
||||
}
|
||||
static void P_PlayerFlip(mobj_t *mo)
|
||||
{
|
||||
if (!mo->player)
|
||||
|
@ -2329,8 +2173,8 @@ boolean P_CheckDeathPitCollide(mobj_t *mo)
|
|||
if (mo->player && mo->player->pflags & PF_GODMODE)
|
||||
return false;
|
||||
|
||||
fixed_t sectorFloor = P_GetSectorFloorZAt(mo->subsector->sector, mo->x, mo->y);
|
||||
fixed_t sectorCeiling = P_GetSectorCeilingZAt(mo->subsector->sector, mo->x, mo->y);
|
||||
fixed_t sectorFloor = P_MobjFloorZ(mo->subsector->sector, mo->subsector->sector, mo->x, mo->y, mo->radius, NULL, false, true);
|
||||
fixed_t sectorCeiling = P_MobjCeilingZ(mo->subsector->sector, mo->subsector->sector, mo->x, mo->y, mo->radius, NULL, true, true);
|
||||
|
||||
if (((mo->z <= sectorFloor
|
||||
&& ((mo->subsector->sector->flags & MSF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->subsector->sector->flags & MSF_FLIPSPECIAL_FLOOR))
|
||||
|
|
Loading…
Reference in a new issue