Merge branch 'angles' into 'next'

Slopes and stuff

Adds support for slopes, slopes on FOFs, slopes on translucent FOFs, slopes on FOFs with holes in the flat, slope physics, dynamic slopes, vertex slopes, dynamic vertex slopes, and a ham sandwich to the game. Only for software mode right now, though. (OGL still gets the physics and the sandwich.) Some things still need to be done, but for now this can be merged in to be finished later.

Please make sure nothing in the vanilla game breaks before giving the thumbs up for this merge.

Since this doesn't merge automatically, if the code review turns out positive and nobody else has done it, I'll handle the merging.

See merge request !22
This commit is contained in:
Alam Ed Arias 2015-09-03 15:57:01 -04:00
commit 3917b02132
33 changed files with 4363 additions and 482 deletions

View file

@ -150,6 +150,7 @@ set(SRB2_CORE_GAME_SOURCES
p_saveg.c p_saveg.c
p_setup.c p_setup.c
p_sight.c p_sight.c
p_slopes.c
p_spec.c p_spec.c
p_telept.c p_telept.c
p_tick.c p_tick.c
@ -162,6 +163,7 @@ set(SRB2_CORE_GAME_SOURCES
p_pspr.h p_pspr.h
p_saveg.h p_saveg.h
p_setup.h p_setup.h
p_slopes.h
p_spec.h p_spec.h
p_tick.h p_tick.h
) )

View file

@ -454,6 +454,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/p_telept.o \ $(OBJDIR)/p_telept.o \
$(OBJDIR)/p_tick.o \ $(OBJDIR)/p_tick.o \
$(OBJDIR)/p_user.o \ $(OBJDIR)/p_user.o \
$(OBJDIR)/p_slopes.o \
$(OBJDIR)/tables.o \ $(OBJDIR)/tables.o \
$(OBJDIR)/r_bsp.o \ $(OBJDIR)/r_bsp.o \
$(OBJDIR)/r_data.o \ $(OBJDIR)/r_data.o \

View file

@ -439,6 +439,9 @@ extern const char *compdate, *comptime, *comprevision;
/// Fun experimental slope stuff! /// Fun experimental slope stuff!
//#define SLOPENESS //#define SLOPENESS
/// Kalaron/Eternity Engine slope code (SRB2CB ported)
#define ESLOPE
/// Delete file while the game is running. /// Delete file while the game is running.
/// \note EXTREMELY buggy, tends to crash game. /// \note EXTREMELY buggy, tends to crash game.
//#define DELFILE //#define DELFILE

View file

@ -982,6 +982,7 @@ static const char *credits[] = {
"", "",
"\1Programming", "\1Programming",
"\1Assistance", "\1Assistance",
"\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom)
"Andrew \"orospakr\" Clunis", "Andrew \"orospakr\" Clunis",
"Gregor \"Oogaland\" Dick", "Gregor \"Oogaland\" Dick",
"Julio \"Chaos Zero 64\" Guir", "Julio \"Chaos Zero 64\" Guir",

View file

@ -119,8 +119,6 @@ fixed_t FixedHypot(fixed_t x, fixed_t y)
return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2) return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2)
} }
#ifdef NEED_FIXED_VECTOR
vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y) vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y)
{ {
vec->x = x; vec->x = x;
@ -863,8 +861,6 @@ void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z)
#undef M #undef M
} }
#endif
#ifdef M_TESTCASE #ifdef M_TESTCASE
//#define MULDIV_TEST //#define MULDIV_TEST
#define SQRT_TEST #define SQRT_TEST

View file

@ -357,8 +357,6 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x)
return INT32_MAX; return INT32_MAX;
} }
#ifdef NEED_FIXED_VECTOR
typedef struct typedef struct
{ {
fixed_t x; fixed_t x;
@ -437,6 +435,4 @@ void FM_MultMatrix(matrix_t *dest, const matrix_t *multme);
void FM_Translate(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z); void FM_Translate(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z);
void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z); void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z);
#endif // defined NEED_FIXED_VECTOR
#endif //m_fixed.h #endif //m_fixed.h

View file

@ -5606,8 +5606,13 @@ void A_MixUp(mobj_t *actor)
P_SetThingPosition(players[i].mo); P_SetThingPosition(players[i].mo);
#ifdef ESLOPE
players[i].mo->floorz = P_GetFloorZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL);
players[i].mo->ceilingz = P_GetCeilingZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL);
#else
players[i].mo->floorz = players[i].mo->subsector->sector->floorheight; players[i].mo->floorz = players[i].mo->subsector->sector->floorheight;
players[i].mo->ceilingz = players[i].mo->subsector->sector->ceilingheight; players[i].mo->ceilingz = players[i].mo->subsector->sector->ceilingheight;
#endif
P_CheckPosition(players[i].mo, players[i].mo->x, players[i].mo->y); P_CheckPosition(players[i].mo, players[i].mo->x, players[i].mo->y);
} }

View file

@ -1174,12 +1174,15 @@ void T_SpikeSector(levelspecthink_t *spikes)
if (affectsec == spikes->sector) // Applied to an actual sector if (affectsec == spikes->sector) // Applied to an actual sector
{ {
fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, affectsec);
fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, affectsec);
if (affectsec->flags & SF_FLIPSPECIAL_FLOOR) if (affectsec->flags & SF_FLIPSPECIAL_FLOOR)
{ {
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0) if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0)
continue; continue;
if (thing->z == affectsec->floorheight) if (thing->z == affectfloor)
dothepain = true; dothepain = true;
} }
@ -1188,18 +1191,20 @@ void T_SpikeSector(levelspecthink_t *spikes)
if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0) if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0)
continue; continue;
if (thing->z + thing->height == affectsec->ceilingheight) if (thing->z + thing->height == affectceil)
dothepain = true; dothepain = true;
} }
} }
else else
{ {
fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, spikes->sector);
fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, spikes->sector);
if (affectsec->flags & SF_FLIPSPECIAL_FLOOR) if (affectsec->flags & SF_FLIPSPECIAL_FLOOR)
{ {
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0) if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0)
continue; continue;
if (thing->z == affectsec->ceilingheight) if (thing->z == affectceil)
dothepain = true; dothepain = true;
} }
@ -1208,7 +1213,7 @@ void T_SpikeSector(levelspecthink_t *spikes)
if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0) if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0)
continue; continue;
if (thing->z + thing->height == affectsec->floorheight) if (thing->z + thing->height == affectfloor)
dothepain = true; dothepain = true;
} }
} }
@ -2087,6 +2092,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
boolean FOFsector = false; boolean FOFsector = false;
boolean inAndOut = false; boolean inAndOut = false;
boolean floortouch = false; boolean floortouch = false;
fixed_t bottomheight, topheight;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
@ -2151,10 +2157,13 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
if (players[j].mo->subsector->sector != targetsec) if (players[j].mo->subsector->sector != targetsec)
continue; continue;
if (players[j].mo->z > sec->ceilingheight) topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec);
bottomheight = P_GetSpecialBottomZ(players[j].mo, sec, targetsec);
if (players[j].mo->z > topheight)
continue; continue;
if (players[j].mo->z + players[j].mo->height < sec->floorheight) if (players[j].mo->z + players[j].mo->height < bottomheight)
continue; continue;
if (floortouch == true && P_IsObjectOnGroundIn(players[j].mo, targetsec)) if (floortouch == true && P_IsObjectOnGroundIn(players[j].mo, targetsec))
@ -2314,7 +2323,7 @@ void T_RaiseSector(levelspecthink_t *raise)
if (raise->vars[1] && !(thing->player->pflags & PF_STARTDASH)) if (raise->vars[1] && !(thing->player->pflags & PF_STARTDASH))
continue; continue;
if (!(thing->z == raise->sector->ceilingheight)) if (!(thing->z == P_GetSpecialTopZ(thing, raise->sector, sector)))
continue; continue;
playeronme = true; playeronme = true;

View file

@ -217,6 +217,23 @@ boolean P_RailThinker(mobj_t *mobj);
void P_PushableThinker(mobj_t *mobj); void P_PushableThinker(mobj_t *mobj);
void P_SceneryThinker(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_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)
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);
@ -278,6 +295,11 @@ extern fixed_t tmfloorz;
extern fixed_t tmceilingz; extern fixed_t tmceilingz;
extern mobj_t *tmfloorthing, *tmhitthing, *tmthing; extern mobj_t *tmfloorthing, *tmhitthing, *tmthing;
extern camera_t *mapcampointer; extern camera_t *mapcampointer;
extern fixed_t tmx;
extern fixed_t tmy;
#ifdef ESLOPE
extern pslope_t *tmfloorslope, *tmceilingslope;
#endif
/* cphipps 2004/08/30 */ /* cphipps 2004/08/30 */
extern void P_MapStart(void); extern void P_MapStart(void);

View file

