mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-11-11 07:41:36 +00:00
Make cameras properly collide with slopes
This commit is contained in:
parent
7a3c5b3dd9
commit
3d2b71b24c
4 changed files with 523 additions and 61 deletions
|
@ -237,6 +237,11 @@ fixed_t P_GetCeilingZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line
|
||||||
fixed_t P_GetFOFTopZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line);
|
fixed_t P_GetFOFTopZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line);
|
||||||
fixed_t P_GetFOFBottomZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line);
|
fixed_t P_GetFOFBottomZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line);
|
||||||
|
|
||||||
|
fixed_t P_CameraGetFloorZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line);
|
||||||
|
fixed_t P_CameraGetCeilingZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line);
|
||||||
|
fixed_t P_CameraGetFOFTopZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line);
|
||||||
|
fixed_t P_CameraGetFOFBottomZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line);
|
||||||
|
|
||||||
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover);
|
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover);
|
||||||
boolean P_CheckDeathPitCollide(mobj_t *mo);
|
boolean P_CheckDeathPitCollide(mobj_t *mo);
|
||||||
boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover);
|
boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover);
|
||||||
|
|
27
src/p_map.c
27
src/p_map.c
|
@ -1517,21 +1517,9 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||||
// that contains the point.
|
// that contains the point.
|
||||||
// Any contacted lines the step closer together
|
// Any contacted lines the step closer together
|
||||||
// will adjust them.
|
// will adjust them.
|
||||||
#ifdef ESLOPE
|
tmfloorz = tmdropoffz = P_CameraGetFloorZ(thiscam, newsubsec->sector, x, y, NULL);
|
||||||
if (newsubsec->sector->f_slope)
|
|
||||||
{
|
|
||||||
tmfloorz = tmdropoffz = P_GetZAt(newsubsec->sector->f_slope, thiscam->x, thiscam->y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
tmfloorz = tmdropoffz = newsubsec->sector->floorheight;
|
|
||||||
|
|
||||||
#ifdef ESLOPE
|
tmceilingz = P_CameraGetCeilingZ(thiscam, newsubsec->sector, x, y, NULL);
|
||||||
if (newsubsec->sector->c_slope)
|
|
||||||
tmceilingz = P_GetZAt(newsubsec->sector->c_slope, thiscam->x, thiscam->y);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
tmceilingz = newsubsec->sector->ceilingheight;
|
|
||||||
|
|
||||||
// Cameras use the heightsec's heights rather then the actual sector heights.
|
// Cameras use the heightsec's heights rather then the actual sector heights.
|
||||||
// If you can see through it, why not move the camera through it too?
|
// If you can see through it, why not move the camera through it too?
|
||||||
|
@ -1560,15 +1548,8 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
|
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fixed_t topheight = *rover->topheight;
|
fixed_t topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, x, y, NULL);
|
||||||
fixed_t bottomheight = *rover->bottomheight;
|
fixed_t bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, x, y, NULL);
|
||||||
|
|
||||||
/*#ifdef ESLOPE
|
|
||||||
if (rover->t_slope)
|
|
||||||
topheight = P_GetZAt(rover->t_slope, thiscam->x, thiscam->y);
|
|
||||||
if (rover->b_slope)
|
|
||||||
bottomheight = P_GetZAt(rover->b_slope, thiscam->x, thiscam->y);
|
|
||||||
#endif*/
|
|
||||||
|
|
||||||
delta1 = thiscam->z - (bottomheight
|
delta1 = thiscam->z - (bottomheight
|
||||||
+ ((topheight - bottomheight)/2));
|
+ ((topheight - bottomheight)/2));
|
||||||
|
|
|
@ -375,14 +375,8 @@ void P_CameraLineOpening(line_t *linedef)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
frontfloor = front->floorheight;
|
frontfloor = P_CameraGetFloorZ(mapcampointer, front, tmx, tmy, linedef);
|
||||||
frontceiling = front->ceilingheight;
|
frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef);
|
||||||
#ifdef ESLOPE
|
|
||||||
if (front->f_slope)
|
|
||||||
frontfloor = P_GetZAt(front->f_slope, camera.x, camera.y);
|
|
||||||
if (front->c_slope)
|
|
||||||
frontceiling = P_GetZAt(front->c_slope, camera.x, camera.y);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (back->camsec >= 0)
|
if (back->camsec >= 0)
|
||||||
{
|
{
|
||||||
|
@ -408,14 +402,8 @@ void P_CameraLineOpening(line_t *linedef)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
backfloor = back->floorheight;
|
backfloor = P_CameraGetFloorZ(mapcampointer, back, tmx, tmy, linedef);
|
||||||
backceiling = back->ceilingheight;
|
backceiling = P_CameraGetCeilingZ(mapcampointer, back, tmx, tmy, linedef);
|
||||||
#ifdef ESLOPE
|
|
||||||
if (back->f_slope)
|
|
||||||
frontfloor = P_GetZAt(back->f_slope, camera.x, camera.y);
|
|
||||||
if (back->c_slope)
|
|
||||||
frontceiling = P_GetZAt(back->c_slope, camera.x, camera.y);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -460,16 +448,8 @@ void P_CameraLineOpening(line_t *linedef)
|
||||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
|
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fixed_t topheight = *rover->topheight;
|
fixed_t topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef);
|
||||||
fixed_t bottomheight = *rover->bottomheight;
|
fixed_t bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef);
|
||||||
|
|
||||||
/*#ifdef ESLOPE
|
|
||||||
if (rover->t_slope)
|
|
||||||
topheight = P_GetZAt(rover->t_slope, camera.x, camera.y);
|
|
||||||
|
|
||||||
if (rover->b_slope)
|
|
||||||
bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y);
|
|
||||||
#endif // ESLOPE*/
|
|
||||||
|
|
||||||
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||||
|
@ -491,16 +471,8 @@ void P_CameraLineOpening(line_t *linedef)
|
||||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
|
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fixed_t topheight = *rover->topheight;
|
fixed_t topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef);
|
||||||
fixed_t bottomheight = *rover->bottomheight;
|
fixed_t bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef);
|
||||||
|
|
||||||
/*#ifdef ESLOPE
|
|
||||||
if (rover->t_slope)
|
|
||||||
topheight = P_GetZAt(rover->t_slope, camera.x, camera.y);
|
|
||||||
|
|
||||||
if (rover->b_slope)
|
|
||||||
bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y);
|
|
||||||
#endif // ESLOPE*/
|
|
||||||
|
|
||||||
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||||
|
|
508
src/p_mobj.c
508
src/p_mobj.c
|
@ -1212,6 +1212,494 @@ fixed_t P_GetFOFBottomZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x
|
||||||
return *fof->bottomheight;
|
return *fof->bottomheight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now do the same as all above, but for cameras because apparently cameras are special?
|
||||||
|
fixed_t P_CameraGetFloorZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code
|
||||||
|
{
|
||||||
|
I_Assert(mobj != NULL);
|
||||||
|
I_Assert(sector != NULL);
|
||||||
|
#ifdef ESLOPE
|
||||||
|
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) {
|
||||||
|
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_PointInSubsector(testx, testy)->sector == sector)
|
||||||
|
return P_GetZAt(slope, testx, testy);
|
||||||
|
|
||||||
|
// 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_GetZAt(slope, x, y);
|
||||||
|
|
||||||
|
// Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching...
|
||||||
|
// The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box
|
||||||
|
// (assuming it isn't already inside), then test each point's slope Z and return the higher of the two.
|
||||||
|
{
|
||||||
|
vertex_t v1, v2;
|
||||||
|
v1.x = line->v1->x;
|
||||||
|
v1.y = line->v1->y;
|
||||||
|
v2.x = line->v2->x;
|
||||||
|
v2.y = line->v2->y;
|
||||||
|
|
||||||
|
/*CONS_Printf("BEFORE: v1 = %f %f %f\n",
|
||||||
|
FIXED_TO_FLOAT(v1.x),
|
||||||
|
FIXED_TO_FLOAT(v1.y),
|
||||||
|
FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y))
|
||||||
|
);
|
||||||
|
CONS_Printf(" v2 = %f %f %f\n",
|
||||||
|
FIXED_TO_FLOAT(v2.x),
|
||||||
|
FIXED_TO_FLOAT(v2.y),
|
||||||
|
FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y))
|
||||||
|
);*/
|
||||||
|
|
||||||
|
if (abs(v1.x-x) > mobj->radius) {
|
||||||
|
// v1's x is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v1.x-x) - mobj->radius;
|
||||||
|
|
||||||
|
if (v1.x < x) { // Moving right
|
||||||
|
v1.x += diff;
|
||||||
|
v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
} else { // Moving left
|
||||||
|
v1.x -= diff;
|
||||||
|
v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(v1.y-y) > mobj->radius) {
|
||||||
|
// v1's y is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v1.y-y) - mobj->radius;
|
||||||
|
|
||||||
|
if (v1.y < y) { // Moving up
|
||||||
|
v1.y += diff;
|
||||||
|
v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
} else { // Moving down
|
||||||
|
v1.y -= diff;
|
||||||
|
v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(v2.x-x) > mobj->radius) {
|
||||||
|
// v1's x is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v2.x-x) - mobj->radius;
|
||||||
|
|
||||||
|
if (v2.x < x) { // Moving right
|
||||||
|
v2.x += diff;
|
||||||
|
v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
} else { // Moving left
|
||||||
|
v2.x -= diff;
|
||||||
|
v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(v2.y-y) > mobj->radius) {
|
||||||
|
// v2's y is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v2.y-y) - mobj->radius;
|
||||||
|
|
||||||
|
if (v2.y < y) { // Moving up
|
||||||
|
v2.y += diff;
|
||||||
|
v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
} else { // Moving down
|
||||||
|
v2.y -= diff;
|
||||||
|
v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*CONS_Printf("AFTER: v1 = %f %f %f\n",
|
||||||
|
FIXED_TO_FLOAT(v1.x),
|
||||||
|
FIXED_TO_FLOAT(v1.y),
|
||||||
|
FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y))
|
||||||
|
);
|
||||||
|
CONS_Printf(" v2 = %f %f %f\n",
|
||||||
|
FIXED_TO_FLOAT(v2.x),
|
||||||
|
FIXED_TO_FLOAT(v2.y),
|
||||||
|
FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y))
|
||||||
|
);*/
|
||||||
|
|
||||||
|
// Return the higher of the two points
|
||||||
|
return max(
|
||||||
|
P_GetZAt(slope, v1.x, v1.y),
|
||||||
|
P_GetZAt(slope, v2.x, v2.y)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else // Well, that makes it easy. Just get the floor height
|
||||||
|
#endif
|
||||||
|
return sector->floorheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed_t P_CameraGetCeilingZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code
|
||||||
|
{
|
||||||
|
I_Assert(mobj != NULL);
|
||||||
|
I_Assert(sector != NULL);
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (sector->c_slope) {
|
||||||
|
fixed_t testx, testy;
|
||||||
|
pslope_t *slope = sector->c_slope;
|
||||||
|
|
||||||
|
// Get the corner of the object that should be the lowest 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) {
|
||||||
|
testx = -testx;
|
||||||
|
testy = -testy;
|
||||||
|
}
|
||||||
|
|
||||||
|
testx += x;
|
||||||
|
testy += y;
|
||||||
|
|
||||||
|
// If the lowest point is in the sector, then we have it easy! Just get the Z at that point
|
||||||
|
if (R_PointInSubsector(testx, testy)->sector == sector)
|
||||||
|
return P_GetZAt(slope, testx, testy);
|
||||||
|
|
||||||
|
// 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 higher than this
|
||||||
|
if (line == NULL)
|
||||||
|
return P_GetZAt(slope, x, y);
|
||||||
|
|
||||||
|
// Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching...
|
||||||
|
// The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box
|
||||||
|
// (assuming it isn't already inside), then test each point's slope Z and return the lower of the two.
|
||||||
|
{
|
||||||
|
vertex_t v1, v2;
|
||||||
|
v1.x = line->v1->x;
|
||||||
|
v1.y = line->v1->y;
|
||||||
|
v2.x = line->v2->x;
|
||||||
|
v2.y = line->v2->y;
|
||||||
|
|
||||||
|
if (abs(v1.x-x) > mobj->radius) {
|
||||||
|
// v1's x is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v1.x-x) - mobj->radius;
|
||||||
|
|
||||||
|
if (v1.x < x) { // Moving right
|
||||||
|
v1.x += diff;
|
||||||
|
v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
} else { // Moving left
|
||||||
|
v1.x -= diff;
|
||||||
|
v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(v1.y-y) > mobj->radius) {
|
||||||
|
// v1's y is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v1.y-y) - mobj->radius;
|
||||||
|
|
||||||
|
if (v1.y < y) { // Moving up
|
||||||
|
v1.y += diff;
|
||||||
|
v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
} else { // Moving down
|
||||||
|
v1.y -= diff;
|
||||||
|
v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(v2.x-x) > mobj->radius) {
|
||||||
|
// v1's x is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v2.x-x) - mobj->radius;
|
||||||
|
|
||||||
|
if (v2.x < x) { // Moving right
|
||||||
|
v2.x += diff;
|
||||||
|
v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
} else { // Moving left
|
||||||
|
v2.x -= diff;
|
||||||
|
v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(v2.y-y) > mobj->radius) {
|
||||||
|
// v2's y is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v2.y-y) - mobj->radius;
|
||||||
|
|
||||||
|
if (v2.y < y) { // Moving up
|
||||||
|
v2.y += diff;
|
||||||
|
v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
} else { // Moving down
|
||||||
|
v2.y -= diff;
|
||||||
|
v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the lower of the two points
|
||||||
|
return min(
|
||||||
|
P_GetZAt(slope, v1.x, v1.y),
|
||||||
|
P_GetZAt(slope, v2.x, v2.y)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else // Well, that makes it easy. Just get the ceiling height
|
||||||
|
#endif
|
||||||
|
return sector->ceilingheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the same as above, but for FOFs!
|
||||||
|
fixed_t P_CameraGetFOFTopZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code
|
||||||
|
{
|
||||||
|
I_Assert(mobj != NULL);
|
||||||
|
I_Assert(sector != NULL);
|
||||||
|
I_Assert(fof != NULL);
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (*fof->t_slope) {
|
||||||
|
fixed_t testx, testy;
|
||||||
|
pslope_t *slope = *fof->t_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) {
|
||||||
|
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_PointInSubsector(testx, testy)->sector == sector)
|
||||||
|
return P_GetZAt(slope, testx, testy);
|
||||||
|
|
||||||
|
// 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_GetZAt(slope, x, y);
|
||||||
|
|
||||||
|
// Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching...
|
||||||
|
// The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box
|
||||||
|
// (assuming it isn't already inside), then test each point's slope Z and return the higher of the two.
|
||||||
|
{
|
||||||
|
vertex_t v1, v2;
|
||||||
|
v1.x = line->v1->x;
|
||||||
|
v1.y = line->v1->y;
|
||||||
|
v2.x = line->v2->x;
|
||||||
|
v2.y = line->v2->y;
|
||||||
|
|
||||||
|
/*CONS_Printf("BEFORE: v1 = %f %f %f\n",
|
||||||
|
FIXED_TO_FLOAT(v1.x),
|
||||||
|
FIXED_TO_FLOAT(v1.y),
|
||||||
|
FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y))
|
||||||
|
);
|
||||||
|
CONS_Printf(" v2 = %f %f %f\n",
|
||||||
|
FIXED_TO_FLOAT(v2.x),
|
||||||
|
FIXED_TO_FLOAT(v2.y),
|
||||||
|
FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y))
|
||||||
|
);*/
|
||||||
|
|
||||||
|
if (abs(v1.x-x) > mobj->radius) {
|
||||||
|
// v1's x is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v1.x-x) - mobj->radius;
|
||||||
|
|
||||||
|
if (v1.x < x) { // Moving right
|
||||||
|
v1.x += diff;
|
||||||
|
v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
} else { // Moving left
|
||||||
|
v1.x -= diff;
|
||||||
|
v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(v1.y-y) > mobj->radius) {
|
||||||
|
// v1's y is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v1.y-y) - mobj->radius;
|
||||||
|
|
||||||
|
if (v1.y < y) { // Moving up
|
||||||
|
v1.y += diff;
|
||||||
|
v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
} else { // Moving down
|
||||||
|
v1.y -= diff;
|
||||||
|
v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(v2.x-x) > mobj->radius) {
|
||||||
|
// v1's x is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v2.x-x) - mobj->radius;
|
||||||
|
|
||||||
|
if (v2.x < x) { // Moving right
|
||||||
|
v2.x += diff;
|
||||||
|
v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
} else { // Moving left
|
||||||
|
v2.x -= diff;
|
||||||
|
v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(v2.y-y) > mobj->radius) {
|
||||||
|
// v2's y is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v2.y-y) - mobj->radius;
|
||||||
|
|
||||||
|
if (v2.y < y) { // Moving up
|
||||||
|
v2.y += diff;
|
||||||
|
v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
} else { // Moving down
|
||||||
|
v2.y -= diff;
|
||||||
|
v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*CONS_Printf("AFTER: v1 = %f %f %f\n",
|
||||||
|
FIXED_TO_FLOAT(v1.x),
|
||||||
|
FIXED_TO_FLOAT(v1.y),
|
||||||
|
FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y))
|
||||||
|
);
|
||||||
|
CONS_Printf(" v2 = %f %f %f\n",
|
||||||
|
FIXED_TO_FLOAT(v2.x),
|
||||||
|
FIXED_TO_FLOAT(v2.y),
|
||||||
|
FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y))
|
||||||
|
);*/
|
||||||
|
|
||||||
|
// Return the higher of the two points
|
||||||
|
return max(
|
||||||
|
P_GetZAt(slope, v1.x, v1.y),
|
||||||
|
P_GetZAt(slope, v2.x, v2.y)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else // Well, that makes it easy. Just get the top height
|
||||||
|
#endif
|
||||||
|
return *fof->topheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed_t P_CameraGetFOFBottomZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code
|
||||||
|
{
|
||||||
|
I_Assert(mobj != NULL);
|
||||||
|
I_Assert(sector != NULL);
|
||||||
|
I_Assert(fof != NULL);
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (*fof->b_slope) {
|
||||||
|
fixed_t testx, testy;
|
||||||
|
pslope_t *slope = *fof->b_slope;
|
||||||
|
|
||||||
|
// Get the corner of the object that should be the lowest 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) {
|
||||||
|
testx = -testx;
|
||||||
|
testy = -testy;
|
||||||
|
}
|
||||||
|
|
||||||
|
testx += x;
|
||||||
|
testy += y;
|
||||||
|
|
||||||
|
// If the lowest point is in the sector, then we have it easy! Just get the Z at that point
|
||||||
|
if (R_PointInSubsector(testx, testy)->sector == sector)
|
||||||
|
return P_GetZAt(slope, testx, testy);
|
||||||
|
|
||||||
|
// 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 higher than this
|
||||||
|
if (line == NULL)
|
||||||
|
return P_GetZAt(slope, x, y);
|
||||||
|
|
||||||
|
// Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching...
|
||||||
|
// The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box
|
||||||
|
// (assuming it isn't already inside), then test each point's slope Z and return the lower of the two.
|
||||||
|
{
|
||||||
|
vertex_t v1, v2;
|
||||||
|
v1.x = line->v1->x;
|
||||||
|
v1.y = line->v1->y;
|
||||||
|
v2.x = line->v2->x;
|
||||||
|
v2.y = line->v2->y;
|
||||||
|
|
||||||
|
if (abs(v1.x-x) > mobj->radius) {
|
||||||
|
// v1's x is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v1.x-x) - mobj->radius;
|
||||||
|
|
||||||
|
if (v1.x < x) { // Moving right
|
||||||
|
v1.x += diff;
|
||||||
|
v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
} else { // Moving left
|
||||||
|
v1.x -= diff;
|
||||||
|
v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(v1.y-y) > mobj->radius) {
|
||||||
|
// v1's y is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v1.y-y) - mobj->radius;
|
||||||
|
|
||||||
|
if (v1.y < y) { // Moving up
|
||||||
|
v1.y += diff;
|
||||||
|
v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
} else { // Moving down
|
||||||
|
v1.y -= diff;
|
||||||
|
v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(v2.x-x) > mobj->radius) {
|
||||||
|
// v1's x is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v2.x-x) - mobj->radius;
|
||||||
|
|
||||||
|
if (v2.x < x) { // Moving right
|
||||||
|
v2.x += diff;
|
||||||
|
v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
} else { // Moving left
|
||||||
|
v2.x -= diff;
|
||||||
|
v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(v2.y-y) > mobj->radius) {
|
||||||
|
// v2's y is out of range, so rein it in
|
||||||
|
fixed_t diff = abs(v2.y-y) - mobj->radius;
|
||||||
|
|
||||||
|
if (v2.y < y) { // Moving up
|
||||||
|
v2.y += diff;
|
||||||
|
v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
} else { // Moving down
|
||||||
|
v2.y -= diff;
|
||||||
|
v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the lower of the two points
|
||||||
|
return min(
|
||||||
|
P_GetZAt(slope, v1.x, v1.y),
|
||||||
|
P_GetZAt(slope, v2.x, v2.y)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else // Well, that makes it easy. Just get the bottom height
|
||||||
|
#endif
|
||||||
|
return *fof->bottomheight;
|
||||||
|
}
|
||||||
|
|
||||||
static void P_PlayerFlip(mobj_t *mo)
|
static void P_PlayerFlip(mobj_t *mo)
|
||||||
{
|
{
|
||||||
if (!mo->player)
|
if (!mo->player)
|
||||||
|
@ -3333,7 +3821,15 @@ static boolean P_CameraCheckHeat(camera_t *thiscam)
|
||||||
if (!(rover->flags & FF_EXISTS))
|
if (!(rover->flags & FF_EXISTS))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (halfheight >= *rover->topheight || halfheight <= *rover->bottomheight)
|
if (halfheight >= (
|
||||||
|
#ifdef ESLOPE
|
||||||
|
*rover->t_slope ? P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) :
|
||||||
|
#endif
|
||||||
|
*rover->topheight) || halfheight <= (
|
||||||
|
#ifdef ESLOPE
|
||||||
|
*rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) :
|
||||||
|
#endif
|
||||||
|
*rover->bottomheight))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
|
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
|
||||||
|
@ -3361,7 +3857,15 @@ static boolean P_CameraCheckWater(camera_t *thiscam)
|
||||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS)
|
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (halfheight >= *rover->topheight || halfheight <= *rover->bottomheight)
|
if (halfheight >= (
|
||||||
|
#ifdef ESLOPE
|
||||||
|
*rover->t_slope ? P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) :
|
||||||
|
#endif
|
||||||
|
*rover->topheight) || halfheight <= (
|
||||||
|
#ifdef ESLOPE
|
||||||
|
*rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) :
|
||||||
|
#endif
|
||||||
|
*rover->bottomheight))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in a new issue