@ -27,6 +27,10 @@
#include "r_splats.h" #include "r_splats.h"
#ifdef ESLOPE
#include "p_slopes.h"
#endif
#include "z_zone.h" #include "z_zone.h"
#include "lua_hook.h" #include "lua_hook.h"
@ -34,8 +38,8 @@
fixed_t tmbbox[4]; fixed_t tmbbox[4];
mobj_t *tmthing; mobj_t *tmthing;
static INT32 tmflags; static INT32 tmflags;
static fixed_t tmx; fixed_t tmx;
static fixed_t tmy; fixed_t tmy;
static precipmobj_t *tmprecipthing; static precipmobj_t *tmprecipthing;
static fixed_t preciptmbbox[4]; static fixed_t preciptmbbox[4];
@ -48,6 +52,9 @@ fixed_t tmfloorz, tmceilingz;
static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights
mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector
mobj_t *tmhitthing; // the solid thing you bumped into (for collisions) mobj_t *tmhitthing; // the solid thing you bumped into (for collisions)
#ifdef ESLOPE
pslope_t *tmfloorslope, *tmceilingslope;
#endif
// keep track of the line that lowers the ceiling, // keep track of the line that lowers the ceiling,
// so missiles don't explode against sky hack walls // so missiles don't explode against sky hack walls
@ -957,6 +964,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->z + thing->height > tmfloorz) if (thing->z + thing->height > tmfloorz)
{ {
tmfloorz = thing->z + thing->height; tmfloorz = thing->z + thing->height;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
} }
return true; return true;
} }
@ -975,6 +985,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height) else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height)
{ {
tmceilingz = topz; tmceilingz = topz;
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
tmfloorthing = thing; // thing we may stand on tmfloorthing = thing; // thing we may stand on
} }
} }
@ -988,6 +1001,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->z < tmceilingz) if (thing->z < tmceilingz)
{ {
tmceilingz = thing->z; tmceilingz = thing->z;
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
} }
return true; return true;
} }
@ -1005,6 +1021,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (topz > tmfloorz && tmthing->z >= thing->z) else if (topz > tmfloorz && tmthing->z >= thing->z)
{ {
tmfloorz = topz; tmfloorz = topz;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
tmfloorthing = thing; // thing we may stand on tmfloorthing = thing; // thing we may stand on
} }
} }
@ -1127,11 +1146,13 @@ static boolean PIT_CheckLine(line_t *ld)
{ {
tmceilingz = opentop; tmceilingz = opentop;
ceilingline = ld; ceilingline = ld;
tmceilingslope = opentopslope;
} }
if (openbottom > tmfloorz) if (openbottom > tmfloorz)
{ {
tmfloorz = openbottom; tmfloorz = openbottom;
tmfloorslope = openbottomslope;
} }
if (highceiling > tmdrpoffceilz) if (highceiling > tmdrpoffceilz)
@ -1208,8 +1229,12 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
// 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.
tmfloorz = tmdropoffz = newsubsec->sector->floorheight; tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->floorheight;
tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight; tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight;
#ifdef ESLOPE
tmfloorslope = newsubsec->sector->f_slope;
tmceilingslope = newsubsec->sector->c_slope;
#endif
// Check list of fake floors and see if tmfloorz/tmceilingz need to be altered. // Check list of fake floors and see if tmfloorz/tmceilingz need to be altered.
if (newsubsec->sector->ffloors) if (newsubsec->sector->ffloors)
@ -1223,32 +1248,43 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (!(rover->flags & FF_EXISTS)) if (!(rover->flags & FF_EXISTS))
continue; continue;
fixed_t topheight = P_GetFOFTopZ(thing, newsubsec->sector, rover, x, y, NULL);
fixed_t bottomheight = P_GetFOFBottomZ(thing, newsubsec->sector, rover, x, y, NULL);
if (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY)) if (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY))
{ {
// If you're inside goowater and slowing down // If you're inside goowater and slowing down
fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale); fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale);
fixed_t minspeed = FixedMul(thing->info->height/9, thing->scale); fixed_t minspeed = FixedMul(thing->info->height/9, thing->scale);
if (thing->z < *rover->topheight && *rover->bottomheight < thingtop if (thing->z < topheight && bottomheight < thingtop
&& abs(thing->momz) < minspeed) && abs(thing->momz) < minspeed)
{ {
// Oh no! The object is stick in between the surface of the goo and sinklevel! help them out! // Oh no! The object is stick in between the surface of the goo and sinklevel! help them out!
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > *rover->topheight - sinklevel if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > topheight - sinklevel
&& thing->momz >= 0 && thing->momz < (minspeed>>2)) && thing->momz >= 0 && thing->momz < (minspeed>>2))
thing->momz += minspeed>>2; thing->momz += minspeed>>2;
else if (thing->eflags & MFE_VERTICALFLIP && thingtop < *rover->bottomheight + sinklevel else if (thing->eflags & MFE_VERTICALFLIP && thingtop < bottomheight + sinklevel
&& thing->momz <= 0 && thing->momz > -(minspeed>>2)) && thing->momz <= 0 && thing->momz > -(minspeed>>2))
thing->momz -= minspeed>>2; thing->momz -= minspeed>>2;
// Land on the top or the bottom, depending on gravity flip. // Land on the top or the bottom, depending on gravity flip.
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= *rover->topheight - sinklevel && thing->momz <= 0) if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= topheight - sinklevel && thing->momz <= 0)
{ {
if (tmfloorz < *rover->topheight - sinklevel) if (tmfloorz < topheight - sinklevel) {
tmfloorz = *rover->topheight - sinklevel; tmfloorz = topheight - sinklevel;
#ifdef ESLOPE
tmfloorslope = *rover->t_slope;
#endif
}
} }
else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= *rover->bottomheight + sinklevel && thing->momz >= 0) else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0)
{ {
if (tmceilingz > *rover->bottomheight + sinklevel) if (tmceilingz > bottomheight + sinklevel) {
tmceilingz = *rover->bottomheight + sinklevel; tmceilingz = bottomheight + sinklevel;
#ifdef ESLOPE
tmceilingslope = *rover->b_slope;
#endif
}
} }
} }
continue; continue;
@ -1265,30 +1301,40 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (rover->flags & FF_QUICKSAND) if (rover->flags & FF_QUICKSAND)
{ {
if (thing->z < *rover->topheight && *rover->bottomheight < thingtop) if (thing->z < topheight && bottomheight < thingtop)
{ {
if (tmfloorz < thing->z) if (tmfloorz < thing->z) {
tmfloorz = thing->z; tmfloorz = thing->z;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
}
} }
// Quicksand blocks never change heights otherwise. // Quicksand blocks never change heights otherwise.
continue; continue;
} }
delta1 = thing->z - (*rover->bottomheight delta1 = thing->z - (bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2)); + ((topheight - bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight delta2 = thingtop - (bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2)); + ((topheight - bottomheight)/2));
if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2) if (topheight > tmfloorz && abs(delta1) < abs(delta2)
&& !(rover->flags & FF_REVERSEPLATFORM)) && !(rover->flags & FF_REVERSEPLATFORM))
{ {
tmfloorz = tmdropoffz = *rover->topheight; tmfloorz = tmdropoffz = topheight;
#ifdef ESLOPE
tmfloorslope = *rover->t_slope;
#endif
} }
if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2) if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2)
&& !(rover->flags & FF_PLATFORM) && !(rover->flags & FF_PLATFORM)
&& !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))) && !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)))
{ {
tmceilingz = tmdrpoffceilz = *rover->bottomheight; tmceilingz = tmdrpoffceilz = bottomheight;
#ifdef ESLOPE
tmceilingslope = *rover->b_slope;
#endif
} }
} }
} }
@ -1361,11 +1407,19 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
delta1 = thing->z - (polybottom + ((polytop - polybottom)/2)); delta1 = thing->z - (polybottom + ((polytop - polybottom)/2));
delta2 = thingtop - (polybottom + ((polytop - polybottom)/2)); delta2 = thingtop - (polybottom + ((polytop - polybottom)/2));
if (polytop > tmfloorz && abs(delta1) < abs(delta2)) if (polytop > tmfloorz && abs(delta1) < abs(delta2)) {
tmfloorz = tmdropoffz = polytop; tmfloorz = tmdropoffz = polytop;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
}
if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) {
tmceilingz = tmdrpoffceilz = polybottom; tmceilingz = tmdrpoffceilz = polybottom;
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
}
} }
plink = (polymaplink_t *)(plink->link.next); plink = (polymaplink_t *)(plink->link.next);
} }
@ -1467,8 +1521,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.
tmfloorz = tmdropoffz = newsubsec->sector->floorheight; tmfloorz = tmdropoffz = P_CameraGetFloorZ(thiscam, newsubsec->sector, x, y, NULL);
tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight;
tmceilingz = P_CameraGetCeilingZ(thiscam, newsubsec->sector, x, y, NULL);
// 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?
@ -1497,17 +1552,20 @@ 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;
delta1 = thiscam->z - (*rover->bottomheight fixed_t topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, x, y, NULL);
+ ((*rover->topheight - *rover->bottomheight)/2)); fixed_t bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, x, y, NULL);
delta2 = thingtop - (*rover->bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2)); delta1 = thiscam->z - (bottomheight
if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2)) + ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight
+ ((topheight - bottomheight)/2));
if (topheight > tmfloorz && abs(delta1) < abs(delta2))
{ {
tmfloorz = tmdropoffz = *rover->topheight; tmfloorz = tmdropoffz = topheight;
} }
if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2)) if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2))
{ {
tmceilingz = tmdrpoffceilz = *rover->bottomheight; tmceilingz = tmdrpoffceilz = bottomheight;
} }
} }
} }
@ -1702,8 +1760,8 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
} }
else else
{ {
tmfloorz = thiscam->subsector->sector->floorheight; tmfloorz = P_CameraGetFloorZ(thiscam, thiscam->subsector->sector, x, y, NULL);
tmceilingz = thiscam->subsector->sector->ceilingheight; tmceilingz = P_CameraGetCeilingZ(thiscam, thiscam->subsector->sector, x, y, NULL);
} }
// the move is ok, // the move is ok,
@ -1769,6 +1827,10 @@ boolean PIT_PushableMoved(mobj_t *thing)
mobj_t *oldthing = tmthing; mobj_t *oldthing = tmthing;
line_t *oldceilline = ceilingline; line_t *oldceilline = ceilingline;
line_t *oldblockline = blockingline; line_t *oldblockline = blockingline;
#ifdef ESLOPE
pslope_t *oldfslope = tmfloorslope;
pslope_t *oldcslope = tmceilingslope;
#endif
// Move the player // Move the player
P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true); P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true);
@ -1781,6 +1843,10 @@ boolean PIT_PushableMoved(mobj_t *thing)
P_SetTarget(&tmthing, oldthing); P_SetTarget(&tmthing, oldthing);
ceilingline = oldceilline; ceilingline = oldceilline;
blockingline = oldblockline; blockingline = oldblockline;
#ifdef ESLOPE
tmfloorslope = oldfslope;
tmceilingslope = oldcslope;
#endif
thing->momz = stand->momz; thing->momz = stand->momz;
} }
else else
@ -1802,6 +1868,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
fixed_t tryy = thing->y; fixed_t tryy = thing->y;
fixed_t radius = thing->radius; fixed_t radius = thing->radius;
fixed_t thingtop = thing->z + thing->height; fixed_t thingtop = thing->z + thing->height;
#ifdef ESLOPE
fixed_t startingonground = P_IsObjectOnGround(thing);
#endif
floatok = false; floatok = false;
if (radius < MAXRADIUS/2) if (radius < MAXRADIUS/2)
@ -1890,13 +1959,23 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{ {
if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep) if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep)
{ {
thing->z = tmceilingz - thing->height; thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
{
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
} }
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep) else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep)
{ {
thing->z = tmfloorz; thing->z = thing->floorz = tmfloorz;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
{
thing->z = thing->floorz = tmfloorz;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
} }
@ -1967,6 +2046,25 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thing->floorz = tmfloorz; thing->floorz = tmfloorz;
thing->ceilingz = tmceilingz; thing->ceilingz = tmceilingz;
#ifdef ESLOPE
// Assign thing's standingslope if needed
if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) {
if (!startingonground && tmfloorslope)
P_HandleSlopeLanding(thing, tmfloorslope);
if (thing->momz <= 0)
thing->standingslope = tmfloorslope;
}
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) {
if (!startingonground && tmceilingslope)
P_HandleSlopeLanding(thing, tmceilingslope);
if (thing->momz >= 0)
thing->standingslope = tmceilingslope;
}
#endif
thing->x = x; thing->x = x;
thing->y = y; thing->y = y;
@ -1982,6 +2080,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y) boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
{ {
fixed_t tryx, tryy; fixed_t tryx, tryy;
tryx = thing->x; tryx = thing->x;
tryy = thing->y; tryy = thing->y;
do { do {
@ -2304,15 +2403,25 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
{ {
fixed_t platx, platy; fixed_t platx, platy;
subsector_t *glidesector; subsector_t *glidesector;
fixed_t floorz, ceilingz;
platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy);
#ifdef ESLOPE
floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight;
ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight;
#else
floorz = glidesector->sector->floorheight;
ceilingz = glidesector->sector->ceilingheight;
#endif
if (glidesector->sector != player->mo->subsector->sector) if (glidesector->sector != player->mo->subsector->sector)
{ {
boolean floorclimb = false; boolean floorclimb = false;
fixed_t topheight, bottomheight;
if (glidesector->sector->ffloors) if (glidesector->sector->ffloors)
{ {
@ -2322,34 +2431,44 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
continue; continue;
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
#ifdef ESLOPE
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y);
#endif
floorclimb = true; floorclimb = true;
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{ {
if ((*rover->topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < *rover->topheight)) if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight))
{ {
floorclimb = true; floorclimb = true;
} }
if (*rover->topheight < player->mo->z) // Waaaay below the ledge. if (topheight < player->mo->z) // Waaaay below the ledge.
{ {
floorclimb = false; floorclimb = false;
} }
if (*rover->bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale))
{ {
floorclimb = false; floorclimb = false;
} }
} }
else else
{ {
if ((*rover->bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > *rover->bottomheight)) if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight))
{ {
floorclimb = true; floorclimb = true;
} }
if (*rover->bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge.
{ {
floorclimb = false; floorclimb = false;
} }
if (*rover->topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale))
{ {
floorclimb = false; floorclimb = false;
} }
@ -2362,30 +2481,30 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{ {
if ((glidesector->sector->floorheight <= player->mo->z + player->mo->height) if ((floorz <= player->mo->z + player->mo->height)
&& ((player->mo->z + player->mo->height - player->mo->momz) <= glidesector->sector->floorheight)) && ((player->mo->z + player->mo->height - player->mo->momz) <= floorz))
floorclimb = true; floorclimb = true;
if ((glidesector->sector->floorheight > player->mo->z) if ((floorz > player->mo->z)
&& glidesector->sector->floorpic == skyflatnum) && glidesector->sector->floorpic == skyflatnum)
return false; return false;
if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > glidesector->sector->ceilingheight) if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz)
|| (player->mo->z + player->mo->height <= glidesector->sector->floorheight)) || (player->mo->z + player->mo->height <= floorz))
floorclimb = true; floorclimb = true;
} }
else else
{ {
if ((glidesector->sector->ceilingheight >= player->mo->z) if ((ceilingz >= player->mo->z)
&& ((player->mo->z - player->mo->momz) >= glidesector->sector->ceilingheight)) && ((player->mo->z - player->mo->momz) >= ceilingz))
floorclimb = true; floorclimb = true;
if ((glidesector->sector->ceilingheight < player->mo->z+player->mo->height) if ((ceilingz < player->mo->z+player->mo->height)
&& glidesector->sector->ceilingpic == skyflatnum) && glidesector->sector->ceilingpic == skyflatnum)
return false; return false;
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < glidesector->sector->floorheight) if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < ceilingz)
|| (player->mo->z >= glidesector->sector->ceilingheight)) || (player->mo->z >= ceilingz))
floorclimb = true; floorclimb = true;
} }
@ -2457,6 +2576,7 @@ isblocking:
line_t *checkline = li; line_t *checkline = li;
sector_t *checksector; sector_t *checksector;
ffloor_t *rover; ffloor_t *rover;
fixed_t topheight, bottomheight;
boolean fofline = false; boolean fofline = false;
INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li);
@ -2472,13 +2592,23 @@ isblocking:
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue; continue;
if (*rover->topheight < slidemo->z) topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
#ifdef ESLOPE
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y);
#endif
if (topheight < slidemo->z)
continue; continue;
if (*rover->bottomheight > slidemo->z + slidemo->height) if (bottomheight > slidemo->z + slidemo->height)
continue; continue;
// Got this far, so I guess it's climbable. // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this?
if (rover->master->flags & ML_TFERLINE) if (rover->master->flags & ML_TFERLINE)
{ {
size_t linenum = li-checksector->lines[0]; size_t linenum = li-checksector->lines[0];
@ -3098,6 +3228,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
if (thing->subsector->sector->ffloors && (realcrush || thing->flags & MF_PUSHABLE)) if (thing->subsector->sector->ffloors && (realcrush || thing->flags & MF_PUSHABLE))
{ {
ffloor_t *rover; ffloor_t *rover;
fixed_t topheight, bottomheight;
fixed_t delta1, delta2; fixed_t delta1, delta2;
INT32 thingtop = thing->z + thing->height; INT32 thingtop = thing->z + thing->height;
@ -3107,9 +3238,19 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
|| ((rover->flags & FF_BLOCKOTHERS) && !thing->player)) || !(rover->flags & FF_EXISTS)) || ((rover->flags & FF_BLOCKOTHERS) && !thing->player)) || !(rover->flags & FF_EXISTS))
continue; continue;
delta1 = thing->z - (*rover->bottomheight + *rover->topheight)/2; topheight = *rover->topheight;
delta2 = thingtop - (*rover->bottomheight + *rover->topheight)/2; bottomheight = *rover->bottomheight;
if (*rover->bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2))
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, thing->x, thing->y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y);
#endif*/
delta1 = thing->z - (bottomheight + topheight)/2;
delta2 = thingtop - (bottomheight + topheight)/2;
if (bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2))
{ {
if (thing->flags & MF_PUSHABLE) if (thing->flags & MF_PUSHABLE)
{ {
@ -3787,7 +3928,7 @@ void P_MapEnd(void)
} }
// P_FloorzAtPos // P_FloorzAtPos
// Returns the floorz of the XYZ position // Returns the floorz of the XYZ position // TODO: Need ceilingpos function too
// Tails 05-26-2003 // Tails 05-26-2003
fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
{ {
@ -3808,9 +3949,19 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE))) if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
continue; continue;
fixed_t topheight = *rover->topheight;
fixed_t bottomheight = *rover->bottomheight;
#ifdef ESLOPE
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, x, y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, x, y);
#endif
if (rover->flags & FF_QUICKSAND) if (rover->flags & FF_QUICKSAND)
{ {
if (z < *rover->topheight && *rover->bottomheight < thingtop) if (z < topheight && bottomheight < thingtop)
{ {
if (floorz < z) if (floorz < z)
floorz = z; floorz = z;
@ -3818,10 +3969,10 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
continue; continue;
} }
delta1 = z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); delta1 = z - (bottomheight + ((topheight - bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
if (*rover->topheight > floorz && abs(delta1) < abs(delta2)) if (topheight > floorz && abs(delta1) < abs(delta2))
floorz = *rover->topheight; floorz = topheight;
} }
} }

View file

@ -322,6 +322,9 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1)
// OPTIMIZE: keep this precalculated // OPTIMIZE: keep this precalculated
// //
fixed_t opentop, openbottom, openrange, lowfloor, highceiling; fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
#ifdef ESLOPE
pslope_t *opentopslope, *openbottomslope;
#endif
// P_CameraLineOpening // P_CameraLineOpening
// P_LineOpening, but for camera // P_LineOpening, but for camera
@ -348,31 +351,56 @@ void P_CameraLineOpening(line_t *linedef)
{ {
frontfloor = sectors[front->camsec].floorheight; frontfloor = sectors[front->camsec].floorheight;
frontceiling = sectors[front->camsec].ceilingheight; frontceiling = sectors[front->camsec].ceilingheight;
#ifdef ESLOPE
if (sectors[front->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera.x, camera.y);
if (sectors[front->camsec].c_slope)
frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera.x, camera.y);
#endif
} }
else if (front->heightsec >= 0) else if (front->heightsec >= 0)
{ {
frontfloor = sectors[front->heightsec].floorheight; frontfloor = sectors[front->heightsec].floorheight;
frontceiling = sectors[front->heightsec].ceilingheight; frontceiling = sectors[front->heightsec].ceilingheight;
#ifdef ESLOPE
if (sectors[front->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera.x, camera.y);
if (sectors[front->heightsec].c_slope)
frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera.x, camera.y);
#endif
} }
else else
{ {
frontfloor = front->floorheight; frontfloor = P_CameraGetFloorZ(mapcampointer, front, tmx, tmy, linedef);
frontceiling = front->ceilingheight; frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef);
} }
if (back->camsec >= 0) if (back->camsec >= 0)
{ {
backfloor = sectors[back->camsec].floorheight; backfloor = sectors[back->camsec].floorheight;
backceiling = sectors[back->camsec].ceilingheight; backceiling = sectors[back->camsec].ceilingheight;
#ifdef ESLOPE
if (sectors[back->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera.x, camera.y);
if (sectors[back->camsec].c_slope)
frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera.x, camera.y);
#endif
} }
else if (back->heightsec >= 0) else if (back->heightsec >= 0)
{ {
backfloor = sectors[back->heightsec].floorheight; backfloor = sectors[back->heightsec].floorheight;
backceiling = sectors[back->heightsec].ceilingheight; backceiling = sectors[back->heightsec].ceilingheight;
#ifdef ESLOPE
if (sectors[back->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera.x, camera.y);
if (sectors[back->heightsec].c_slope)
frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera.x, camera.y);
#endif
} }
else else
{ {
backfloor = back->floorheight; backfloor = P_CameraGetFloorZ(mapcampointer, back, tmx, tmy, linedef);
backceiling = back->ceilingheight; backceiling = P_CameraGetCeilingZ(mapcampointer, back, tmx, tmy, linedef);
} }
{ {
@ -417,17 +445,20 @@ 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;
delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); fixed_t topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef);
delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); fixed_t bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef);
if (*rover->bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = *rover->bottomheight;
else if (*rover->bottomheight < highestceiling && delta1 >= delta2)
highestceiling = *rover->bottomheight;
if (*rover->topheight > highestfloor && delta1 < delta2) delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
highestfloor = *rover->topheight; delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
else if (*rover->topheight > lowestfloor && delta1 < delta2) if (bottomheight < lowestceiling && delta1 >= delta2)
lowestfloor = *rover->topheight; lowestceiling = bottomheight;
else if (bottomheight < highestceiling && delta1 >= delta2)
highestceiling = bottomheight;
if (topheight > highestfloor && delta1 < delta2)
highestfloor = topheight;
else if (topheight > lowestfloor && delta1 < delta2)
lowestfloor = topheight;
} }
// Check for backsectors fake floors // Check for backsectors fake floors
@ -437,17 +468,20 @@ 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;
delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); fixed_t topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef);
delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); fixed_t bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef);
if (*rover->bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = *rover->bottomheight;
else if (*rover->bottomheight < highestceiling && delta1 >= delta2)
highestceiling = *rover->bottomheight;
if (*rover->topheight > highestfloor && delta1 < delta2) delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
highestfloor = *rover->topheight; delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
else if (*rover->topheight > lowestfloor && delta1 < delta2) if (bottomheight < lowestceiling && delta1 >= delta2)
lowestfloor = *rover->topheight; lowestceiling = bottomheight;
else if (bottomheight < highestceiling && delta1 >= delta2)
highestceiling = bottomheight;
if (topheight > highestfloor && delta1 < delta2)
highestfloor = topheight;
else if (topheight > lowestfloor && delta1 < delta2)
lowestfloor = topheight;
} }
if (highestceiling < highceiling) if (highestceiling < highceiling)
@ -495,26 +529,40 @@ void P_LineOpening(line_t *linedef)
I_Assert(front != NULL); I_Assert(front != NULL);
I_Assert(back != NULL); I_Assert(back != NULL);
if (front->ceilingheight < back->ceilingheight) { // Set open and high/low values here
{ fixed_t frontheight, backheight;
opentop = front->ceilingheight;
highceiling = back->ceilingheight;
}
else
{
opentop = back->ceilingheight;
highceiling = front->ceilingheight;
}
if (front->floorheight > back->floorheight) frontheight = P_GetCeilingZ(tmthing, front, tmx, tmy, linedef);
{ backheight = P_GetCeilingZ(tmthing, back, tmx, tmy, linedef);
openbottom = front->floorheight;
lowfloor = back->floorheight; if (frontheight < backheight)
} {
else opentop = frontheight;
{ highceiling = backheight;
openbottom = back->floorheight; opentopslope = front->c_slope;
lowfloor = front->floorheight; }
else
{
opentop = backheight;
highceiling = frontheight;
opentopslope = back->c_slope;
}
frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef);
backheight = P_GetFloorZ(tmthing, back, tmx, tmy, linedef);
if (frontheight > backheight)
{
openbottom = frontheight;
lowfloor = backheight;
openbottomslope = front->f_slope;
}
else
{
openbottom = backheight;
lowfloor = frontheight;
openbottomslope = back->f_slope;
}
} }
if (tmthing) if (tmthing)
@ -580,6 +628,10 @@ void P_LineOpening(line_t *linedef)
fixed_t highestfloor = openbottom; fixed_t highestfloor = openbottom;
fixed_t lowestfloor = lowfloor; fixed_t lowestfloor = lowfloor;
fixed_t delta1, delta2; fixed_t delta1, delta2;
#ifdef ESLOPE
pslope_t *ceilingslope = opentopslope;
pslope_t *floorslope = openbottomslope;
#endif
// Check for frontsector's fake floors // Check for frontsector's fake floors
for (rover = front->ffloors; rover; rover = rover->next) for (rover = front->ffloors; rover; rover = rover->next)
@ -593,23 +645,34 @@ void P_LineOpening(line_t *linedef)
|| (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) || (rover->flags & FF_BLOCKOTHERS && !tmthing->player)))
continue; continue;
delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); fixed_t topheight = P_GetFOFTopZ(tmthing, front, rover, tmx, tmy, linedef);
delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); fixed_t bottomheight = P_GetFOFBottomZ(tmthing, front, rover, tmx, tmy, linedef);
delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
{ {
if (*rover->bottomheight < lowestceiling) if (bottomheight < lowestceiling) {
lowestceiling = *rover->bottomheight; lowestceiling = bottomheight;
else if (*rover->bottomheight < highestceiling) #ifdef ESLOPE
highestceiling = *rover->bottomheight; ceilingslope = *rover->b_slope;
#endif
}
else if (bottomheight < highestceiling)
highestceiling = bottomheight;
} }
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
{ {
if (*rover->topheight > highestfloor) if (topheight > highestfloor) {
highestfloor = *rover->topheight; highestfloor = topheight;
else if (*rover->topheight > lowestfloor) #ifdef ESLOPE
lowestfloor = *rover->topheight; floorslope = *rover->t_slope;
#endif
}
else if (topheight > lowestfloor)
lowestfloor = topheight;
} }
} }
@ -625,23 +688,34 @@ void P_LineOpening(line_t *linedef)
|| (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) || (rover->flags & FF_BLOCKOTHERS && !tmthing->player)))
continue; continue;
delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); fixed_t topheight = P_GetFOFTopZ(tmthing, back, rover, tmx, tmy, linedef);
delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); fixed_t bottomheight = P_GetFOFBottomZ(tmthing, back, rover, tmx, tmy, linedef);
delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
{ {
if (*rover->bottomheight < lowestceiling) if (bottomheight < lowestceiling) {
lowestceiling = *rover->bottomheight; lowestceiling = bottomheight;
else if (*rover->bottomheight < highestceiling) #ifdef ESLOPE
highestceiling = *rover->bottomheight; ceilingslope = *rover->b_slope;
#endif
}
else if (bottomheight < highestceiling)
highestceiling = bottomheight;
} }
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
{ {
if (*rover->topheight > highestfloor) if (topheight > highestfloor) {
highestfloor = *rover->topheight; highestfloor = topheight;
else if (*rover->topheight > lowestfloor) #ifdef ESLOPE
lowestfloor = *rover->topheight; floorslope = *rover->t_slope;
#endif
}
else if (topheight > lowestfloor)
lowestfloor = topheight;
} }
} }
@ -653,13 +727,21 @@ void P_LineOpening(line_t *linedef)
delta1 = abs(tmthing->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); delta1 = abs(tmthing->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
if (polysec->floorheight < lowestceiling && delta1 >= delta2) if (polysec->floorheight < lowestceiling && delta1 >= delta2) {
lowestceiling = polysec->floorheight; lowestceiling = polysec->floorheight;
#ifdef ESLOPE
ceilingslope = NULL;
#endif
}
else if (polysec->floorheight < highestceiling && delta1 >= delta2) else if (polysec->floorheight < highestceiling && delta1 >= delta2)
highestceiling = polysec->floorheight; highestceiling = polysec->floorheight;
if (polysec->ceilingheight > highestfloor && delta1 < delta2) if (polysec->ceilingheight > highestfloor && delta1 < delta2) {
highestfloor = polysec->ceilingheight; highestfloor = polysec->ceilingheight;
#ifdef ESLOPE
floorslope = NULL;
#endif
}
else if (polysec->ceilingheight > lowestfloor && delta1 < delta2) else if (polysec->ceilingheight > lowestfloor && delta1 < delta2)
lowestfloor = polysec->ceilingheight; lowestfloor = polysec->ceilingheight;
} }
@ -667,11 +749,19 @@ void P_LineOpening(line_t *linedef)
if (highestceiling < highceiling) if (highestceiling < highceiling)
highceiling = highestceiling; highceiling = highestceiling;
if (highestfloor > openbottom) if (highestfloor > openbottom) {
openbottom = highestfloor; openbottom = highestfloor;
#ifdef ESLOPE
openbottomslope = floorslope;
#endif
}
if (lowestceiling < opentop) if (lowestceiling < opentop) {
opentop = lowestceiling; opentop = lowestceiling;
#ifdef ESLOPE
opentopslope = ceilingslope;
#endif
}
if (lowestfloor > lowfloor) if (lowestfloor > lowfloor)
lowfloor = lowestfloor; lowfloor = lowestfloor;
@ -769,6 +859,7 @@ void P_SetThingPosition(mobj_t *thing)
{ // link into subsector { // link into subsector
subsector_t *ss; subsector_t *ss;
sector_t *oldsec = NULL; sector_t *oldsec = NULL;
fixed_t tfloorz, tceilz;
I_Assert(thing != NULL); I_Assert(thing != NULL);
I_Assert(!P_MobjWasRemoved(thing)); I_Assert(!P_MobjWasRemoved(thing));
@ -838,12 +929,15 @@ void P_SetThingPosition(mobj_t *thing)
// sector's floor is the same height. // sector's floor is the same height.
if (thing->player && oldsec != NULL && thing->subsector && oldsec != thing->subsector->sector) if (thing->player && oldsec != NULL && thing->subsector && oldsec != thing->subsector->sector)
{ {
tfloorz = P_GetFloorZ(thing, ss->sector, thing->x, thing->y, NULL);
tceilz = P_GetCeilingZ(thing, ss->sector, thing->x, thing->y, NULL);
if (thing->eflags & MFE_VERTICALFLIP) if (thing->eflags & MFE_VERTICALFLIP)
{ {
if (thing->z + thing->height >= thing->subsector->sector->ceilingheight) if (thing->z + thing->height >= tceilz)
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
else if (thing->z <= thing->subsector->sector->floorheight) else if (thing->z <= tfloorz)
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
} }

View file

@ -55,6 +55,9 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y);
boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y); boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y);
extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
#ifdef ESLOPE
extern pslope_t *opentopslope, *openbottomslope;
#endif
void P_LineOpening(line_t *plinedef); void P_LineOpening(line_t *plinedef);

File diff suppressed because it is too large Load diff

View file

@ -354,6 +354,10 @@ typedef struct mobj_s
INT32 cusval; INT32 cusval;
INT32 cvmem; INT32 cvmem;
#ifdef ESLOPE
struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?)
#endif
// WARNING: New fields must be added separately to savegame and Lua. // WARNING: New fields must be added separately to savegame and Lua.
} mobj_t; } mobj_t;

View file

@ -30,6 +30,9 @@
#include "r_sky.h" #include "r_sky.h"
#include "p_polyobj.h" #include "p_polyobj.h"
#include "lua_script.h" #include "lua_script.h"
#ifdef ESLOPE
#include "p_slopes.h"
#endif
savedata_t savedata; savedata_t savedata;
UINT8 *save_p; UINT8 *save_p;
@ -921,7 +924,8 @@ typedef enum
MD2_EXTVAL1 = 1<<5, MD2_EXTVAL1 = 1<<5,
MD2_EXTVAL2 = 1<<6, MD2_EXTVAL2 = 1<<6,
MD2_HNEXT = 1<<7, MD2_HNEXT = 1<<7,
MD2_HPREV = 1<<8 MD2_HPREV = 1<<8,
MD2_SLOPE = 1<<9
} mobj_diff2_t; } mobj_diff2_t;
typedef enum typedef enum
@ -1109,6 +1113,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_HNEXT; diff2 |= MD2_HNEXT;
if (mobj->hprev) if (mobj->hprev)
diff2 |= MD2_HPREV; diff2 |= MD2_HPREV;
if (mobj->standingslope)
diff2 |= MD2_SLOPE;
if (diff2 != 0) if (diff2 != 0)
diff |= MD_MORE; diff |= MD_MORE;
@ -1221,6 +1227,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEUINT32(save_p, mobj->hnext->mobjnum); WRITEUINT32(save_p, mobj->hnext->mobjnum);
if (diff2 & MD2_HPREV) if (diff2 & MD2_HPREV)
WRITEUINT32(save_p, mobj->hprev->mobjnum); WRITEUINT32(save_p, mobj->hprev->mobjnum);
if (diff2 & MD2_SLOPE)
WRITEUINT16(save_p, mobj->standingslope->id);
WRITEUINT32(save_p, mobj->mobjnum); WRITEUINT32(save_p, mobj->mobjnum);
} }
@ -2068,6 +2076,9 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p); mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p);
if (diff2 & MD2_HPREV) if (diff2 & MD2_HPREV)
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
if (diff2 & MD2_SLOPE)
mobj->standingslope = P_SlopeById(READUINT16(save_p));
if (diff & MD_REDFLAG) if (diff & MD_REDFLAG)
{ {

View file

@ -72,6 +72,10 @@
#include "hardware/hw_light.h" #include "hardware/hw_light.h"
#endif #endif
#ifdef ESLOPE
#include "p_slopes.h"
#endif
// //
// Map MD5, calculated on level load. // Map MD5, calculated on level load.
// Sent to clients in PT_SERVERINFO. // Sent to clients in PT_SERVERINFO.
@ -846,7 +850,7 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
// //
// P_LoadThings // P_LoadThings
// //
static void P_LoadThings(lumpnum_t lumpnum) static void P_PrepareThings(lumpnum_t lumpnum)
{ {
size_t i; size_t i;
mapthing_t *mt; mapthing_t *mt;
@ -884,13 +888,27 @@ static void P_LoadThings(lumpnum_t lumpnum)
} }
Z_Free(datastart); Z_Free(datastart);
}
static void P_LoadThings(void)
{
size_t i;
mapthing_t *mt;
// Loading the things lump itself into memory is now handled in P_PrepareThings, above
mt = mapthings; mt = mapthings;
numhuntemeralds = 0; numhuntemeralds = 0;
for (i = 0; i < nummapthings; i++, mt++) for (i = 0; i < nummapthings; i++, mt++)
{ {
sector_t *mtsector = R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector;
// Z for objects // Z for objects
mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS) mt->z = (INT16)(
->sector->floorheight>>FRACBITS); #ifdef ESLOPE
mtsector->f_slope ? P_GetZAt(mtsector->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) :
#endif
mtsector->floorheight)>>FRACBITS;
if (mt->type == 1700 // MT_AXIS if (mt->type == 1700 // MT_AXIS
|| mt->type == 1701 // MT_AXISTRANSFER || mt->type == 1701 // MT_AXISTRANSFER
@ -2114,7 +2132,8 @@ void P_LoadThingsOnly(void)
P_LevelInitStuff(); P_LevelInitStuff();
P_LoadThings(lastloadedmaplumpnum + ML_THINGS); P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
P_LoadThings();
P_SpawnSecretItems(true); P_SpawnSecretItems(true);
} }
@ -2531,7 +2550,13 @@ boolean P_SetupLevel(boolean skipprecip)
P_MapStart(); P_MapStart();
P_LoadThings(lastloadedmaplumpnum + ML_THINGS); P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
#ifdef ESLOPE
P_ResetDynamicSlopes();
#endif
P_LoadThings();
P_SpawnSecretItems(loademblems); P_SpawnSecretItems(loademblems);

1135
src/p_slopes.c Normal file

File diff suppressed because it is too large Load diff

80
src/p_slopes.h Normal file
View file

@ -0,0 +1,80 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright(C) 2004 Stephen McGranahan
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//--------------------------------------------------------------------------
//
// DESCRIPTION:
// Slopes
// SoM created 05/10/09
//
//-----------------------------------------------------------------------------
#ifndef P_SLOPES_H__
#define P_SLOPES_H__
#ifdef ESLOPE
void P_ResetDynamicSlopes(void);
void P_RunDynamicSlopes(void);
// P_SpawnSlope_Line
// Creates one or more slopes based on the given line type and front/back
// sectors.
void P_SpawnSlope_Line(int linenum);
#ifdef SPRINGCLEAN
// Loads just map objects that make slopes,
// terrain affecting objects have to be spawned first
void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum);
typedef enum
{
THING_SlopeFloorPointLine = 9500,
THING_SlopeCeilingPointLine = 9501,
THING_SetFloorSlope = 9502,
THING_SetCeilingSlope = 9503,
THING_CopyFloorPlane = 9510,
THING_CopyCeilingPlane = 9511,
THING_VavoomFloor=1500,
THING_VavoomCeiling=1501,
THING_VertexFloorZ=1504,
THING_VertexCeilingZ=1505,
} slopething_e;
#endif
//
// P_CopySectorSlope
//
// Searches through tagged sectors and copies
//
void P_CopySectorSlope(line_t *line);
pslope_t *P_SlopeById(UINT16 id);
// Returns the height of the sloped plane at (x, y) as a fixed_t
fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y);
// Lots of physics-based bullshit
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
void P_SlopeLaunch(mobj_t *mo);
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope);
void P_ButteredSlope(mobj_t *mo);
#endif
// EOF
#endif // #ifdef ESLOPE

View file

@ -3365,6 +3365,7 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *targetsec) static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *targetsec)
{ {
ffloor_t *rover; ffloor_t *rover;
fixed_t top, bottom;
if (!mo->player) // should NEVER happen if (!mo->player) // should NEVER happen
return false; return false;
@ -3381,6 +3382,9 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
//if (!(rover->flags & FF_EXISTS)) //if (!(rover->flags & FF_EXISTS))
// return false; // return false;
top = P_GetSpecialTopZ(mo, sector, targetsec);
bottom = P_GetSpecialBottomZ(mo, sector, targetsec);
// Check the 3D floor's type... // Check the 3D floor's type...
if (rover->flags & FF_BLOCKPLAYER) if (rover->flags & FF_BLOCKPLAYER)
{ {
@ -3388,27 +3392,27 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
{ {
if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != *rover->topheight) if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != top)
return false; return false;
} }
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
{ {
if (!(mo->eflags & MFE_VERTICALFLIP) if (!(mo->eflags & MFE_VERTICALFLIP)
|| mo->z + mo->height != *rover->bottomheight) || mo->z + mo->height != bottom)
return false; return false;
} }
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
{ {
if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == *rover->bottomheight) if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottom)
|| (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == *rover->topheight))) || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == top)))
return false; return false;
} }
} }
else else
{ {
// Water and intangible FOFs // Water and intangible FOFs
if (mo->z > *rover->topheight || (mo->z + mo->height) < *rover->bottomheight) if (mo->z > top || (mo->z + mo->height) < bottom)
return false; return false;
} }
@ -3426,9 +3430,9 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
static inline boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec) static inline boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
{ {
if (mo->eflags & MFE_VERTICALFLIP) if (mo->eflags & MFE_VERTICALFLIP)
return (mo->z+mo->height == sec->ceilingheight && sec->flags & SF_FLIPSPECIAL_CEILING); return (mo->z+mo->height == P_GetSpecialTopZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_CEILING);
else else
return (mo->z == sec->floorheight && sec->flags & SF_FLIPSPECIAL_FLOOR); return (mo->z == P_GetSpecialBottomZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_FLOOR);
} }
/** Applies a sector special to a player. /** Applies a sector special to a player.
@ -4389,27 +4393,27 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
{ {
if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != *rover->topheight) if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector))
continue; continue;
} }
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
{ {
if (!(player->mo->eflags & MFE_VERTICALFLIP) if (!(player->mo->eflags & MFE_VERTICALFLIP)
|| player->mo->z + player->mo->height != *rover->bottomheight) || player->mo->z + player->mo->height != P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector))
continue; continue;
} }
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
{ {
if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == *rover->bottomheight) if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector))
|| (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == *rover->topheight))) || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector))))
continue; continue;
} }
} }
else else
{ {
// Water and DEATH FOG!!! heh // Water and DEATH FOG!!! heh
if (player->mo->z > *rover->topheight || (player->mo->z + player->mo->height) < *rover->bottomheight) if (player->mo->z > P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector) || (player->mo->z + player->mo->height) < P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector))
continue; continue;
} }
@ -4519,6 +4523,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
{ {
boolean nofloorneeded = false; boolean nofloorneeded = false;
fixed_t f_affectpoint, c_affectpoint;
if (!sector->special) // nothing special, exit if (!sector->special) // nothing special, exit
return; return;
@ -4581,16 +4586,19 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
return; return;
} }
f_affectpoint = P_GetSpecialBottomZ(player->mo, sector, sector);
c_affectpoint = P_GetSpecialTopZ(player->mo, sector, sector);
// Only go further if on the ground // Only go further if on the ground
if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != sector->floorheight) if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != f_affectpoint)
return; return;
if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != sector->ceilingheight) if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != c_affectpoint)
return; return;
if ((sector->flags & SF_FLIPSPECIAL_BOTH) if ((sector->flags & SF_FLIPSPECIAL_BOTH)
&& player->mo->z != sector->floorheight && player->mo->z != f_affectpoint
&& player->mo->z + player->mo->height != sector->ceilingheight) && player->mo->z + player->mo->height != c_affectpoint)
return; return;
P_ProcessSpecialSector(player, sector, NULL); P_ProcessSpecialSector(player, sector, NULL);
@ -4751,6 +4759,9 @@ void P_UpdateSpecials(void)
// POINT LIMIT // POINT LIMIT
P_CheckPointLimit(); P_CheckPointLimit();
// Dynamic slopeness
P_RunDynamicSlopes();
// ANIMATE TEXTURES // ANIMATE TEXTURES
for (anim = anims; anim < lastanim; anim++) for (anim = anims; anim < lastanim; anim++)
{ {
@ -4894,6 +4905,12 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
ffloor->topyoffs = &sec2->ceiling_yoffs; ffloor->topyoffs = &sec2->ceiling_yoffs;
ffloor->topangle = &sec2->ceilingpic_angle; ffloor->topangle = &sec2->ceilingpic_angle;
#ifdef ESLOPE
// Add slopes
ffloor->t_slope = &sec2->c_slope;
ffloor->b_slope = &sec2->f_slope;
#endif
if ((flags & FF_SOLID) && (master->flags & ML_EFFECT1)) // Block player only if ((flags & FF_SOLID) && (master->flags & ML_EFFECT1)) // Block player only
flags &= ~FF_BLOCKOTHERS; flags &= ~FF_BLOCKOTHERS;
@ -5327,6 +5344,7 @@ void T_LaserFlash(laserthink_t *flash)
sector_t *sourcesec; sector_t *sourcesec;
ffloor_t *ffloor = flash->ffloor; ffloor_t *ffloor = flash->ffloor;
sector_t *sector = flash->sector; sector_t *sector = flash->sector;
fixed_t top, bottom;
if (!ffloor || !(ffloor->flags & FF_EXISTS)) if (!ffloor || !(ffloor->flags & FF_EXISTS))
return; return;
@ -5350,8 +5368,11 @@ void T_LaserFlash(laserthink_t *flash)
&& thing->flags & MF_BOSS) && thing->flags & MF_BOSS)
continue; // Don't hurt bosses continue; // Don't hurt bosses
if (thing->z >= sourcesec->ceilingheight top = P_GetSpecialTopZ(thing, sourcesec, sector);
|| thing->z + thing->height <= sourcesec->floorheight) bottom = P_GetSpecialBottomZ(thing, sourcesec, sector);
if (thing->z >= top
|| thing->z + thing->height <= bottom)
continue; continue;
if (thing->flags & MF_SHOOTABLE) if (thing->flags & MF_SHOOTABLE)
@ -6430,6 +6451,14 @@ void P_SpawnSpecials(INT32 fromnetsave)
sectors[s].midmap = lines[i].frontsector->midmap; sectors[s].midmap = lines[i].frontsector->midmap;
break; break;
#ifdef ESLOPE // Slope copy specials. Handled here for sanity.
case 720:
case 721:
case 722:
P_CopySectorSlope(&lines[i]);
break;
#endif
default: default:
break; break;
} }
@ -6634,6 +6663,8 @@ void T_Scroll(scroll_t *s)
if (thing->eflags & MFE_PUSHED) // Already pushed this tic by an exclusive pusher. if (thing->eflags & MFE_PUSHED) // Already pushed this tic by an exclusive pusher.
continue; continue;
height = P_GetSpecialBottomZ(thing, sec, psec);
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped
if (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height != height)) // Thing must a) be non-floating and have z+height == height if (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height != height)) // Thing must a) be non-floating and have z+height == height
{ {
@ -6654,6 +6685,8 @@ void T_Scroll(scroll_t *s)
if (thing->eflags & MFE_PUSHED) if (thing->eflags & MFE_PUSHED)
continue; continue;
height = P_GetSpecialBottomZ(thing, sec, sec);
if (!(thing->flags & MF_NOCLIP) && if (!(thing->flags & MF_NOCLIP) &&
(!(thing->flags & MF_NOGRAVITY || thing->z > height))) (!(thing->flags & MF_NOGRAVITY || thing->z > height)))
{ {
@ -6693,6 +6726,8 @@ void T_Scroll(scroll_t *s)
if (thing->eflags & MFE_PUSHED) if (thing->eflags & MFE_PUSHED)
continue; continue;
height = P_GetSpecialTopZ(thing, sec, psec);
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped
if (!(thing->flags & MF_NOGRAVITY || thing->z != height))// Thing must a) be non-floating and have z == height if (!(thing->flags & MF_NOGRAVITY || thing->z != height))// Thing must a) be non-floating and have z == height
{ {
@ -6713,6 +6748,8 @@ void T_Scroll(scroll_t *s)
if (thing->eflags & MFE_PUSHED) if (thing->eflags & MFE_PUSHED)
continue; continue;
height = P_GetSpecialTopZ(thing, sec, sec);
if (!(thing->flags & MF_NOCLIP) && if (!(thing->flags & MF_NOCLIP) &&
(!(thing->flags & MF_NOGRAVITY || thing->z+thing->height < height))) (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height < height)))
{ {
@ -7006,7 +7043,7 @@ static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32
*/ */
void T_Friction(friction_t *f) void T_Friction(friction_t *f)
{ {
sector_t *sec; sector_t *sec, *referrer;
mobj_t *thing; mobj_t *thing;
msecnode_t *node; msecnode_t *node;
@ -7015,7 +7052,7 @@ void T_Friction(friction_t *f)
// Make sure the sector type hasn't changed // Make sure the sector type hasn't changed
if (f->roverfriction) if (f->roverfriction)
{ {
sector_t *referrer = sectors + f->referrer; referrer = sectors + f->referrer;
if (!(GETSECSPECIAL(referrer->special, 3) == 1 if (!(GETSECSPECIAL(referrer->special, 3) == 1
|| GETSECSPECIAL(referrer->special, 3) == 3)) || GETSECSPECIAL(referrer->special, 3) == 3))
@ -7047,9 +7084,7 @@ void T_Friction(friction_t *f)
{ {
if (f->roverfriction) if (f->roverfriction)
{ {
sector_t *referrer = &sectors[f->referrer]; if (thing->floorz != P_GetSpecialTopZ(thing, referrer, sec))
if (thing->floorz != referrer->ceilingheight)
{ {
node = node->m_snext; node = node->m_snext;
continue; continue;
@ -7062,7 +7097,7 @@ void T_Friction(friction_t *f)
thing->movefactor = f->movefactor; thing->movefactor = f->movefactor;
} }
} }
else if (sec->floorheight == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction? else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction?
|| f->friction < thing->friction)) || f->friction < thing->friction))
{ {
thing->friction = f->friction; thing->friction = f->friction;
@ -7336,7 +7371,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
*/ */
void T_Pusher(pusher_t *p) void T_Pusher(pusher_t *p)
{ {
sector_t *sec; sector_t *sec, *referrer;
mobj_t *thing; mobj_t *thing;
msecnode_t *node; msecnode_t *node;
INT32 xspeed = 0,yspeed = 0; INT32 xspeed = 0,yspeed = 0;
@ -7345,7 +7380,6 @@ void T_Pusher(pusher_t *p)
//INT32 ht = 0; //INT32 ht = 0;
boolean inFOF; boolean inFOF;
boolean touching; boolean touching;
boolean foundfloor = false;
boolean moved; boolean moved;
xspeed = yspeed = 0; xspeed = yspeed = 0;
@ -7357,19 +7391,16 @@ void T_Pusher(pusher_t *p)
if (p->roverpusher) if (p->roverpusher)
{ {
sector_t *referrer = &sectors[p->referrer]; referrer = &sectors[p->referrer];
if (GETSECSPECIAL(referrer->special, 3) == 2 if (!(GETSECSPECIAL(referrer->special, 3) == 2
|| GETSECSPECIAL(referrer->special, 3) == 3) || GETSECSPECIAL(referrer->special, 3) == 3))
foundfloor = true; return;
} }
else if (!(GETSECSPECIAL(sec->special, 3) == 2 else if (!(GETSECSPECIAL(sec->special, 3) == 2
|| GETSECSPECIAL(sec->special, 3) == 3)) || GETSECSPECIAL(sec->special, 3) == 3))
return; return;
if (p->roverpusher && foundfloor == false) // Not even a 3d floor has the PUSH_MASK.
return;
// For constant pushers (wind/current) there are 3 situations: // For constant pushers (wind/current) there are 3 situations:
// //
// 1) Affected Thing is above the floor. // 1) Affected Thing is above the floor.
@ -7444,41 +7475,38 @@ void T_Pusher(pusher_t *p)
// Find the area that the 'thing' is in // Find the area that the 'thing' is in
if (p->roverpusher) if (p->roverpusher)
{ {
sector_t *referrer = &sectors[p->referrer]; fixed_t top, bottom;
INT32 special;
special = GETSECSPECIAL(referrer->special, 3); top = P_GetSpecialTopZ(thing, referrer, sec);
bottom = P_GetSpecialBottomZ(thing, referrer, sec);
if (!(special == 2 || special == 3))
return;
if (thing->eflags & MFE_VERTICALFLIP) if (thing->eflags & MFE_VERTICALFLIP)
{ {
if (referrer->floorheight > thing->z + thing->height if (bottom > thing->z + thing->height
|| referrer->ceilingheight < (thing->z + (thing->height >> 1))) || top < (thing->z + (thing->height >> 1)))
continue; continue;
if (thing->z < referrer->floorheight) if (thing->z < bottom)
touching = true; touching = true;
if (thing->z + (thing->height >> 1) > referrer->floorheight) if (thing->z + (thing->height >> 1) > bottom)
inFOF = true; inFOF = true;
} }
else else
{ {
if (referrer->ceilingheight < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1))) if (top < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1)))
continue; continue;
if (thing->z + thing->height > referrer->ceilingheight) if (thing->z + thing->height > top)
touching = true; touching = true;
if (thing->z + (thing->height >> 1) < referrer->ceilingheight) if (thing->z + (thing->height >> 1) < top)
inFOF = true; inFOF = true;
} }
} }
else // Treat the entire sector as one big FOF else // Treat the entire sector as one big FOF
{ {
if (thing->z == thing->subsector->sector->floorheight) if (thing->z == P_GetSpecialBottomZ(thing, sec, sec))
touching = true; touching = true;
else if (p->type != p_current) else if (p->type != p_current)
inFOF = true; inFOF = true;

View file

@ -1212,7 +1212,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
if (mo->eflags & MFE_VERTICALFLIP) if (mo->eflags & MFE_VERTICALFLIP)
{ {
// Detect if the player is on the ceiling. // Detect if the player is on the ceiling.
if (mo->z+mo->height >= sec->ceilingheight) if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec))
return true; return true;
// Otherwise, detect if the player is on the bottom of a FOF. // Otherwise, detect if the player is on the bottom of a FOF.
else else
@ -1236,7 +1236,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
continue; continue;
// Actually check if the player is on the suitable FOF. // Actually check if the player is on the suitable FOF.
if (mo->z+mo->height == *rover->bottomheight) if (mo->z+mo->height == P_GetSpecialBottomZ(mo, sectors + rover->secnum, sec))
return true; return true;
} }
} }
@ -1245,7 +1245,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
else else
{ {
// Detect if the player is on the floor. // Detect if the player is on the floor.
if (mo->z <= sec->floorheight) if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec))
return true; return true;
// Otherwise, detect if the player is on the top of a FOF. // Otherwise, detect if the player is on the top of a FOF.
else else
@ -1269,7 +1269,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
continue; continue;
// Actually check if the player is on the suitable FOF. // Actually check if the player is on the suitable FOF.
if (mo->z == *rover->topheight) if (mo->z == P_GetSpecialTopZ(mo, sectors + rover->secnum, sec))
return true; return true;
} }
} }
@ -1789,6 +1789,9 @@ static void P_CheckBouncySectors(player_t *player)
fixed_t oldx; fixed_t oldx;
fixed_t oldy; fixed_t oldy;
fixed_t oldz; fixed_t oldz;
#ifdef ESLOPE
vector3_t momentum;
#endif
oldx = player->mo->x; oldx = player->mo->x;
oldy = player->mo->y; oldy = player->mo->y;
@ -1809,16 +1812,21 @@ static void P_CheckBouncySectors(player_t *player)
{ {
ffloor_t *rover; ffloor_t *rover;
boolean top = true; boolean top = true;
fixed_t topheight, bottomheight;
for (rover = node->m_sector->ffloors; rover; rover = rover->next) for (rover = node->m_sector->ffloors; rover; rover = rover->next)
{ {
if (player->mo->z > *rover->topheight) topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
if (player->mo->z > topheight)
continue; continue;
if (player->mo->z + player->mo->height < *rover->bottomheight) if (player->mo->z + player->mo->height < bottomheight)
continue; continue;
if (oldz < *rover->topheight && oldz > *rover->bottomheight) if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)
&& oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL))
top = false; top = false;
if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 15) if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 15)
@ -1833,7 +1841,29 @@ static void P_CheckBouncySectors(player_t *player)
{ {
fixed_t newmom; fixed_t newmom;
#ifdef ESLOPE
pslope_t *slope;
if (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) { // Hit top
slope = *rover->t_slope;
} else { // Hit bottom
slope = *rover->b_slope;
}
momentum.x = player->mo->momx;
momentum.y = player->mo->momy;
momentum.z = player->mo->momz*2;
if (slope) {
// Reverse quantizing might could use its own function later
slope->zangle = ANGLE_MAX-slope->zangle;
P_QuantizeMomentumToSlope(&momentum, slope);
slope->zangle = ANGLE_MAX-slope->zangle;
}
newmom = momentum.z = -FixedMul(momentum.z,linedist)/2;
#else
newmom = -FixedMul(player->mo->momz,linedist); newmom = -FixedMul(player->mo->momz,linedist);
#endif
if (abs(newmom) < (linedist*2)) if (abs(newmom) < (linedist*2))
{ {
@ -1856,7 +1886,18 @@ static void P_CheckBouncySectors(player_t *player)
else if (newmom < -P_GetPlayerHeight(player)/2) else if (newmom < -P_GetPlayerHeight(player)/2)
newmom = -P_GetPlayerHeight(player)/2; newmom = -P_GetPlayerHeight(player)/2;
#ifdef ESLOPE
momentum.z = newmom*2;
if (slope)
P_QuantizeMomentumToSlope(&momentum, slope);
player->mo->momx = momentum.x;
player->mo->momy = momentum.y;
player->mo->momz = momentum.z/2;
#else
player->mo->momz = newmom; player->mo->momz = newmom;
#endif
if (player->pflags & PF_SPINNING) if (player->pflags & PF_SPINNING)
{ {
@ -2280,10 +2321,23 @@ static void P_DoClimbing(player_t *player)
floorclimb = false; floorclimb = false;
boostup = false; boostup = false;
skyclimber = false; skyclimber = false;
fixed_t floorheight, ceilingheight; // ESLOPE
#ifdef ESLOPE
floorheight = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y)
: glidesector->sector->floorheight;
ceilingheight = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y)
: glidesector->sector->ceilingheight;
#else
floorheight = glidesector->sector->floorheight;
ceilingheight = glidesector->sector->ceilingheight;
#endif
if (glidesector->sector->ffloors) if (glidesector->sector->ffloors)
{ {
ffloor_t *rover; ffloor_t *rover;
fixed_t topheight, bottomheight; // ESLOPE
for (rover = glidesector->sector->ffloors; rover; rover = rover->next) for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{ {
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
@ -2291,13 +2345,21 @@ static void P_DoClimbing(player_t *player)
floorclimb = true; floorclimb = true;
#ifdef ESLOPE
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
#else
bottomheight = *rover->bottomheight;
topheight = *rover->topheight;
#endif
// Only supports rovers that are moving like an 'elevator', not just the top or bottom. // Only supports rovers that are moving like an 'elevator', not just the top or bottom.
if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42) if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42)
{ {
if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (*rover->bottomheight < player->mo->z+player->mo->height) if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (bottomheight < player->mo->z+player->mo->height)
&& (*rover->topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))) && (topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)))
|| ((player->mo->eflags & MFE_VERTICALFLIP) && (*rover->topheight > player->mo->z) || ((player->mo->eflags & MFE_VERTICALFLIP) && (topheight > player->mo->z)
&& (*rover->bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)))) && (bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))))
{ {
if (cmd->forwardmove != 0) if (cmd->forwardmove != 0)
player->mo->momz += rover->master->frontsector->floorspeed; player->mo->momz += rover->master->frontsector->floorspeed;
@ -2313,8 +2375,9 @@ static void P_DoClimbing(player_t *player)
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{ {
// Trying to climb down past the bottom of the FOF // Trying to climb down past the bottom of the FOF
if ((*rover->topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= *rover->topheight)) if ((topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= topheight))
{ {
fixed_t bottomheight2;
ffloor_t *roverbelow; ffloor_t *roverbelow;
boolean foundfof = false; boolean foundfof = false;
floorclimb = true; floorclimb = true;
@ -2329,7 +2392,13 @@ static void P_DoClimbing(player_t *player)
if (roverbelow == rover) if (roverbelow == rover)
continue; continue;
if (*roverbelow->bottomheight < *rover->topheight + FixedMul(16*FRACUNIT, player->mo->scale)) #ifdef ESLOPE
bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight;
#else
bottomheight2 = *roverbelow->bottomheight;
#endif
if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale))
foundfof = true; foundfof = true;
} }
@ -2338,7 +2407,7 @@ static void P_DoClimbing(player_t *player)
} }
// Below the FOF // Below the FOF
if (*rover->topheight <= player->mo->z) if (topheight <= player->mo->z)
{ {
floorclimb = false; floorclimb = false;
boostup = false; boostup = false;
@ -2346,7 +2415,7 @@ static void P_DoClimbing(player_t *player)
} }
// Above the FOF // Above the FOF
if (*rover->bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)) if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))
{ {
floorclimb = false; floorclimb = false;
thrust = true; thrust = true;
@ -2356,8 +2425,9 @@ static void P_DoClimbing(player_t *player)
else else
{ {
// Trying to climb down past the bottom of a FOF // Trying to climb down past the bottom of a FOF
if ((*rover->bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= *rover->bottomheight)) if ((bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= bottomheight))
{ {
fixed_t topheight2;
ffloor_t *roverbelow; ffloor_t *roverbelow;
boolean foundfof = false; boolean foundfof = false;
floorclimb = true; floorclimb = true;
@ -2372,7 +2442,13 @@ static void P_DoClimbing(player_t *player)
if (roverbelow == rover) if (roverbelow == rover)
continue; continue;
if (*roverbelow->topheight > *rover->bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) #ifdef ESLOPE
topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight;
#else
topheight2 = *roverbelow->topheight;
#endif
if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale))
foundfof = true; foundfof = true;
} }
@ -2381,7 +2457,7 @@ static void P_DoClimbing(player_t *player)
} }
// Below the FOF // Below the FOF
if (*rover->bottomheight >= player->mo->z + player->mo->height) if (bottomheight >= player->mo->z + player->mo->height)
{ {
floorclimb = false; floorclimb = false;
boostup = false; boostup = false;
@ -2389,7 +2465,7 @@ static void P_DoClimbing(player_t *player)
} }
// Above the FOF // Above the FOF
if (*rover->topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)) if (topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))
{ {
floorclimb = false; floorclimb = false;
thrust = true; thrust = true;
@ -2410,7 +2486,7 @@ static void P_DoClimbing(player_t *player)
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{ {
// Trying to climb down past the upper texture area // Trying to climb down past the upper texture area
if ((glidesector->sector->floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= glidesector->sector->floorheight)) if ((floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= floorheight))
{ {
boolean foundfof = false; boolean foundfof = false;
floorclimb = true; floorclimb = true;
@ -2418,13 +2494,20 @@ static void P_DoClimbing(player_t *player)
// Is there a FOF directly below that we can move onto? // Is there a FOF directly below that we can move onto?
if (glidesector->sector->ffloors) if (glidesector->sector->ffloors)
{ {
fixed_t bottomheight;
ffloor_t *rover; ffloor_t *rover;
for (rover = glidesector->sector->ffloors; rover; rover = rover->next) for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{ {
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue; continue;
if (*rover->bottomheight < glidesector->sector->floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) #ifdef ESLOPE
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
#else
bottomheight = *rover->bottomheight;
#endif
if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale))
{ {
foundfof = true; foundfof = true;
break; break;
@ -2437,8 +2520,8 @@ static void P_DoClimbing(player_t *player)
} }
// Reached the top of the lower texture area // Reached the top of the lower texture area
if (!floorclimb && glidesector->sector->ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) if (!floorclimb && ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)
&& (glidesector->sector->ceilingpic == skyflatnum || glidesector->sector->floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale)))) && (glidesector->sector->ceilingpic == skyflatnum || floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale))))
{ {
thrust = true; thrust = true;
boostup = true; boostup = true;
@ -2448,7 +2531,7 @@ static void P_DoClimbing(player_t *player)
else else
{ {
// Trying to climb down past the upper texture area // Trying to climb down past the upper texture area
if ((glidesector->sector->ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= glidesector->sector->ceilingheight)) if ((ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= ceilingheight))
{ {
boolean foundfof = false; boolean foundfof = false;
floorclimb = true; floorclimb = true;
@ -2462,7 +2545,7 @@ static void P_DoClimbing(player_t *player)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue; continue;
if (*rover->topheight > glidesector->sector->ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) if (*rover->topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
{ {
foundfof = true; foundfof = true;
break; break;
@ -2475,7 +2558,7 @@ static void P_DoClimbing(player_t *player)
} }
// Allow climbing from a FOF or lower texture onto the upper texture and vice versa. // Allow climbing from a FOF or lower texture onto the upper texture and vice versa.
if (player->mo->z > glidesector->sector->ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) if (player->mo->z > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
{ {
floorclimb = true; floorclimb = true;
thrust = false; thrust = false;
@ -2483,8 +2566,8 @@ static void P_DoClimbing(player_t *player)
} }
// Reached the top of the lower texture area // Reached the top of the lower texture area
if (!floorclimb && glidesector->sector->floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) if (!floorclimb && floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)
&& (glidesector->sector->ceilingpic == skyflatnum || glidesector->sector->ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale)))) && (glidesector->sector->ceilingpic == skyflatnum || ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale))))
{ {
thrust = true; thrust = true;
boostup = true; boostup = true;
@ -2493,14 +2576,14 @@ static void P_DoClimbing(player_t *player)
} }
// Trying to climb on the sky // Trying to climb on the sky
if ((glidesector->sector->ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum) if ((ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum)
{ {
skyclimber = true; skyclimber = true;
} }
// Climbing on the lower texture area? // Climbing on the lower texture area?
if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < glidesector->sector->floorheight) if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < floorheight)
|| ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= glidesector->sector->floorheight)) || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= floorheight))
{ {
floorclimb = true; floorclimb = true;
@ -2516,8 +2599,8 @@ static void P_DoClimbing(player_t *player)
} }
} }
// Climbing on the upper texture area? // Climbing on the upper texture area?
else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= glidesector->sector->ceilingheight) else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= ceilingheight)
|| ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > glidesector->sector->ceilingheight)) || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > ceilingheight))
{ {
floorclimb = true; floorclimb = true;
@ -3688,7 +3771,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SLIDING) && !player->exiting if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SLIDING) && !player->exiting
&& !P_PlayerInPain(player)) // subsequent revs && !P_PlayerInPain(player)) // subsequent revs
{ {
if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<<FRACBITS, player->mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<<FRACBITS, player->mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)
#ifdef ESLOPE
&& (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
#endif
)
{ {
player->mo->momx = player->cmomx; player->mo->momx = player->cmomx;
player->mo->momy = player->cmomy; player->mo->momy = player->cmomy;
@ -3717,7 +3804,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
// down the spin button and not spinning. // down the spin button and not spinning.
// AKA Just go into a spin on the ground, you idiot. ;) // AKA Just go into a spin on the ground, you idiot. ;)
else if ((cmd->buttons & BT_USE || ((twodlevel || (player->mo->flags2 & MF2_TWOD)) && cmd->forwardmove < -20)) else if ((cmd->buttons & BT_USE || ((twodlevel || (player->mo->flags2 & MF2_TWOD)) && cmd->forwardmove < -20))
&& !player->climbing && !player->mo->momz && onground && player->speed > FixedMul(5<<FRACBITS, player->mo->scale) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) && !player->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<<FRACBITS, player->mo->scale)
#ifdef ESLOPE
|| (player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)
#endif
) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING))
{ {
player->pflags |= PF_SPINNING; player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
@ -3729,7 +3820,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
// Rolling normally // Rolling normally
if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH) if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH)
&& player->speed < FixedMul(5*FRACUNIT,player->mo->scale)) && player->speed < FixedMul(5*FRACUNIT,player->mo->scale)
#ifdef ESLOPE
&& (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
#endif
)
{ {
if (GETSECSPECIAL(player->mo->subsector->sector->special, 4) == 7 || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player))) if (GETSECSPECIAL(player->mo->subsector->sector->special, 4) == 7 || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player)))
P_InstaThrust(player->mo, player->mo->angle, FixedMul(10*FRACUNIT, player->mo->scale)); P_InstaThrust(player->mo, player->mo->angle, FixedMul(10*FRACUNIT, player->mo->scale));
@ -4433,12 +4528,16 @@ static void P_3dMovement(player_t *player)
angle_t dangle; // replaces old quadrants bits angle_t dangle; // replaces old quadrants bits
fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale); fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale);
boolean analogmove = false; boolean analogmove = false;
#ifndef OLD_MOVEMENT_CODE
fixed_t oldMagnitude, newMagnitude; fixed_t oldMagnitude, newMagnitude;
#ifdef ESLOPE
vector3_t totalthrust;
totalthrust.x = totalthrust.y = 0; // I forget if this is needed
totalthrust.z = FRACUNIT*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes
#endif // ESLOPE
// Get the old momentum; this will be needed at the end of the function! -SH // Get the old momentum; this will be needed at the end of the function! -SH
oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
#endif
analogmove = P_AnalogMove(player); analogmove = P_AnalogMove(player);
@ -4615,17 +4714,10 @@ static void P_3dMovement(player_t *player)
} }
movepushforward = FixedMul(movepushforward, player->mo->scale); movepushforward = FixedMul(movepushforward, player->mo->scale);
#ifdef OLD_MOVEMENT_CODE
if (player->speed < topspeed && mforward && cmd->forwardmove > 0) // Sonic's Speed #ifdef ESLOPE
P_Thrust(player->mo, movepushangle, movepushforward); totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward);
else if (mforward && cmd->forwardmove < 0) totalthrust.y += P_ReturnThrustY(player->mo, movepushangle, movepushforward);
P_Thrust(player->mo, movepushangle, movepushforward);
else if (player->speed < topspeed && mbackward && cmd->forwardmove < 0)
P_Thrust(player->mo, movepushangle, movepushforward);
else if (mbackward && cmd->forwardmove > 0)
P_Thrust(player->mo, movepushangle, movepushforward);
else if (!mforward && !mbackward)
P_Thrust(player->mo, movepushangle, movepushforward);
#else #else
P_Thrust(player->mo, movepushangle, movepushforward); P_Thrust(player->mo, movepushangle, movepushforward);
#endif #endif
@ -4644,33 +4736,12 @@ static void P_3dMovement(player_t *player)
if (!(player->pflags & PF_GLIDING || player->exiting || P_PlayerInPain(player))) if (!(player->pflags & PF_GLIDING || player->exiting || P_PlayerInPain(player)))
{ {
angle_t controldirection; angle_t controldirection;
#ifdef OLD_MOVEMENT_CODE
angle_t controlplayerdirection;
boolean cforward; // controls pointing forward from the player
boolean cbackward; // controls pointing backward from the player
angle_t dangle;
cforward = cbackward = false;
#endif
// Calculate the angle at which the controls are pointing // Calculate the angle at which the controls are pointing
// to figure out the proper mforward and mbackward. // to figure out the proper mforward and mbackward.
// (Why was it so complicated before? ~Red) // (Why was it so complicated before? ~Red)
controldirection = R_PointToAngle2(0, 0, cmd->forwardmove*FRACUNIT, -cmd->sidemove*FRACUNIT)+movepushangle; controldirection = R_PointToAngle2(0, 0, cmd->forwardmove*FRACUNIT, -cmd->sidemove*FRACUNIT)+movepushangle;
#ifdef OLD_MOVEMENT_CODE
controlplayerdirection = player->mo->angle;
dangle = controldirection - controlplayerdirection;
if (dangle > ANGLE_180) //flip to keep to one side
dangle = InvAngle(dangle);
if (dangle > ANGLE_90)
cbackward = true; // Controls pointing backwards from player
else
cforward = true; // Controls pointing in player's general direction
#endif
movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration); movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration);
// allow very small movement while in air for gameplay // allow very small movement while in air for gameplay
@ -4693,13 +4764,10 @@ static void P_3dMovement(player_t *player)
movepushsideangle = controldirection; movepushsideangle = controldirection;
movepushforward = FixedMul(movepushforward, player->mo->scale); movepushforward = FixedMul(movepushforward, player->mo->scale);
#ifdef OLD_MOVEMENT_CODE
if (player->speed < topspeed) #ifdef ESLOPE
P_Thrust(player->mo, controldirection, movepushforward); totalthrust.x += P_ReturnThrustX(player->mo, controldirection, movepushforward);
else if ((mforward) && (cbackward)) totalthrust.y += P_ReturnThrustY(player->mo, controldirection, movepushforward);
P_Thrust(player->mo, controldirection, movepushforward);
else if ((mbackward) && (cforward))
P_Thrust(player->mo, controldirection, movepushforward);
#else #else
P_Thrust(player->mo, controldirection, movepushforward); P_Thrust(player->mo, controldirection, movepushforward);
#endif #endif
@ -4707,29 +4775,6 @@ static void P_3dMovement(player_t *player)
} }
else if (cmd->sidemove && !(player->pflags & PF_GLIDING) && !player->exiting && !P_PlayerInPain(player)) else if (cmd->sidemove && !(player->pflags & PF_GLIDING) && !player->exiting && !P_PlayerInPain(player))
{ {
#ifdef OLD_MOVEMENT_CODE
boolean mright = 0;
boolean mleft = 0;
angle_t sideangle;
sideangle = player->mo->angle - ANGLE_90;
// Monster Iestyn - 04-11-13
// Quadrants are stupid, excessive and broken, let's do this a much simpler way!
// Get delta angle from rmom angle and player angle first
dangle = R_PointToAngle2(0,0, player->rmomx, player->rmomy) - sideangle;
if (dangle > ANGLE_180)
dangle = InvAngle(dangle);
// now use it to determine direction!
if (dangle <= ANGLE_45) // angles 0-45 or 315-360
mright = 1; // going right
else if (dangle >= ANGLE_135) // angles 135-225
mleft = 1; // going left
// anything else will leave both at 0, so no need to do anything else
#endif
movepushside = cmd->sidemove * (thrustfactor * acceleration); movepushside = cmd->sidemove * (thrustfactor * acceleration);
if (!onground) if (!onground)
@ -4752,19 +4797,37 @@ static void P_3dMovement(player_t *player)
// Finally move the player now that his speed/direction has been decided. // Finally move the player now that his speed/direction has been decided.
movepushside = FixedMul(movepushside, player->mo->scale); movepushside = FixedMul(movepushside, player->mo->scale);
#ifdef OLD_MOVEMENT_CODE
if (player->speed < topspeed) #ifdef ESLOPE
P_Thrust(player->mo, movepushsideangle, movepushside); totalthrust.x += P_ReturnThrustX(player->mo, movepushsideangle, movepushside);
else if (mright && cmd->sidemove < 0) totalthrust.y += P_ReturnThrustY(player->mo, movepushsideangle, movepushside);
P_Thrust(player->mo, movepushsideangle, movepushside);
else if (mleft && cmd->sidemove > 0)
P_Thrust(player->mo, movepushsideangle, movepushside);
#else #else
P_Thrust(player->mo, movepushsideangle, movepushside); P_Thrust(player->mo, movepushsideangle, movepushside);
#endif #endif
} }
#ifndef OLD_MOVEMENT_CODE #ifdef ESLOPE
if ((totalthrust.x || totalthrust.y)
&& player->mo->standingslope && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) {
// Factor thrust to slope, but only for the part pushing up it!
// The rest is unaffected.
angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection;
if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face toward
if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270) {
P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope);
}
} else { // Direction goes up, so thrustangle needs to face away
if (thrustangle > ANGLE_90 && thrustangle < ANGLE_270) {
P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope);
}
}
}
player->mo->momx += totalthrust.x;
player->mo->momy += totalthrust.y;
#endif
// Time to ask three questions: // Time to ask three questions:
// 1) Are we over topspeed? // 1) Are we over topspeed?
// 2) If "yes" to 1, were we moving over topspeed to begin with? // 2) If "yes" to 1, were we moving over topspeed to begin with?
@ -4798,7 +4861,6 @@ static void P_3dMovement(player_t *player)
player->mo->momy = tempmomy + player->cmomy; player->mo->momy = tempmomy + player->cmomy;
} }
} }
#endif
} }
// //

View file

@ -459,6 +459,11 @@ static void R_AddLine(seg_t *line)
doorclosed = 0; doorclosed = 0;
// Closed door. // Closed door.
#ifdef ESLOPE
// Just don't bother checking this if one side is sloped. This is probably inefficient, but it's better than
// random renderer stopping around slopes...
if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope))
#endif
if (backsector->ceilingheight <= frontsector->floorheight if (backsector->ceilingheight <= frontsector->floorheight
|| backsector->floorheight >= frontsector->ceilingheight) || backsector->floorheight >= frontsector->ceilingheight)
{ {
@ -487,6 +492,10 @@ static void R_AddLine(seg_t *line)
#endif #endif
backsector->ceilingpic == frontsector->ceilingpic backsector->ceilingpic == frontsector->ceilingpic
&& backsector->floorpic == frontsector->floorpic && backsector->floorpic == frontsector->floorpic
#ifdef ESLOPE
&& backsector->f_slope == frontsector->f_slope
&& backsector->c_slope == frontsector->c_slope
#endif
&& backsector->lightlevel == frontsector->lightlevel && backsector->lightlevel == frontsector->lightlevel
&& !curline->sidedef->midtexture && !curline->sidedef->midtexture
// Check offsets too! // Check offsets too!
@ -842,11 +851,19 @@ static void R_Subsector(size_t num)
sub->sector->moved = frontsector->moved = false; sub->sector->moved = frontsector->moved = false;
} }
light = R_GetPlaneLight(frontsector, frontsector->floorheight, false); light = R_GetPlaneLight(frontsector,
#ifdef ESLOPE
frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
frontsector->floorheight, false);
if (frontsector->floorlightsec == -1) if (frontsector->floorlightsec == -1)
floorlightlevel = *frontsector->lightlist[light].lightlevel; floorlightlevel = *frontsector->lightlist[light].lightlevel;
floorcolormap = frontsector->lightlist[light].extra_colormap; floorcolormap = frontsector->lightlist[light].extra_colormap;
light = R_GetPlaneLight(frontsector, frontsector->ceilingheight, false); light = R_GetPlaneLight(frontsector,
#ifdef ESLOPE
frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
frontsector->ceilingheight, false);
if (frontsector->ceilinglightsec == -1) if (frontsector->ceilinglightsec == -1)
ceilinglightlevel = *frontsector->lightlist[light].lightlevel; ceilinglightlevel = *frontsector->lightlist[light].lightlevel;
ceilingcolormap = frontsector->lightlist[light].extra_colormap; ceilingcolormap = frontsector->lightlist[light].extra_colormap;
@ -854,32 +871,52 @@ static void R_Subsector(size_t num)
sub->sector->extra_colormap = frontsector->extra_colormap; sub->sector->extra_colormap = frontsector->extra_colormap;
if ((frontsector->floorheight < viewz || (frontsector->heightsec != -1 if (((
#ifdef ESLOPE
frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) :
#endif
frontsector->floorheight) < viewz || (frontsector->heightsec != -1
&& sectors[frontsector->heightsec].ceilingpic == skyflatnum))) && sectors[frontsector->heightsec].ceilingpic == skyflatnum)))
{ {
floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel,
frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL); frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL
#ifdef ESLOPE
, frontsector->f_slope
#endif
);
} }
else else
floorplane = NULL; floorplane = NULL;
if ((frontsector->ceilingheight > viewz || frontsector->ceilingpic == skyflatnum if (((
#ifdef ESLOPE
frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) :
#endif
frontsector->ceilingheight) > viewz || frontsector->ceilingpic == skyflatnum
|| (frontsector->heightsec != -1 || (frontsector->heightsec != -1
&& sectors[frontsector->heightsec].floorpic == skyflatnum))) && sectors[frontsector->heightsec].floorpic == skyflatnum)))
{ {
ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic,
ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle,
ceilingcolormap, NULL); ceilingcolormap, NULL
#ifdef ESLOPE
, frontsector->c_slope
#endif
);
} }
else else
ceilingplane = NULL; ceilingplane = NULL;
numffloors = 0; numffloors = 0;
#ifdef ESLOPE
ffloor[numffloors].slope = NULL;
#endif
ffloor[numffloors].plane = NULL; ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL; ffloor[numffloors].polyobj = NULL;
if (frontsector->ffloors) if (frontsector->ffloors)
{ {
ffloor_t *rover; ffloor_t *rover;
fixed_t heightcheck;
for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next) for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next)
{ {
@ -897,18 +934,47 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = NULL; ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL; ffloor[numffloors].polyobj = NULL;
heightcheck =
#ifdef ESLOPE
*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) :
#endif
*rover->bottomheight;
if (*rover->bottomheight <= frontsector->ceilingheight if (*rover->bottomheight <= frontsector->ceilingheight
&& *rover->bottomheight >= frontsector->floorheight && *rover->bottomheight >= frontsector->floorheight
&& ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) && ((viewz < heightcheck && !(rover->flags & FF_INVERTPLANES))
|| (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) || (viewz > heightcheck && (rover->flags & FF_BOTHPLANES))))
{ {
#ifdef ESLOPE
light = R_GetPlaneLight(frontsector,
*rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->bottomheight,
viewz < heightcheck);
#else
light = R_GetPlaneLight(frontsector, *rover->bottomheight, light = R_GetPlaneLight(frontsector, *rover->bottomheight,
viewz < *rover->bottomheight); viewz < *rover->bottomheight);
#endif
ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
*rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover); *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover
#ifdef ESLOPE
, *rover->b_slope
#endif
);
#ifdef ESLOPE
ffloor[numffloors].slope = *rover->b_slope;
// Tell the renderer this sector has slopes in it.
if (ffloor[numffloors].slope)
frontsector->hasslope = true;
#endif
ffloor[numffloors].height =
#ifdef ESLOPE
*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) :
#endif
*rover->bottomheight;
ffloor[numffloors].height = *rover->bottomheight;
ffloor[numffloors].ffloor = rover; ffloor[numffloors].ffloor = rover;
numffloors++; numffloors++;
} }
@ -916,16 +982,46 @@ static void R_Subsector(size_t num)
break; break;
ffloor[numffloors].plane = NULL; ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL; ffloor[numffloors].polyobj = NULL;
heightcheck =
#ifdef ESLOPE
*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) :
#endif
*rover->topheight;
if (*rover->topheight >= frontsector->floorheight if (*rover->topheight >= frontsector->floorheight
&& *rover->topheight <= frontsector->ceilingheight && *rover->topheight <= frontsector->ceilingheight
&& ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) && ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES))
|| (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) || (viewz < heightcheck && (rover->flags & FF_BOTHPLANES))))
{ {
#ifdef ESLOPE
light = R_GetPlaneLight(frontsector,
*rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->topheight,
viewz < heightcheck);
#else
light = R_GetPlaneLight(frontsector, *rover->topheight, viewz < *rover->topheight); light = R_GetPlaneLight(frontsector, *rover->topheight, viewz < *rover->topheight);
#endif
ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
frontsector->lightlist[light].extra_colormap, rover); frontsector->lightlist[light].extra_colormap, rover
ffloor[numffloors].height = *rover->topheight; #ifdef ESLOPE
, *rover->t_slope
#endif
);
#ifdef ESLOPE
ffloor[numffloors].slope = *rover->t_slope;
// Tell the renderer this sector has slopes in it.
if (ffloor[numffloors].slope)
frontsector->hasslope = true;
#endif
ffloor[numffloors].height =
#ifdef ESLOPE
*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) :
#endif
*rover->topheight;
ffloor[numffloors].ffloor = rover; ffloor[numffloors].ffloor = rover;
numffloors++; numffloors++;
} }
@ -977,11 +1073,18 @@ static void R_Subsector(size_t num)
polysec->lightlevel, xoff, yoff, polysec->lightlevel, xoff, yoff,
polysec->floorpic_angle-po->angle, polysec->floorpic_angle-po->angle,
NULL, NULL,
NULL); NULL
#ifdef ESLOPE
, NULL // will ffloors be slopable eventually?
#endif
);
//ffloor[numffloors].plane->polyobj = po; //ffloor[numffloors].plane->polyobj = po;
ffloor[numffloors].height = polysec->floorheight; ffloor[numffloors].height = polysec->floorheight;
ffloor[numffloors].polyobj = po; ffloor[numffloors].polyobj = po;
#ifdef ESLOPE
ffloor[numffloors].slope = NULL;
#endif
// ffloor[numffloors].ffloor = rover; // ffloor[numffloors].ffloor = rover;
po->visplane = ffloor[numffloors].plane; po->visplane = ffloor[numffloors].plane;
numffloors++; numffloors++;
@ -1014,11 +1117,18 @@ static void R_Subsector(size_t num)
light = 0; light = 0;
ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic,
polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle, polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle,
NULL, NULL); NULL, NULL
#ifdef ESLOPE
, NULL // will ffloors be slopable eventually?
#endif
);
//ffloor[numffloors].plane->polyobj = po; //ffloor[numffloors].plane->polyobj = po;
ffloor[numffloors].polyobj = po; ffloor[numffloors].polyobj = po;
ffloor[numffloors].height = polysec->ceilingheight; ffloor[numffloors].height = polysec->ceilingheight;
#ifdef ESLOPE
ffloor[numffloors].slope = NULL;
#endif
// ffloor[numffloors].ffloor = rover; // ffloor[numffloors].ffloor = rover;
po->visplane = ffloor[numffloors].plane; po->visplane = ffloor[numffloors].plane;
numffloors++; numffloors++;
@ -1077,6 +1187,11 @@ void R_Prep3DFloors(sector_t *sector)
fixed_t bestheight, maxheight; fixed_t bestheight, maxheight;
INT32 count, i, mapnum; INT32 count, i, mapnum;
sector_t *sec; sector_t *sec;
#ifdef ESLOPE
pslope_t *bestslope;
fixed_t heighttest; // I think it's better to check the Z height at the sector's center
// than assume unsloped heights are accurate indicators of order in sloped sectors. -Red
#endif
count = 1; count = 1;
for (rover = sector->ffloors; rover; rover = rover->next) for (rover = sector->ffloors; rover; rover = rover->next)
@ -1099,7 +1214,14 @@ void R_Prep3DFloors(sector_t *sector)
else else
memset(sector->lightlist, 0, sizeof (lightlist_t) * count); memset(sector->lightlist, 0, sizeof (lightlist_t) * count);
#ifdef ESLOPE
heighttest = sector->c_slope ? P_GetZAt(sector->c_slope, sector->soundorg.x, sector->soundorg.y) : sector->ceilingheight;
sector->lightlist[0].height = heighttest + 1;
sector->lightlist[0].slope = sector->c_slope;
#else
sector->lightlist[0].height = sector->ceilingheight + 1; sector->lightlist[0].height = sector->ceilingheight + 1;
#endif
sector->lightlist[0].lightlevel = &sector->lightlevel; sector->lightlist[0].lightlevel = &sector->lightlevel;
sector->lightlist[0].caster = NULL; sector->lightlist[0].caster = NULL;
sector->lightlist[0].extra_colormap = sector->extra_colormap; sector->lightlist[0].extra_colormap = sector->extra_colormap;
@ -1117,6 +1239,29 @@ void R_Prep3DFloors(sector_t *sector)
&& !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES))) && !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES)))
continue; continue;
#ifdef ESLOPE
heighttest = *rover->t_slope ? P_GetZAt(*rover->t_slope, sector->soundorg.x, sector->soundorg.y) : *rover->topheight;
if (heighttest > bestheight && heighttest < maxheight)
{
best = rover;
bestheight = heighttest;
bestslope = *rover->t_slope;
continue;
}
if (rover->flags & FF_DOUBLESHADOW) {
heighttest = *rover->b_slope ? P_GetZAt(*rover->b_slope, sector->soundorg.x, sector->soundorg.y) : *rover->bottomheight;
if (heighttest > bestheight
&& heighttest < maxheight)
{
best = rover;
bestheight = heighttest;
bestslope = *rover->b_slope;
continue;
}
}
#else
if (*rover->topheight > bestheight && *rover->topheight < maxheight) if (*rover->topheight > bestheight && *rover->topheight < maxheight)
{ {
best = rover; best = rover;
@ -1130,6 +1275,7 @@ void R_Prep3DFloors(sector_t *sector)
bestheight = *rover->bottomheight; bestheight = *rover->bottomheight;
continue; continue;
} }
#endif
} }
if (!best) if (!best)
{ {
@ -1140,6 +1286,9 @@ void R_Prep3DFloors(sector_t *sector)
sector->lightlist[i].height = maxheight = bestheight; sector->lightlist[i].height = maxheight = bestheight;
sector->lightlist[i].caster = best; sector->lightlist[i].caster = best;
sector->lightlist[i].flags = best->flags; sector->lightlist[i].flags = best->flags;
#ifdef ESLOPE
sector->lightlist[i].slope = bestslope;
#endif
sec = &sectors[best->secnum]; sec = &sectors[best->secnum];
mapnum = sec->midmap; mapnum = sec->midmap;
if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps) if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps)
@ -1165,7 +1314,12 @@ void R_Prep3DFloors(sector_t *sector)
if (best->flags & FF_DOUBLESHADOW) if (best->flags & FF_DOUBLESHADOW)
{ {
#ifdef ESLOPE
heighttest = *best->b_slope ? P_GetZAt(*best->b_slope, sector->soundorg.x, sector->soundorg.y) : *best->bottomheight;
if (bestheight == heighttest) ///TODO: do this in a more efficient way -Red
#else
if (bestheight == *best->bottomheight) if (bestheight == *best->bottomheight)
#endif
{ {
sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel; sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel;
sector->lightlist[i].extra_colormap = sector->lightlist[i].extra_colormap =

View file

@ -155,6 +155,12 @@ typedef struct ffloor_s
fixed_t *bottomyoffs; fixed_t *bottomyoffs;
angle_t *bottomangle; angle_t *bottomangle;
#ifdef ESLOPE
// Pointers to pointers. Yup.
struct pslope_s **t_slope;
struct pslope_s **b_slope;
#endif
size_t secnum; size_t secnum;
ffloortype_e flags; ffloortype_e flags;
struct line_s *master; struct line_s *master;
@ -184,6 +190,9 @@ typedef struct lightlist_s
extracolormap_t *extra_colormap; extracolormap_t *extra_colormap;
INT32 flags; INT32 flags;
ffloor_t *caster; ffloor_t *caster;
#ifdef ESLOPE
struct pslope_s *slope; // FF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh.
#endif
} lightlist_t; } lightlist_t;
@ -224,6 +233,52 @@ typedef struct secplane_t
fixed_t a, b, c, d, ic; fixed_t a, b, c, d, ic;
} secplane_t; } secplane_t;
// Slopes
#ifdef ESLOPE
typedef enum {
SL_NOPHYSICS = 1, // Don't do momentum adjustment with this slope
SL_NODYNAMIC = 1<<1, // Slope will never need to move during the level, so don't fuss with recalculating it
SL_ANCHORVERTEX = 1<<2, // Slope is using a Slope Vertex Thing to anchor its position
SL_VERTEXSLOPE = 1<<3, // Slope is built from three Slope Vertex Things
} slopeflags_t;
typedef struct pslope_s
{
UINT16 id; // The number of the slope, mostly used for netgame syncing purposes
// --- Information used in clipping/projection ---
// Origin vector for the plane
vector3_t o;
// 2-Dimentional vector (x, y) normalized. Used to determine distance from
// the origin in 2d mapspace. (Basically a thrust of FRACUNIT in xydirection angle)
vector2_t d;
// The rate at which z changes based on distance from the origin plane.
fixed_t zdelta;
// The normal of the slope; will always point upward, and thus be inverted on ceilings. I think it's only needed for physics? -Red
vector3_t normal;
// For comparing when a slope should be rendered
fixed_t lowz;
fixed_t highz;
// This values only check and must be updated if the slope itself is modified
angle_t zangle; // Angle of the plane going up from the ground (not mesured in degrees)
angle_t xydirection; // The direction the slope is facing (north, west, south, etc.)
struct line_s *sourceline; // The line that generated the slope
fixed_t extent; // Distance value used for recalculating zdelta
UINT8 refpos; // 1=front floor 2=front ceiling 3=back floor 4=back ceiling (used for dynamic sloping)
UINT8 flags; // Slope options
mapthing_t **vertices; // List should be three long for slopes made by vertex things, or one long for slopes using one vertex thing to anchor
struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later
} pslope_t;
#endif
typedef enum typedef enum
{ {
SF_FLIPSPECIAL_FLOOR = 1, SF_FLIPSPECIAL_FLOOR = 1,
@ -337,6 +392,13 @@ typedef struct sector_s
precipmobj_t *preciplist; precipmobj_t *preciplist;
struct mprecipsecnode_s *touching_preciplist; struct mprecipsecnode_s *touching_preciplist;
#ifdef ESLOPE
// Eternity engine slope
pslope_t *f_slope; // floor slope
pslope_t *c_slope; // ceiling slope
boolean hasslope; // The sector, or one of its visible FOFs, contains a slope
#endif
// these are saved for netgames, so do not let Lua touch these! // these are saved for netgames, so do not let Lua touch these!
// offsets sector spawned with (via linedef type 7) // offsets sector spawned with (via linedef type 7)
@ -612,6 +674,12 @@ typedef struct drawseg_s
INT16 *thicksidecol; INT16 *thicksidecol;
INT32 numthicksides; INT32 numthicksides;
fixed_t frontscale[MAXVIDWIDTH]; fixed_t frontscale[MAXVIDWIDTH];
#ifdef ESLOPE
fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures
vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes
#endif
} drawseg_t; } drawseg_t;
typedef enum typedef enum

View file

@ -103,6 +103,12 @@ fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
UINT8 *ds_source; // start of a 64*64 tile image UINT8 *ds_source; // start of a 64*64 tile image
UINT8 *ds_transmap; // one of the translucency tables UINT8 *ds_transmap; // one of the translucency tables
#ifdef ESLOPE
pslope_t *ds_slope; // Current slope being used
floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff?
float focallengthf, zeroheight;
#endif
/** \brief Variable flat sizes /** \brief Variable flat sizes
*/ */

View file

@ -60,6 +60,16 @@ extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
extern UINT8 *ds_source; // start of a 64*64 tile image extern UINT8 *ds_source; // start of a 64*64 tile image
extern UINT8 *ds_transmap; extern UINT8 *ds_transmap;
#ifdef ESLOPE
typedef struct {
float x, y, z;
} floatv3_t;
pslope_t *ds_slope; // Current slope being used
floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff?
float focallengthf, zeroheight;
#endif
// Variable flat sizes // Variable flat sizes
extern UINT32 nflatxshift; extern UINT32 nflatxshift;
extern UINT32 nflatyshift; extern UINT32 nflatyshift;
@ -141,6 +151,11 @@ void ASMCALL R_DrawSpan_8_MMX(void);
void R_DrawTranslatedColumn_8(void); void R_DrawTranslatedColumn_8(void);
void R_DrawTranslatedTranslucentColumn_8(void); void R_DrawTranslatedTranslucentColumn_8(void);
void R_DrawSpan_8(void); void R_DrawSpan_8(void);
#ifdef ESLOPE
void R_DrawTiltedSpan_8(void);
void R_DrawTiltedTranslucentSpan_8(void);
void R_DrawTiltedSplat_8(void);
#endif
void R_DrawSplat_8(void); void R_DrawSplat_8(void);
void R_DrawTranslucentSplat_8(void); void R_DrawTranslucentSplat_8(void);
void R_DrawTranslucentSpan_8(void); void R_DrawTranslucentSpan_8(void);

View file

@ -526,6 +526,436 @@ void R_DrawSpan_8 (void)
} }
} }
#ifdef ESLOPE
// R_CalcTiltedLighting
// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly.
static size_t tiltlighting[MAXVIDWIDTH];
void R_CalcTiltedLighting(fixed_t start, fixed_t end)
{
// ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version
// of this function. Here's my own.
INT32 left = ds_x1, right = ds_x2;
fixed_t step = (end-start)/(ds_x2-ds_x1+1);
size_t i;
// I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once,
// but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now...
for (i = left; i <= right; i++) {
tiltlighting[i] = (start += step) >> FRACBITS;
if (tiltlighting[i] < 0)
tiltlighting[i] = 0;
else if (tiltlighting[i] >= MAXLIGHTSCALE)
tiltlighting[i] = MAXLIGHTSCALE-1;
}
}
/** \brief The R_DrawTiltedSpan_8 function
Draw slopes! Holy sheit!
*/
void R_DrawTiltedSpan_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
double iz, uz, vz;
UINT32 u, v;
int i;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
float lightstart, lightend;
lightend = (iz + ds_sz.x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source;
//colormap = ds_colormap;
#if 0 // The "perfect" reference version of this routine. Pretty slow.
// Use it only to see how things are supposed to look.
i = 0;
do
{
double z = 1.f/iz;
u = (INT64)(uz*z) + viewx;
v = (INT64)(vz*z) + viewy;
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
dest++;
iz += ds_sz.x;
uz += ds_su.x;
vz += ds_sv.x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
double startz = 1.f/iz;
double startu = uz*startz;
double startv = vz*startz;
double izstep, uzstep, vzstep;
izstep = ds_sz.x * SPANSIZE;
uzstep = ds_su.x * SPANSIZE;
vzstep = ds_sv.x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
{
iz += izstep;
uz += uzstep;
vz += vzstep;
double endz = 1.f/iz;
double endu = uz*endz;
double endv = vz*endz;
UINT32 stepu = (INT64)((endu - startu) * INVSPAN);
UINT32 stepv = (INT64)((endv - startv) * INVSPAN);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
dest++;
u += stepu;
v += stepv;
}
startu = endu;
startv = endv;
width -= SPANSIZE;
}
if (width > 0)
{
if (width == 1)
{
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
}
else
{
double left = width;
iz += ds_sz.x * left;
uz += ds_su.x * left;
vz += ds_sv.x * left;
double endz = 1.f/iz;
double endu = uz*endz;
double endv = vz*endz;
left = 1.f/left;
UINT32 stepu = (INT64)((endu - startu) * left);
UINT32 stepv = (INT64)((endv - startv) * left);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (; width != 0; width--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
dest++;
u += stepu;
v += stepv;
}
}
}
#endif
}
/** \brief The R_DrawTiltedTranslucentSpan_8 function
Like DrawTiltedSpan, but translucent
*/
void R_DrawTiltedTranslucentSpan_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
double iz, uz, vz;
UINT32 u, v;
int i;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
float lightstart, lightend;
lightend = (iz + ds_sz.x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source;
//colormap = ds_colormap;
#if 0 // The "perfect" reference version of this routine. Pretty slow.
// Use it only to see how things are supposed to look.
i = 0;
do
{
double z = 1.f/iz;
u = (INT64)(uz*z) + viewx;
v = (INT64)(vz*z) + viewy;
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
dest++;
iz += ds_sz.x;
uz += ds_su.x;
vz += ds_sv.x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
double startz = 1.f/iz;
double startu = uz*startz;
double startv = vz*startz;
double izstep, uzstep, vzstep;
izstep = ds_sz.x * SPANSIZE;
uzstep = ds_su.x * SPANSIZE;
vzstep = ds_sv.x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
{
iz += izstep;
uz += uzstep;
vz += vzstep;
double endz = 1.f/iz;
double endu = uz*endz;
double endv = vz*endz;
UINT32 stepu = (INT64)((endu - startu) * INVSPAN);
UINT32 stepv = (INT64)((endv - startv) * INVSPAN);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
dest++;
u += stepu;
v += stepv;
}
startu = endu;
startv = endv;
width -= SPANSIZE;
}
if (width > 0)
{
if (width == 1)
{
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
}
else
{
double left = width;
iz += ds_sz.x * left;
uz += ds_su.x * left;
vz += ds_sv.x * left;
double endz = 1.f/iz;
double endu = uz*endz;
double endv = vz*endz;
left = 1.f/left;
UINT32 stepu = (INT64)((endu - startu) * left);
UINT32 stepv = (INT64)((endv - startv) * left);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (; width != 0; width--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
dest++;
u += stepu;
v += stepv;
}
}
}
#endif
}
void R_DrawTiltedSplat_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
double iz, uz, vz;
UINT32 u, v;
int i;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
UINT8 val;
iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
float lightstart, lightend;
lightend = (iz + ds_sz.x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source;
//colormap = ds_colormap;
#if 0 // The "perfect" reference version of this routine. Pretty slow.
// Use it only to see how things are supposed to look.
i = 0;
do
{
double z = 1.f/iz;
u = (INT64)(uz*z) + viewx;
v = (INT64)(vz*z) + viewy;
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
if (val != TRANSPARENTPIXEL)
*dest = val;
dest++;
iz += ds_sz.x;
uz += ds_su.x;
vz += ds_sv.x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
double startz = 1.f/iz;
double startu = uz*startz;
double startv = vz*startz;
double izstep, uzstep, vzstep;
izstep = ds_sz.x * SPANSIZE;
uzstep = ds_su.x * SPANSIZE;
vzstep = ds_sv.x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
{
iz += izstep;
uz += uzstep;
vz += vzstep;
double endz = 1.f/iz;
double endu = uz*endz;
double endv = vz*endz;
UINT32 stepu = (INT64)((endu - startu) * INVSPAN);
UINT32 stepv = (INT64)((endv - startv) * INVSPAN);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
if (val != TRANSPARENTPIXEL)
*dest = val;
dest++;
u += stepu;
v += stepv;
}
startu = endu;
startv = endv;
width -= SPANSIZE;
}
if (width > 0)
{
if (width == 1)
{
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
if (val != TRANSPARENTPIXEL)
*dest = val;
}
else
{
double left = width;
iz += ds_sz.x * left;
uz += ds_su.x * left;
vz += ds_sv.x * left;
double endz = 1.f/iz;
double endu = uz*endz;
double endv = vz*endz;
left = 1.f/left;
UINT32 stepu = (INT64)((endu - startu) * left);
UINT32 stepv = (INT64)((endv - startv) * left);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (; width != 0; width--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
if (val != TRANSPARENTPIXEL)
*dest = val;
dest++;
u += stepu;
v += stepv;
}
}
}
#endif
}
#endif // ESLOPE
/** \brief The R_DrawSplat_8 function /** \brief The R_DrawSplat_8 function
Just like R_DrawSpan_8, but skips transparent pixels. Just like R_DrawSpan_8, but skips transparent pixels.
*/ */

View file

@ -527,6 +527,8 @@ static void R_InitTextureMapping(void)
focallength = FixedDiv(centerxfrac, focallength = FixedDiv(centerxfrac,
FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2)); FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2));
focallengthf = FIXED_TO_FLOAT(focallength);
for (i = 0; i < FINEANGLES/2; i++) for (i = 0; i < FINEANGLES/2; i++)
{ {
if (FINETANGENT(i) > FRACUNIT*2) if (FINETANGENT(i) > FRACUNIT*2)

View file

@ -74,7 +74,7 @@ static INT32 spanstart[MAXVIDHEIGHT];
// //
// texture mapping // texture mapping
// //
static lighttable_t **planezlight; lighttable_t **planezlight;
static fixed_t planeheight; static fixed_t planeheight;
//added : 10-02-98: yslopetab is what yslope used to be, //added : 10-02-98: yslopetab is what yslope used to be,
@ -327,6 +327,11 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
if (pindex >= MAXLIGHTZ) if (pindex >= MAXLIGHTZ)
pindex = MAXLIGHTZ - 1; pindex = MAXLIGHTZ - 1;
#ifdef ESLOPE
if (currentplane->slope)
ds_colormap = colormaps;
else
#endif
ds_colormap = planezlight[pindex]; ds_colormap = planezlight[pindex];
if (currentplane->extra_colormap) if (currentplane->extra_colormap)
@ -423,11 +428,18 @@ static visplane_t *new_visplane(unsigned hash)
// //
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap,
ffloor_t *pfloor) ffloor_t *pfloor
#ifdef ESLOPE
, pslope_t *slope
#endif
)
{ {
visplane_t *check; visplane_t *check;
unsigned hash; unsigned hash;
#ifdef ESLOPE
if (slope); else // Don't mess with this right now if a slope is involved
#endif
if (plangle != 0) if (plangle != 0)
{ {
// Add the view offset, rotated by the plane angle. // Add the view offset, rotated by the plane angle.
@ -462,7 +474,11 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
&& xoff == check->xoffs && yoff == check->yoffs && xoff == check->xoffs && yoff == check->yoffs
&& planecolormap == check->extra_colormap && planecolormap == check->extra_colormap
&& !pfloor && !check->ffloor && check->viewz == viewz && !pfloor && !check->ffloor && check->viewz == viewz
&& check->viewangle == viewangle) && check->viewangle == viewangle
#ifdef ESLOPE
&& check->slope == slope
#endif
)
{ {
return check; return check;
} }
@ -485,6 +501,9 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
#ifdef POLYOBJECTS_PLANES #ifdef POLYOBJECTS_PLANES
check->polyobj = NULL; check->polyobj = NULL;
#endif #endif
#ifdef ESLOPE
check->slope = slope;
#endif
memset(check->top, 0xff, sizeof (check->top)); memset(check->top, 0xff, sizeof (check->top));
memset(check->bottom, 0x00, sizeof (check->bottom)); memset(check->bottom, 0x00, sizeof (check->bottom));
@ -551,6 +570,9 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
new_pl->plangle = pl->plangle; new_pl->plangle = pl->plangle;
#ifdef POLYOBJECTS_PLANES #ifdef POLYOBJECTS_PLANES
new_pl->polyobj = pl->polyobj; new_pl->polyobj = pl->polyobj;
#endif
#ifdef ESLOPE
new_pl->slope = pl->slope;
#endif #endif
pl = new_pl; pl = new_pl;
pl->minx = start; pl->minx = start;
@ -814,7 +836,11 @@ void R_DrawSinglePlane(visplane_t *pl)
else light = (pl->lightlevel >> LIGHTSEGSHIFT); else light = (pl->lightlevel >> LIGHTSEGSHIFT);
#ifndef NOWATER #ifndef NOWATER
if (pl->ffloor->flags & FF_RIPPLE) if (pl->ffloor->flags & FF_RIPPLE
#ifdef ESLOPE
&& !pl->slope
#endif
)
{ {
INT32 top, bottom; INT32 top, bottom;
@ -842,6 +868,9 @@ void R_DrawSinglePlane(visplane_t *pl)
} }
else light = (pl->lightlevel >> LIGHTSEGSHIFT); else light = (pl->lightlevel >> LIGHTSEGSHIFT);
#ifdef ESLOPE
if (!pl->slope) // Don't mess with angle on slopes! We'll handle this ourselves later
#endif
if (viewangle != pl->viewangle) if (viewangle != pl->viewangle)
{ {
memset(cachedheight, 0, sizeof (cachedheight)); memset(cachedheight, 0, sizeof (cachedheight));
@ -915,6 +944,99 @@ void R_DrawSinglePlane(visplane_t *pl)
if (light < 0) if (light < 0)
light = 0; light = 0;
#ifdef ESLOPE
if (pl->slope) {
// Potentially override other stuff for now cus we're mean. :< But draw a slope plane!
// I copied ZDoom's code and adapted it to SRB2... -Red
floatv3_t p, m, n;
float ang;
float vx, vy, vz;
float fudge;
xoffs &= ((1 << (32-nflatshiftup))-1);
yoffs &= ((1 << (32-nflatshiftup))-1);
xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
// Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red
fudge = ((1<<nflatshiftup)+1.0f)/(1<<nflatshiftup);
xoffs *= fudge;
yoffs /= fudge;
vx = FIXED_TO_FLOAT(viewx+xoffs);
vy = FIXED_TO_FLOAT(viewy-yoffs);
vz = FIXED_TO_FLOAT(viewz);
zeroheight = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx, viewy));
#define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180)
// p is the texture origin in view space
// Don't add in the offsets at this stage, because doing so can result in
// errors if the flat is rotated.
ang = ANG2RAD(ANGLE_270 - viewangle);
p.x = vx * cos(ang) - vy * sin(ang);
p.z = vx * sin(ang) + vy * cos(ang);
p.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, -xoffs, yoffs)) - vz;
// m is the v direction vector in view space
ang = ANG2RAD(ANGLE_180 - viewangle - pl->plangle);
m.x = cos(ang);
m.z = sin(ang);
// n is the u direction vector in view space
n.x = sin(ang);
n.z = -cos(ang);
ang = ANG2RAD(pl->plangle);
m.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FLOAT_TO_FIXED(sin(ang)), viewy + FLOAT_TO_FIXED(cos(ang)))) - zeroheight;
n.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FLOAT_TO_FIXED(cos(ang)), viewy - FLOAT_TO_FIXED(sin(ang)))) - zeroheight;
m.x /= fudge;
m.y /= fudge;
m.z /= fudge;
n.x *= fudge;
n.y *= fudge;
n.z *= fudge;
// Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using.
#define CROSS(d, v1, v2) \
d.x = (v1.y * v2.z) - (v1.z * v2.y);\
d.y = (v1.z * v2.x) - (v1.x * v2.z);\
d.z = (v1.x * v2.y) - (v1.y * v2.x)
CROSS(ds_su, p, m);
CROSS(ds_sv, p, n);
CROSS(ds_sz, m, n);
#undef CROSS
ds_su.z *= focallengthf;
ds_sv.z *= focallengthf;
ds_sz.z *= focallengthf;
// Premultiply the texture vectors with the scale factors
#define SFMULT 65536.f*(1<<nflatshiftup)
ds_su.x *= SFMULT;
ds_su.y *= SFMULT;
ds_su.z *= SFMULT;
ds_sv.x *= SFMULT;
ds_sv.y *= SFMULT;
ds_sv.z *= SFMULT;
#undef SFMULT
if (spanfunc == R_DrawTranslucentSpan_8)
spanfunc = R_DrawTiltedTranslucentSpan_8;
else if (spanfunc == splatfunc)
spanfunc = R_DrawTiltedSplat_8;
else
spanfunc = R_DrawTiltedSpan_8;
planezlight = scalelight[light];
} else
#endif // ESLOPE
planezlight = zlight[light]; planezlight = zlight[light];
// set the maximum value for unsigned // set the maximum value for unsigned

View file

@ -61,6 +61,9 @@ typedef struct visplane_s
#ifdef POLYOBJECTS_PLANES #ifdef POLYOBJECTS_PLANES
polyobj_t *polyobj; polyobj_t *polyobj;
#endif #endif
#ifdef ESLOPE
pslope_t *slope;
#endif
} visplane_t; } visplane_t;
extern visplane_t *floorplane; extern visplane_t *floorplane;
@ -79,6 +82,8 @@ extern fixed_t cachedxstep[MAXVIDHEIGHT];
extern fixed_t cachedystep[MAXVIDHEIGHT]; extern fixed_t cachedystep[MAXVIDHEIGHT];
extern fixed_t basexscale, baseyscale; extern fixed_t basexscale, baseyscale;
extern lighttable_t **planezlight;
extern fixed_t *yslope; extern fixed_t *yslope;
extern fixed_t distscale[MAXVIDWIDTH]; extern fixed_t distscale[MAXVIDWIDTH];
@ -91,7 +96,11 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2);
void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2);
void R_DrawPlanes(void); void R_DrawPlanes(void);
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle,
extracolormap_t *planecolormap, ffloor_t *ffloor); extracolormap_t *planecolormap, ffloor_t *ffloor
#ifdef ESLOPE
, pslope_t *slope
#endif
);
visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop); visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop); void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_PlaneBounds(visplane_t *plane); void R_PlaneBounds(visplane_t *plane);
@ -110,6 +119,14 @@ typedef struct planemgr_s
INT16 f_clip[MAXVIDWIDTH]; INT16 f_clip[MAXVIDWIDTH];
INT16 c_clip[MAXVIDWIDTH]; INT16 c_clip[MAXVIDWIDTH];
#ifdef ESLOPE
// For slope rendering; the height at the other end
fixed_t f_pos_slope;
fixed_t b_pos_slope;
struct pslope_s *slope;
#endif
struct ffloor_s *ffloor; struct ffloor_s *ffloor;
#ifdef POLYOBJECTS_PLANES #ifdef POLYOBJECTS_PLANES
polyobj_t *polyobj; polyobj_t *polyobj;

File diff suppressed because it is too large Load diff

View file

@ -950,12 +950,22 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
for (i = 1; i < sector->numlights; i++) for (i = 1; i < sector->numlights; i++)
{ {
if (sector->lightlist[i].height >= sprite->gzt || !(sector->lightlist[i].caster->flags & FF_CUTSPRITES)) fixed_t testheight = sector->lightlist[i].height;
if (!(sector->lightlist[i].caster->flags & FF_CUTSPRITES))
continue; continue;
if (sector->lightlist[i].height <= sprite->gz)
#ifdef ESLOPE
if (sector->lightlist[i].slope)
testheight = P_GetZAt(sector->lightlist[i].slope, sprite->gx, sprite->gy);
#endif
if (testheight >= sprite->gzt)
continue;
if (testheight <= sprite->gz)
return; return;
cutfrac = (INT16)((centeryfrac - FixedMul(sector->lightlist[i].height - viewz, sprite->scale))>>FRACBITS); cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->scale))>>FRACBITS);
if (cutfrac < 0) if (cutfrac < 0)
continue; continue;
if (cutfrac > vid.height) if (cutfrac > vid.height)
@ -966,15 +976,15 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t)); newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t));
sprite->cut |= SC_BOTTOM; sprite->cut |= SC_BOTTOM;
sprite->gz = sector->lightlist[i].height; sprite->gz = testheight;
newsprite->gzt = sprite->gz; newsprite->gzt = sprite->gz;
sprite->sz = cutfrac; sprite->sz = cutfrac;
newsprite->szt = (INT16)(sprite->sz - 1); newsprite->szt = (INT16)(sprite->sz - 1);
if (sector->lightlist[i].height < sprite->pzt && sector->lightlist[i].height > sprite->pz) if (testheight < sprite->pzt && testheight > sprite->pz)
sprite->pz = newsprite->pzt = sector->lightlist[i].height; sprite->pz = newsprite->pzt = testheight;
else else
{ {
newsprite->pz = newsprite->gz; newsprite->pz = newsprite->gz;
@ -1191,7 +1201,20 @@ static void R_ProjectSprite(mobj_t *thing)
if (thing->subsector->sector->numlights) if (thing->subsector->sector->numlights)
{ {
INT32 lightnum; INT32 lightnum;
#ifdef ESLOPE // R_GetPlaneLight won't work on sloped lights!
light = thing->subsector->sector->numlights - 1;
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y)
: thing->subsector->sector->lightlist[lightnum].height;
if (h <= gzt) {
light = lightnum - 1;
break;
}
}
#else
light = R_GetPlaneLight(thing->subsector->sector, gzt, false); light = R_GetPlaneLight(thing->subsector->sector, gzt, false);
#endif
lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT); lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT);
if (lightnum < 0) if (lightnum < 0)
@ -1752,24 +1775,34 @@ static void R_CreateDrawNodes(void)
{ {
if (r2->plane) if (r2->plane)
{ {
fixed_t planeobjectz, planecameraz;
if (r2->plane->minx > rover->x2 || r2->plane->maxx < rover->x1) if (r2->plane->minx > rover->x2 || r2->plane->maxx < rover->x1)
continue; continue;
if (rover->szt > r2->plane->low || rover->sz < r2->plane->high) if (rover->szt > r2->plane->low || rover->sz < r2->plane->high)
continue; continue;
#ifdef ESLOPE
// Effective height may be different for each comparison in the case of slopes
if (r2->plane->slope) {
planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy);
planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy);
} else
#endif
planeobjectz = planecameraz = r2->plane->height;
if (rover->mobjflags & MF_NOCLIPHEIGHT) if (rover->mobjflags & MF_NOCLIPHEIGHT)
{ {
//Objects with NOCLIPHEIGHT can appear halfway in. //Objects with NOCLIPHEIGHT can appear halfway in.
if (r2->plane->height < viewz && rover->pz+(rover->thingheight/2) >= r2->plane->height) if (planecameraz < viewz && rover->pz+(rover->thingheight/2) >= planeobjectz)
continue; continue;
if (r2->plane->height > viewz && rover->pzt-(rover->thingheight/2) <= r2->plane->height) if (planecameraz > viewz && rover->pzt-(rover->thingheight/2) <= planeobjectz)
continue; continue;
} }
else else
{ {
if (r2->plane->height < viewz && rover->pz >= r2->plane->height) if (planecameraz < viewz && rover->pz >= planeobjectz)
continue; continue;
if (r2->plane->height > viewz && rover->pzt <= r2->plane->height) if (planecameraz > viewz && rover->pzt <= planeobjectz)
continue; continue;
} }
@ -1799,6 +1832,7 @@ static void R_CreateDrawNodes(void)
} }
else if (r2->thickseg) else if (r2->thickseg)
{ {
fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz;
if (rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1) if (rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1)
continue; continue;
@ -1809,9 +1843,25 @@ static void R_CreateDrawNodes(void)
if (scale <= rover->scale) if (scale <= rover->scale)
continue; continue;
if ((*r2->ffloor->topheight > viewz && *r2->ffloor->bottomheight < viewz) || #ifdef ESLOPE
(*r2->ffloor->topheight < viewz && rover->gzt < *r2->ffloor->topheight) || if (*r2->ffloor->t_slope) {
(*r2->ffloor->bottomheight > viewz && rover->gz > *r2->ffloor->bottomheight)) topplaneobjectz = P_GetZAt(*r2->ffloor->t_slope, rover->gx, rover->gy);
topplanecameraz = P_GetZAt(*r2->ffloor->t_slope, viewx, viewy);
} else
#endif
topplaneobjectz = topplanecameraz = *r2->ffloor->topheight;
#ifdef ESLOPE
if (*r2->ffloor->b_slope) {
botplaneobjectz = P_GetZAt(*r2->ffloor->b_slope, rover->gx, rover->gy);
botplanecameraz = P_GetZAt(*r2->ffloor->b_slope, viewx, viewy);
} else
#endif
botplaneobjectz = botplanecameraz = *r2->ffloor->bottomheight;
if ((topplanecameraz > viewz && botplanecameraz < viewz) ||
(topplanecameraz < viewz && rover->gzt < topplaneobjectz) ||
(botplanecameraz > viewz && rover->gz > botplaneobjectz))
{ {
entry = R_CreateDrawNode(NULL); entry = R_CreateDrawNode(NULL);
(entry->prev = r2->prev)->next = entry; (entry->prev = r2->prev)->next = entry;
@ -2030,21 +2080,21 @@ void R_ClipSprites(void)
if (spr->gzt <= ds->tsilheight) if (spr->gzt <= ds->tsilheight)
silhouette &= ~SIL_TOP; silhouette &= ~SIL_TOP;
if (silhouette == 1) if (silhouette == SIL_BOTTOM)
{ {
// bottom sil // bottom sil
for (x = r1; x <= r2; x++) for (x = r1; x <= r2; x++)
if (spr->clipbot[x] == -2) if (spr->clipbot[x] == -2)
spr->clipbot[x] = ds->sprbottomclip[x]; spr->clipbot[x] = ds->sprbottomclip[x];
} }
else if (silhouette == 2) else if (silhouette == SIL_TOP)
{ {
// top sil // top sil
for (x = r1; x <= r2; x++) for (x = r1; x <= r2; x++)
if (spr->cliptop[x] == -2) if (spr->cliptop[x] == -2)
spr->cliptop[x] = ds->sprtopclip[x]; spr->cliptop[x] = ds->sprtopclip[x];
} }
else if (silhouette == 3) else if (silhouette == (SIL_TOP|SIL_BOTTOM))
{ {
// both // both
for (x = r1; x <= r2; x++) for (x = r1; x <= r2; x++)

View file

@ -2225,9 +2225,6 @@ angle_t tantoangle[2049] =
536870912 536870912
}; };
#ifdef NEED_FIXED_VECTOR
static angle_t fineacon[65536*2] = { static angle_t fineacon[65536*2] = {
ANGLE_MAX, 2143707442, 2142143280, 2140943052, 2139931208, 2139039753, 2138233813, 2137492672, 2136802831, 2136154917, 2135542102, 2134959233, 2134402306, 2133868139, 2133354148, 2132858208, ANGLE_MAX, 2143707442, 2142143280, 2140943052, 2139931208, 2139039753, 2138233813, 2137492672, 2136802831, 2136154917, 2135542102, 2134959233, 2134402306, 2133868139, 2133354148, 2132858208,
2132378539, 2131913638, 2131462220, 2131023174, 2130595537, 2130178462, 2129771202, 2129373097, 2128983555, 2128602046, 2128228092, 2127861261, 2127501162, 2127147436, 2126799757, 2126457825, 2132378539, 2131913638, 2131462220, 2131023174, 2130595537, 2130178462, 2129771202, 2129373097, 2128983555, 2128602046, 2128228092, 2127861261, 2127501162, 2127147436, 2126799757, 2126457825,
@ -10706,5 +10703,3 @@ void FM_Rotate(matrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z)
M(3, 3) = FRACUNIT; M(3, 3) = FRACUNIT;
#undef M #undef M
} }
#endif

View file

@ -96,9 +96,6 @@ FUNCMATH angle_t FixedAngle(fixed_t fa);
// and with a factor, with +factor for (fa/factor) and -factor for (fa*factor) // and with a factor, with +factor for (fa/factor) and -factor for (fa*factor)
FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor); FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor);
#ifdef NEED_FIXED_VECTOR
/// The FixedAcos function /// The FixedAcos function
FUNCMATH angle_t FixedAcos(fixed_t x); FUNCMATH angle_t FixedAcos(fixed_t x);
@ -112,8 +109,6 @@ void FV3_Rotate(vector3_t *rotVec, const vector3_t *axisVec, const angle_t angle
/// Fixed Point Matrix functions /// Fixed Point Matrix functions
void FM_Rotate(matrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z); void FM_Rotate(matrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z);
#endif // defined NEED_FIXED_VECTOR
// The table values in tables.c are calculated with this many fractional bits. // The table values in tables.c are calculated with this many fractional bits.
#define FINE_FRACBITS 16 #define FINE_FRACBITS 16

View file

@ -351,6 +351,13 @@ int main(int argc, char** argv)
return 0; return 0;
} }
static void *cpu_cpy(void *dest, const void *src, size_t n)
{
return memcpy(dest, src, n);
}
void *(*M_Memcpy)(void* dest, const void* src, size_t n) = cpu_cpy;
void I_Error(const char *error, ...) void I_Error(const char *error, ...)
{ {
(void)error; (void)error;