Merge branch 'next' into public_next

This commit is contained in:
Monster Iestyn 2016-06-23 17:15:21 +01:00
commit 2761c04cb9
9 changed files with 417 additions and 612 deletions

View file

@ -431,6 +431,12 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Kalaron/Eternity Engine slope code (SRB2CB ported) /// Kalaron/Eternity Engine slope code (SRB2CB ported)
#define ESLOPE #define ESLOPE
#ifdef ESLOPE
/// Backwards compatibility with SRB2CB's slope linedef types.
/// \note A simple shim that prints a warning.
#define ESLOPE_TYPESHIM
#endif
/// 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

@ -986,6 +986,7 @@ static const char *credits[] = {
"\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom) "\"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",
"Vivian \"toaster\" Grannell",
"Julio \"Chaos Zero 64\" Guir", "Julio \"Chaos Zero 64\" Guir",
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog "\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
"Matthew \"Shuffle\" Marsalko", "Matthew \"Shuffle\" Marsalko",

View file

@ -437,6 +437,16 @@ static int lib_pMobjFlip(lua_State *L)
return 1; return 1;
} }
static int lib_pGetMobjGravity(lua_State *L)
{
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
//HUDSAFE
if (!mobj)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushfixed(L, P_GetMobjGravity(mobj));
return 1;
}
static int lib_pWeaponOrPanel(lua_State *L) static int lib_pWeaponOrPanel(lua_State *L)
{ {
mobjtype_t type = luaL_checkinteger(L, 1); mobjtype_t type = luaL_checkinteger(L, 1);
@ -2008,6 +2018,7 @@ static luaL_Reg lib[] = {
{"P_SPMAngle",lib_pSPMAngle}, {"P_SPMAngle",lib_pSPMAngle},
{"P_SpawnPlayerMissile",lib_pSpawnPlayerMissile}, {"P_SpawnPlayerMissile",lib_pSpawnPlayerMissile},
{"P_MobjFlip",lib_pMobjFlip}, {"P_MobjFlip",lib_pMobjFlip},
{"P_GetMobjGravity",lib_pGetMobjGravity},
{"P_WeaponOrPanel",lib_pWeaponOrPanel}, {"P_WeaponOrPanel",lib_pWeaponOrPanel},
{"P_FlashPal",lib_pFlashPal}, {"P_FlashPal",lib_pFlashPal},
{"P_GetClosestAxis",lib_pGetClosestAxis}, {"P_GetClosestAxis",lib_pGetClosestAxis},

View file

@ -251,6 +251,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 aimtype
#endif #endif
void P_ColorTeamMissile(mobj_t *missile, player_t *source); void P_ColorTeamMissile(mobj_t *missile, player_t *source);
SINT8 P_MobjFlip(mobj_t *mobj); SINT8 P_MobjFlip(mobj_t *mobj);
fixed_t P_GetMobjGravity(mobj_t *mo);
boolean P_WeaponOrPanel(mobjtype_t type); boolean P_WeaponOrPanel(mobjtype_t type);
boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled); boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled);

View file

@ -2423,6 +2423,8 @@ isblocking:
// //
// P_IsClimbingValid // P_IsClimbingValid
// //
// Unlike P_DoClimbing, don't use when up against a one-sided linedef.
//
static boolean P_IsClimbingValid(player_t *player, angle_t angle) static boolean P_IsClimbingValid(player_t *player, angle_t angle)
{ {
fixed_t platx, platy; fixed_t platx, platy;
@ -2647,6 +2649,7 @@ isblocking:
// see about climbing on the wall // see about climbing on the wall
if (!(checkline->flags & ML_NOCLIMB)) if (!(checkline->flags & ML_NOCLIMB))
{ {
boolean canclimb; // FUCK C90
angle_t climbangle, climbline; angle_t climbangle, climbline;
INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li);
@ -2657,9 +2660,11 @@ isblocking:
climbangle += (ANGLE_90 * (whichside ? -1 : 1)); climbangle += (ANGLE_90 * (whichside ? -1 : 1));
canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true);
if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45) if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45)
|| (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135)) || (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135))
&& P_IsClimbingValid(slidemo->player, climbangle)) && canclimb)
{ {
slidemo->angle = climbangle; slidemo->angle = climbangle;
if (!demoplayback || P_AnalogMove(slidemo->player)) if (!demoplayback || P_AnalogMove(slidemo->player))

View file

@ -1252,13 +1252,12 @@ static void P_PlayerFlip(mobj_t *mo)
} }
// //
// P_CheckGravity // P_GetMobjGravity
// //
// Checks the current gravity state // Returns the current gravity
// of the object. If affect is true, // value of the object.
// a gravity force will be applied.
// //
void P_CheckGravity(mobj_t *mo, boolean affect) fixed_t P_GetMobjGravity(mobj_t *mo)
{ {
fixed_t gravityadd = 0; fixed_t gravityadd = 0;
boolean no3dfloorgrav = true; // Custom gravity boolean no3dfloorgrav = true; // Custom gravity
@ -1317,9 +1316,6 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
if (mo->eflags & MFE_UNDERWATER && !goopgravity) if (mo->eflags & MFE_UNDERWATER && !goopgravity)
gravityadd = gravityadd/3; gravityadd = gravityadd/3;
if (!mo->momz) // mobj at stop, no floor, so feel the push of gravity!
gravityadd <<= 1;
if (mo->player) if (mo->player)
{ {
if (mo->player->charability == CA_FLY && (mo->player->powers[pw_tailsfly] if (mo->player->charability == CA_FLY && (mo->player->powers[pw_tailsfly]
@ -1400,12 +1396,31 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
if (goopgravity) if (goopgravity)
gravityadd = -gravityadd/5; gravityadd = -gravityadd/5;
if (affect)
mo->momz += FixedMul(gravityadd, mo->scale);
if (mo->player && !!(mo->eflags & MFE_VERTICALFLIP) != wasflip) if (mo->player && !!(mo->eflags & MFE_VERTICALFLIP) != wasflip)
P_PlayerFlip(mo); P_PlayerFlip(mo);
gravityadd = FixedMul(gravityadd, mo->scale);
return gravityadd;
}
//
// P_CheckGravity
//
// Checks the current gravity state
// of the object. If affect is true,
// a gravity force will be applied.
//
void P_CheckGravity(mobj_t *mo, boolean affect)
{
fixed_t gravityadd = P_GetMobjGravity(mo);
if (!mo->momz) // mobj at stop, no floor, so feel the push of gravity!
gravityadd <<= 1;
if (affect)
mo->momz += gravityadd;
if (mo->type == MT_SKIM && mo->z + mo->momz <= mo->watertop && mo->z >= mo->watertop) if (mo->type == MT_SKIM && mo->z + mo->momz <= mo->watertop && mo->z >= mo->watertop)
{ {
mo->momz = 0; mo->momz = 0;
@ -1480,7 +1495,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
&& abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale) && abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale)
&& (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING)) && (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING))
#ifdef ESLOPE #ifdef ESLOPE
&& !(player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2) && !(player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && (abs(player->mo->standingslope->zdelta) >= FRACUNIT/2))
#endif #endif
) )
{ {
@ -2154,16 +2169,6 @@ static boolean P_ZMovement(mobj_t *mo)
I_Assert(mo != NULL); I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo)); I_Assert(!P_MobjWasRemoved(mo));
#ifdef ESLOPE
if (mo->standingslope)
{
if (mo->flags & MF_NOCLIPHEIGHT)
mo->standingslope = NULL;
else if (!P_IsObjectOnGround(mo))
P_SlopeLaunch(mo);
}
#endif
// Intercept the stupid 'fall through 3dfloors' bug // Intercept the stupid 'fall through 3dfloors' bug
if (mo->subsector->sector->ffloors) if (mo->subsector->sector->ffloors)
P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0); P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0);
@ -2178,6 +2183,16 @@ static boolean P_ZMovement(mobj_t *mo)
} }
mo->z += mo->momz; mo->z += mo->momz;
#ifdef ESLOPE
if (mo->standingslope)
{
if (mo->flags & MF_NOCLIPHEIGHT)
mo->standingslope = NULL;
else if (!P_IsObjectOnGround(mo))
P_SlopeLaunch(mo);
}
#endif
switch (mo->type) switch (mo->type)
{ {
case MT_THROWNBOUNCE: case MT_THROWNBOUNCE:
@ -2364,10 +2379,7 @@ static boolean P_ZMovement(mobj_t *mo)
if ((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) { if ((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) {
mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
// Reverse quantizing might could use its own function later P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope);
mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle;
P_QuantizeMomentumToSlope(&mom, mo->standingslope);
mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle;
} }
#endif #endif

View file

@ -199,7 +199,6 @@ static fixed_t P_GetExtent(sector_t *sector, line_t *line)
// Find furthest vertex from the reference line. It, along with the two ends // Find furthest vertex from the reference line. It, along with the two ends
// of the line, will define the plane. // of the line, will define the plane.
// SRB2CBTODO: Use a formula to get the slope to slide objects depending on how steep
for(i = 0; i < sector->linecount; i++) for(i = 0; i < sector->linecount; i++)
{ {
line_t *li = sector->lines[i]; line_t *li = sector->lines[i];
@ -231,7 +230,6 @@ static fixed_t P_GetExtent(sector_t *sector, line_t *line)
// //
// Creates one or more slopes based on the given line type and front/back // Creates one or more slopes based on the given line type and front/back
// sectors. // sectors.
// Kalaron: Check if dynamic slopes need recalculation
// //
void P_SpawnSlope_Line(int linenum) void P_SpawnSlope_Line(int linenum)
{ {
@ -276,7 +274,6 @@ void P_SpawnSlope_Line(int linenum)
ny = -FixedDiv(line->dx, len); ny = -FixedDiv(line->dx, len);
} }
// SRB2CBTODO: Transform origin relative to the bounds of an individual FOF
origin.x = line->v1->x + (line->v2->x - line->v1->x)/2; origin.x = line->v1->x + (line->v2->x - line->v1->x)/2;
origin.y = line->v1->y + (line->v2->y - line->v1->y)/2; origin.y = line->v1->y + (line->v2->y - line->v1->y)/2;
@ -327,7 +324,7 @@ void P_SpawnSlope_Line(int linenum)
// fslope->normal is a 3D line perpendicular to the 3D vector // fslope->normal is a 3D line perpendicular to the 3D vector
// Sync the linedata of the line that started this slope // Sync the linedata of the line that started this slope
// SRB2CBTODO: Anything special for remote(control sector)-based slopes later? // TODO: Anything special for control sector based slopes later?
fslope->sourceline = line; fslope->sourceline = line;
// To find the real highz/lowz of a slope, you need to check all the vertexes // To find the real highz/lowz of a slope, you need to check all the vertexes
@ -379,7 +376,7 @@ void P_SpawnSlope_Line(int linenum)
cslope->refpos = 2; cslope->refpos = 2;
// Sync the linedata of the line that started this slope // Sync the linedata of the line that started this slope
// SRB2CBTODO: Anything special for remote(control sector)-based slopes later? // TODO: Anything special for control sector based slopes later?
cslope->sourceline = line; cslope->sourceline = line;
// Remember the way the slope is formed // Remember the way the slope is formed
@ -445,7 +442,7 @@ void P_SpawnSlope_Line(int linenum)
fslope->refpos = 3; fslope->refpos = 3;
// Sync the linedata of the line that started this slope // Sync the linedata of the line that started this slope
// SRB2CBTODO: Anything special for remote(control sector)-based slopes later? // TODO: Anything special for control sector based slopes later?
fslope->sourceline = line; fslope->sourceline = line;
// Remember the way the slope is formed // Remember the way the slope is formed
@ -488,7 +485,7 @@ void P_SpawnSlope_Line(int linenum)
cslope->refpos = 4; cslope->refpos = 4;
// Sync the linedata of the line that started this slope // Sync the linedata of the line that started this slope
// SRB2CBTODO: Anything special for remote(control sector)-based slopes later? // TODO: Anything special for control sector based slopes later?
cslope->sourceline = line; cslope->sourceline = line;
// Remember the way the slope is formed // Remember the way the slope is formed
@ -554,16 +551,11 @@ static pslope_t *P_NewVertexSlope(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag
ret->vertices[2] = mt; ret->vertices[2] = mt;
} }
if (!ret->vertices[0])
CONS_Printf("PANIC 0\n");
if (!ret->vertices[1])
CONS_Printf("PANIC 1\n");
if (!ret->vertices[2])
CONS_Printf("PANIC 2\n");
// Now set heights for each vertex, because they haven't been set yet // Now set heights for each vertex, because they haven't been set yet
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
mt = ret->vertices[i]; mt = ret->vertices[i];
if (!mt) // If a vertex wasn't found, it's game over. There's nothing you can do to recover (except maybe try and kill the slope instead - TODO?)
I_Error("P_NewVertexSlope: Slope vertex %s (for linedef tag %d) not found!", sizeu1(i), tag1);
if (mt->extrainfo) if (mt->extrainfo)
mt->z = mt->options; mt->z = mt->options;
else else
@ -623,265 +615,10 @@ pslope_t *P_SlopeById(UINT16 id)
return ret; return ret;
} }
#ifdef SPRINGCLEAN
#include "byteptr.h"
#include "p_setup.h"
#include "p_local.h"
//==========================================================================
//
// P_SetSlopesFromVertexHeights
//
//==========================================================================
void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum)
{
mapthing_t *mt;
boolean vt_found = false;
size_t i, j, k, l, q;
//size_t i;
//mapthing_t *mt;
char *data;
char *datastart;
// SRB2CBTODO: WHAT IS (5 * sizeof (short))?! It = 10
// anything else seems to make a map not load properly,
// but this hard-coded value MUST have some reason for being what it is
size_t snummapthings = W_LumpLength(lumpnum) / (5 * sizeof (short));
mapthing_t *smapthings = Z_Calloc(snummapthings * sizeof (*smapthings), PU_LEVEL, NULL);
fixed_t x, y;
sector_t *sector;
// Spawn axis points first so they are
// at the front of the list for fast searching.
data = datastart = W_CacheLumpNum(lumpnum, PU_LEVEL);
mt = smapthings;
for (i = 0; i < snummapthings; i++, mt++)
{
mt->x = READINT16(data);
mt->y = READINT16(data);
mt->angle = READINT16(data);
mt->type = READINT16(data);
mt->options = READINT16(data);
// mt->z hasn't been set yet!
//mt->extrainfo = (byte)(mt->type >> 12); // slope things are special, they have a bigger range of types
//mt->type &= 4095; // SRB2CBTODO: WHAT IS THIS???? Mobj type limits?!!!!
x = mt->x*FRACUNIT;
y = mt->y*FRACUNIT;
sector = R_PointInSubsector(x, y)->sector;
// Z for objects
#ifdef ESLOPE
if (sector->f_slope)
mt->z = (short)(P_GetZAt(sector->f_slope, x, y)>>FRACBITS);
else
#endif
mt->z = (short)(sector->floorheight>>FRACBITS);
mt->z = mt->z + (mt->options >> ZSHIFT);
if (mt->type == THING_VertexFloorZ || mt->type == THING_VertexCeilingZ) // THING_VertexFloorZ
{
for(l = 0; l < numvertexes; l++)
{
if (vertexes[l].x == mt->x*FRACUNIT && vertexes[l].y == mt->y*FRACUNIT)
{
if (mt->type == THING_VertexFloorZ)
{
vertexes[l].z = mt->z*FRACUNIT;
//I_Error("Z value: %i", vertexes[l].z/FRACUNIT);
}
else
{
vertexes[l].z = mt->z*FRACUNIT; // celing floor
}
vt_found = true;
}
}
//mt->type = 0; // VPHYSICS: Dynamic slopes
if (vt_found)
{
for (k = 0; k < numsectors; k++)
{
sector_t *sec = &sectors[k];
if (sec->linecount != 3) continue; // only works with triangular sectors
v3float_t vt1, vt2, vt3; // cross = ret->normalf
v3float_t vec1, vec2;
int vi1, vi2, vi3;
vi1 = (int)(sec->lines[0]->v1 - vertexes);
vi2 = (int)(sec->lines[0]->v2 - vertexes);
vi3 = (sec->lines[1]->v1 == sec->lines[0]->v1 || sec->lines[1]->v1 == sec->lines[0]->v2)?
(int)(sec->lines[1]->v2 - vertexes) : (int)(sec->lines[1]->v1 - vertexes);
//if (vertexes[vi1].z)
// I_Error("OSNAP %i", vertexes[vi1].z/FRACUNIT);
//if (vertexes[vi2].z)
// I_Error("OSNAP %i", vertexes[vi2].z/FRACUNIT);
//if (vertexes[vi3].z)
// I_Error("OSNAP %i", vertexes[vi3].z/FRACUNIT);
//I_Error("%i, %i", mt->z*FRACUNIT, vertexes[vi1].z);
//I_Error("%i, %i, %i", mt->x, mt->y, mt->z);
//P_SpawnMobj(mt->x*FRACUNIT, mt->y*FRACUNIT, mt->z*FRACUNIT, MT_RING);
// TODO: Make sure not to spawn in the same place 2x! (we need an object in every vertex of the
// triangle sector to setup the real vertex slopes
// Check for the vertexes of all sectors
for(q = 0; q < numvertexes; q++)
{
if (vertexes[q].x == mt->x*FRACUNIT && vertexes[q].y == mt->y*FRACUNIT)
{
//I_Error("yeah %i", vertexes[q].z);
P_SpawnMobj(vertexes[q].x, vertexes[q].y, vertexes[q].z, MT_RING);
#if 0
if ((mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z)
&& !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z)
&& !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z))
P_SpawnMobj(vertexes[vi1].x, vertexes[vi1].y, vertexes[vi1].z, MT_RING);
else if ((mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z)
&& !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z)
&& !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z))
P_SpawnMobj(vertexes[vi2].x, vertexes[vi2].y, vertexes[vi2].z, MT_BOUNCETV);
else if ((mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z)
&& !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z)
&& !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z))
P_SpawnMobj(vertexes[vi3].x, vertexes[vi3].y, vertexes[vi3].z, MT_GFZFLOWER1);
else
#endif
continue;
}
}
vt1.x = FIXED_TO_FLOAT(vertexes[vi1].x);
vt1.y = FIXED_TO_FLOAT(vertexes[vi1].y);
vt2.x = FIXED_TO_FLOAT(vertexes[vi2].x);
vt2.y = FIXED_TO_FLOAT(vertexes[vi2].y);
vt3.x = FIXED_TO_FLOAT(vertexes[vi3].x);
vt3.y = FIXED_TO_FLOAT(vertexes[vi3].y);
for(j = 0; j < 2; j++)
{
fixed_t z3;
//I_Error("Lo hicimos");
vt1.z = mt->z;//FIXED_TO_FLOAT(j==0 ? sec->floorheight : sec->ceilingheight);
vt2.z = mt->z;//FIXED_TO_FLOAT(j==0? sec->floorheight : sec->ceilingheight);
z3 = mt->z;//j==0? sec->floorheight : sec->ceilingheight; // Destination height
vt3.z = FIXED_TO_FLOAT(z3);
if (P_PointOnLineSide(vertexes[vi3].x, vertexes[vi3].y, sec->lines[0]) == 0)
{
vec1.x = vt2.x - vt3.x;
vec1.y = vt2.y - vt3.y;
vec1.z = vt2.z - vt3.z;
vec2.x = vt1.x - vt3.x;
vec2.y = vt1.y - vt3.y;
vec2.z = vt1.z - vt3.z;
}
else
{
vec1.x = vt1.x - vt3.x;
vec1.y = vt1.y - vt3.y;
vec1.z = vt1.z - vt3.z;
vec2.x = vt2.x - vt3.x;
vec2.y = vt2.y - vt3.y;
vec2.z = vt2.z - vt3.z;
}
pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL);
memset(ret, 0, sizeof(*ret));
{
M_CrossProduct3f(&ret->normalf, &vec1, &vec2);
// Cross product length
float len = (float)sqrt(ret->normalf.x * ret->normalf.x +
ret->normalf.y * ret->normalf.y +
ret->normalf.z * ret->normalf.z);
if (len == 0)
{
// Only happens when all vertices in this sector are on the same line.
// Let's just ignore this case.
//CONS_Printf("Slope thing at (%d,%d) lies directly on its target line.\n", (int)(x>>16), (int)(y>>16));
return;
}
// cross/len
ret->normalf.x /= len;
ret->normalf.y /= len;
ret->normalf.z /= len;
// ZDoom cross = ret->normalf
// Fix backward normals
if ((ret->normalf.z < 0 && j == 0) || (ret->normalf.z > 0 && j == 1))
{
// cross = -cross
ret->normalf.x = -ret->normalf.x;
ret->normalf.y = -ret->normalf.x;
ret->normalf.z = -ret->normalf.x;
}
}
secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL);
srcplane->a = FLOAT_TO_FIXED (ret->normalf.x);
srcplane->b = FLOAT_TO_FIXED (ret->normalf.y);
srcplane->c = FLOAT_TO_FIXED (ret->normalf.z);
//srcplane->ic = FixedDiv(FRACUNIT, srcplane->c);
srcplane->d = -TMulScale16 (srcplane->a, vertexes[vi3].x,
srcplane->b, vertexes[vi3].y,
srcplane->c, z3);
if (j == 0)
{
sec->f_slope = ret;
sec->f_slope->secplane = *srcplane;
}
else if (j == 1)
{
sec->c_slope = ret;
sec->c_slope->secplane = *srcplane;
}
}
}
}
}
}
Z_Free(datastart);
}
#endif
// Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes // Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes
void P_ResetDynamicSlopes(void) { void P_ResetDynamicSlopes(void) {
size_t i; size_t i;
#if 1 // Rewrite old specials to new ones, and give a console warning #ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning
boolean warned = false; boolean warned = false;
#endif #endif
@ -894,7 +631,7 @@ void P_ResetDynamicSlopes(void) {
{ {
switch (lines[i].special) switch (lines[i].special)
{ {
#if 1 // Rewrite old specials to new ones, and give a console warning #ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning
#define WARNME if (!warned) {warned = true; CONS_Alert(CONS_WARNING, "This level uses old slope specials.\nA conversion will be needed before 2.2's release.\n");} #define WARNME if (!warned) {warned = true; CONS_Alert(CONS_WARNING, "This level uses old slope specials.\nA conversion will be needed before 2.2's release.\n");}
case 386: case 386:
case 387: case 387:
@ -1018,7 +755,11 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y)
// When given a vector, rotates it and aligns it to a slope // When given a vector, rotates it and aligns it to a slope
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
{ {
vector3_t axis; vector3_t axis; // Fuck you, C90.
if (slope->flags & SL_NOPHYSICS)
return; // No physics, no quantizing.
axis.x = -slope->d.y; axis.x = -slope->d.y;
axis.y = slope->d.x; axis.y = slope->d.x;
axis.z = 0; axis.z = 0;
@ -1026,24 +767,38 @@ void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
FV3_Rotate(momentum, &axis, slope->zangle >> ANGLETOFINESHIFT); FV3_Rotate(momentum, &axis, slope->zangle >> ANGLETOFINESHIFT);
} }
//
// P_ReverseQuantizeMomentumToSlope
//
// When given a vector, rotates and aligns it to a flat surface (from being relative to a given slope)
void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
{
slope->zangle = InvAngle(slope->zangle);
P_QuantizeMomentumToSlope(momentum, slope);
slope->zangle = InvAngle(slope->zangle);
}
// //
// P_SlopeLaunch // P_SlopeLaunch
// //
// Handles slope ejection for objects // Handles slope ejection for objects
void P_SlopeLaunch(mobj_t *mo) void P_SlopeLaunch(mobj_t *mo)
{ {
// Double the pre-rotation Z, then halve the post-rotation Z. This reduces the if (!(mo->standingslope->flags & SL_NOPHYSICS)) // If there's physics, time for launching.
// vertical launch given from slopes while increasing the horizontal launch {
// given. Good for SRB2's gravity and horizontal speeds. // Double the pre-rotation Z, then halve the post-rotation Z. This reduces the
vector3_t slopemom; // vertical launch given from slopes while increasing the horizontal launch
slopemom.x = mo->momx; // given. Good for SRB2's gravity and horizontal speeds.
slopemom.y = mo->momy; vector3_t slopemom;
slopemom.z = mo->momz*2; slopemom.x = mo->momx;
P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); slopemom.y = mo->momy;
slopemom.z = mo->momz*2;
P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
mo->momx = slopemom.x; mo->momx = slopemom.x;
mo->momy = slopemom.y; mo->momy = slopemom.y;
mo->momz = slopemom.z/2; mo->momz = slopemom.z/2;
}
//CONS_Printf("Launched off of slope.\n"); //CONS_Printf("Launched off of slope.\n");
mo->standingslope = NULL; mo->standingslope = NULL;
@ -1052,17 +807,21 @@ void P_SlopeLaunch(mobj_t *mo)
// Function to help handle landing on slopes // Function to help handle landing on slopes
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
{ {
vector3_t mom; vector3_t mom; // Ditto.
if (slope->flags & SL_NOPHYSICS) { // No physics, no need to make anything complicated.
if (P_MobjFlip(thing)*(thing->momz) < 0) { // falling, land on slope
thing->momz = -P_MobjFlip(thing);
thing->standingslope = slope;
}
return;
}
mom.x = thing->momx; mom.x = thing->momx;
mom.y = thing->momy; mom.y = thing->momy;
mom.z = thing->momz*2; mom.z = thing->momz*2;
//CONS_Printf("langing on slope\n"); P_ReverseQuantizeMomentumToSlope(&mom, slope);
// Reverse quantizing might could use its own function later
slope->zangle = ANGLE_MAX-slope->zangle;
P_QuantizeMomentumToSlope(&mom, slope);
slope->zangle = ANGLE_MAX-slope->zangle;
if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope
thing->momx = mom.x; thing->momx = mom.x;
@ -1082,6 +841,9 @@ void P_ButteredSlope(mobj_t *mo)
if (!mo->standingslope) if (!mo->standingslope)
return; return;
if (mo->standingslope->flags & SL_NOPHYSICS)
return; // No physics, no butter.
if (mo->flags & (MF_NOCLIPHEIGHT|MF_NOGRAVITY)) if (mo->flags & (MF_NOCLIPHEIGHT|MF_NOGRAVITY))
return; // don't slide down slopes if you can't touch them or you're not affected by gravity return; // don't slide down slopes if you can't touch them or you're not affected by gravity
@ -1106,8 +868,6 @@ void P_ButteredSlope(mobj_t *mo)
mult = FINECOSINE(angle >> ANGLETOFINESHIFT); mult = FINECOSINE(angle >> ANGLETOFINESHIFT);
} }
//CONS_Printf("%d\n", mult);
thrust = FixedMul(thrust, FRACUNIT*2/3 + mult/8); thrust = FixedMul(thrust, FRACUNIT*2/3 + mult/8);
} }
@ -1115,10 +875,11 @@ void P_ButteredSlope(mobj_t *mo)
thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16); thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16);
// This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down // This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down
// Multiply by gravity // Let's get the gravity strength for the object...
thrust = FixedMul(thrust, gravity); // TODO account for per-sector gravity etc thrust = FixedMul(thrust, abs(P_GetMobjGravity(mo)));
// Multiply by scale (gravity strength depends on mobj scale)
thrust = FixedMul(thrust, mo->scale); // ... and its friction against the ground for good measure (divided by original friction to keep behaviour for normal slopes the same).
thrust = FixedMul(thrust, FixedDiv(mo->friction, ORIG_FRICTION));
P_Thrust(mo, mo->standingslope->xydirection, thrust); P_Thrust(mo, mo->standingslope->xydirection, thrust);
} }

View file

@ -21,26 +21,6 @@ void P_RunDynamicSlopes(void);
// sectors. // sectors.
void P_SpawnSlope_Line(int linenum); 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 // P_CopySectorSlope
// //
@ -55,6 +35,7 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y);
// Lots of physics-based bullshit // Lots of physics-based bullshit
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
void P_SlopeLaunch(mobj_t *mo); void P_SlopeLaunch(mobj_t *mo);
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope); void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope);
void P_ButteredSlope(mobj_t *mo); void P_ButteredSlope(mobj_t *mo);

View file

@ -1851,12 +1851,8 @@ static void P_CheckBouncySectors(player_t *player)
momentum.y = player->mo->momy; momentum.y = player->mo->momy;
momentum.z = player->mo->momz*2; momentum.z = player->mo->momz*2;
if (slope) { if (slope)
// Reverse quantizing might could use its own function later P_ReverseQuantizeMomentumToSlope(&momentum, slope);
slope->zangle = ANGLE_MAX-slope->zangle;
P_QuantizeMomentumToSlope(&momentum, slope);
slope->zangle = ANGLE_MAX-slope->zangle;
}
newmom = momentum.z = -FixedMul(momentum.z,linedist)/2; newmom = momentum.z = -FixedMul(momentum.z,linedist)/2;
#else #else
@ -2284,9 +2280,9 @@ static void P_DoClimbing(player_t *player)
platx = P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platx = P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
platy = P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platy = P_ReturnThrustY(player->mo, 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_IsPointInSubsector(player->mo->x + platx, player->mo->y + platy);
if (glidesector->sector != player->mo->subsector->sector) if (!glidesector || glidesector->sector != player->mo->subsector->sector)
{ {
boolean floorclimb; boolean floorclimb;
boolean thrust; boolean thrust;
@ -2298,299 +2294,304 @@ static void P_DoClimbing(player_t *player)
boostup = false; boostup = false;
skyclimber = false; skyclimber = false;
#ifdef ESLOPE if (glidesector)
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)
{ {
ffloor_t *rover; #ifdef ESLOPE
fixed_t topheight, bottomheight; // 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
for (rover = glidesector->sector->ffloors; rover; rover = rover->next) if (glidesector->sector->ffloors)
{ {
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) ffloor_t *rover;
continue; fixed_t topheight, bottomheight; // ESLOPE
floorclimb = true; for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue;
floorclimb = true;
#ifdef ESLOPE #ifdef ESLOPE
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; 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; topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
#else #else
bottomheight = *rover->bottomheight; bottomheight = *rover->bottomheight;
topheight = *rover->topheight; topheight = *rover->topheight;
#endif #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) && (bottomheight < player->mo->z+player->mo->height)
&& (topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)))
|| ((player->mo->eflags & MFE_VERTICALFLIP) && (topheight > player->mo->z)
&& (bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))))
{ {
if (cmd->forwardmove != 0) if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (bottomheight < player->mo->z+player->mo->height)
player->mo->momz += rover->master->frontsector->floorspeed; && (topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)))
else || ((player->mo->eflags & MFE_VERTICALFLIP) && (topheight > player->mo->z)
&& (bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))))
{ {
player->mo->momz = rover->master->frontsector->floorspeed; if (cmd->forwardmove != 0)
climb = false; player->mo->momz += rover->master->frontsector->floorspeed;
else
{
player->mo->momz = rover->master->frontsector->floorspeed;
climb = false;
}
} }
} }
}
// Gravity is flipped, so the comments are, too. // Gravity is flipped, so the comments are, too.
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{
// Trying to climb down past the bottom of the FOF
if ((topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= topheight))
{ {
fixed_t bottomheight2; // Trying to climb down past the bottom of the FOF
ffloor_t *roverbelow; if ((topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= topheight))
boolean foundfof = false;
floorclimb = true;
boostup = false;
// Is there a FOF directly below this one that we can move onto?
for (roverbelow = glidesector->sector->ffloors; roverbelow; roverbelow = roverbelow->next)
{ {
if (!(roverbelow->flags & FF_EXISTS) || !(roverbelow->flags & FF_BLOCKPLAYER) || (roverbelow->flags & FF_BUSTUP)) fixed_t bottomheight2;
continue; ffloor_t *roverbelow;
boolean foundfof = false;
floorclimb = true;
boostup = false;
if (roverbelow == rover) // Is there a FOF directly below this one that we can move onto?
continue; for (roverbelow = glidesector->sector->ffloors; roverbelow; roverbelow = roverbelow->next)
{
if (!(roverbelow->flags & FF_EXISTS) || !(roverbelow->flags & FF_BLOCKPLAYER) || (roverbelow->flags & FF_BUSTUP))
continue;
if (roverbelow == rover)
continue;
#ifdef ESLOPE #ifdef ESLOPE
bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight; bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight;
#else #else
bottomheight2 = *roverbelow->bottomheight; bottomheight2 = *roverbelow->bottomheight;
#endif #endif
if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale)) if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale))
foundfof = true; foundfof = true;
}
if (!foundfof)
player->mo->momz = 0;
} }
if (!foundfof) // Below the FOF
player->mo->momz = 0; if (topheight <= player->mo->z)
}
// Below the FOF
if (topheight <= player->mo->z)
{
floorclimb = false;
boostup = false;
thrust = false;
}
// Above the FOF
if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))
{
floorclimb = false;
thrust = true;
boostup = true;
}
}
else
{
// Trying to climb down past the bottom of a FOF
if ((bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= bottomheight))
{
fixed_t topheight2;
ffloor_t *roverbelow;
boolean foundfof = false;
floorclimb = true;
boostup = false;
// Is there a FOF directly below this one that we can move onto?
for (roverbelow = glidesector->sector->ffloors; roverbelow; roverbelow = roverbelow->next)
{ {
if (!(roverbelow->flags & FF_EXISTS) || !(roverbelow->flags & FF_BLOCKPLAYER) || (roverbelow->flags & FF_BUSTUP)) floorclimb = false;
continue; boostup = false;
thrust = false;
}
if (roverbelow == rover) // Above the FOF
continue; if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))
{
floorclimb = false;
thrust = true;
boostup = true;
}
}
else
{
// Trying to climb down past the bottom of a FOF
if ((bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= bottomheight))
{
fixed_t topheight2;
ffloor_t *roverbelow;
boolean foundfof = false;
floorclimb = true;
boostup = false;
// Is there a FOF directly below this one that we can move onto?
for (roverbelow = glidesector->sector->ffloors; roverbelow; roverbelow = roverbelow->next)
{
if (!(roverbelow->flags & FF_EXISTS) || !(roverbelow->flags & FF_BLOCKPLAYER) || (roverbelow->flags & FF_BUSTUP))
continue;
if (roverbelow == rover)
continue;
#ifdef ESLOPE #ifdef ESLOPE
topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight; topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight;
#else #else
topheight2 = *roverbelow->topheight; topheight2 = *roverbelow->topheight;
#endif #endif
if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale))
foundfof = true; foundfof = true;
}
if (!foundfof)
player->mo->momz = 0;
} }
if (!foundfof) // Below the FOF
player->mo->momz = 0; if (bottomheight >= player->mo->z + player->mo->height)
{
floorclimb = false;
boostup = false;
thrust = false;
}
// Above the FOF
if (topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))
{
floorclimb = false;
thrust = true;
boostup = true;
}
} }
// Below the FOF if (floorclimb)
if (bottomheight >= player->mo->z + player->mo->height)
{ {
floorclimb = false; if (rover->flags & FF_CRUMBLE && !(netgame && player->spectator))
boostup = false; EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, !(rover->flags & FF_NORETURN));
thrust = false; break;
} }
// Above the FOF
if (topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))
{
floorclimb = false;
thrust = true;
boostup = true;
}
}
if (floorclimb)
{
if (rover->flags & FF_CRUMBLE && !(netgame && player->spectator))
EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, !(rover->flags & FF_NORETURN));
break;
} }
} }
}
// Gravity is flipped, so are comments. // Gravity is flipped, so are comments.
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{
// Trying to climb down past the upper texture area
if ((floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= floorheight))
{ {
boolean foundfof = false; // Trying to climb down past the upper texture area
floorclimb = true; if ((floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= floorheight))
// Is there a FOF directly below that we can move onto?
if (glidesector->sector->ffloors)
{ {
fixed_t bottomheight; boolean foundfof = false;
ffloor_t *rover; floorclimb = true;
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
// Is there a FOF directly below that we can move onto?
if (glidesector->sector->ffloors)
{ {
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) fixed_t bottomheight;
continue; ffloor_t *rover;
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue;
#ifdef ESLOPE #ifdef ESLOPE
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
#else #else
bottomheight = *rover->bottomheight; bottomheight = *rover->bottomheight;
#endif #endif
if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale))
{ {
foundfof = true; foundfof = true;
break; break;
}
} }
} }
if (!foundfof)
player->mo->momz = 0;
} }
if (!foundfof) // Reached the top of the lower texture area
player->mo->momz = 0; if (!floorclimb && ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)
&& (glidesector->sector->ceilingpic == skyflatnum || floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale))))
{
thrust = true;
boostup = true;
// Play climb-up animation here
}
}
else
{
// Trying to climb down past the upper texture area
if ((ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= ceilingheight))
{
boolean foundfof = false;
floorclimb = true;
// Is there a FOF directly below that we can move onto?
if (glidesector->sector->ffloors)
{
ffloor_t *rover;
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue;
if (*rover->topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
{
foundfof = true;
break;
}
}
}
if (!foundfof)
player->mo->momz = 0;
}
// Allow climbing from a FOF or lower texture onto the upper texture and vice versa.
if (player->mo->z > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
{
floorclimb = true;
thrust = false;
boostup = false;
}
// Reached the top of the lower texture area
if (!floorclimb && floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)
&& (glidesector->sector->ceilingpic == skyflatnum || ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale))))
{
thrust = true;
boostup = true;
// Play climb-up animation here
}
} }
// Reached the top of the lower texture area // Trying to climb on the sky
if (!floorclimb && ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) if ((ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum)
&& (glidesector->sector->ceilingpic == skyflatnum || floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale))))
{ {
thrust = true; skyclimber = true;
boostup = true; }
// Play climb-up animation here
// Climbing on the lower texture area?
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 <= floorheight))
{
floorclimb = true;
if (glidesector->sector->floorspeed)
{
if (cmd->forwardmove != 0)
player->mo->momz += glidesector->sector->floorspeed;
else
{
player->mo->momz = glidesector->sector->floorspeed;
climb = false;
}
}
}
// Climbing on the upper texture area?
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) > ceilingheight))
{
floorclimb = true;
if (glidesector->sector->ceilspeed)
{
if (cmd->forwardmove != 0)
player->mo->momz += glidesector->sector->ceilspeed;
else
{
player->mo->momz = glidesector->sector->ceilspeed;
climb = false;
}
}
} }
} }
else else
{
// Trying to climb down past the upper texture area
if ((ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= ceilingheight))
{
boolean foundfof = false;
floorclimb = true;
// Is there a FOF directly below that we can move onto?
if (glidesector->sector->ffloors)
{
ffloor_t *rover;
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue;
if (*rover->topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
{
foundfof = true;
break;
}
}
}
if (!foundfof)
player->mo->momz = 0;
}
// Allow climbing from a FOF or lower texture onto the upper texture and vice versa.
if (player->mo->z > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
{
floorclimb = true;
thrust = false;
boostup = false;
}
// Reached the top of the lower texture area
if (!floorclimb && floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)
&& (glidesector->sector->ceilingpic == skyflatnum || ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale))))
{
thrust = true;
boostup = true;
// Play climb-up animation here
}
}
// Trying to climb on the sky
if ((ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum)
{
skyclimber = true;
}
// Climbing on the lower texture area?
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 <= floorheight))
{
floorclimb = true; floorclimb = true;
if (glidesector->sector->floorspeed)
{
if (cmd->forwardmove != 0)
player->mo->momz += glidesector->sector->floorspeed;
else
{
player->mo->momz = glidesector->sector->floorspeed;
climb = false;
}
}
}
// Climbing on the upper texture area?
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) > ceilingheight))
{
floorclimb = true;
if (glidesector->sector->ceilspeed)
{
if (cmd->forwardmove != 0)
player->mo->momz += glidesector->sector->ceilspeed;
else
{
player->mo->momz = glidesector->sector->ceilspeed;
climb = false;
}
}
}
if (player->lastsidehit != -1 && player->lastlinehit != -1) if (player->lastsidehit != -1 && player->lastlinehit != -1)
{ {
thinker_t *think; thinker_t *think;
@ -2851,16 +2852,18 @@ static void P_DoTeeter(player_t *player)
{ {
boolean teeter = false; boolean teeter = false;
boolean roverfloor; // solid 3d floors? boolean roverfloor; // solid 3d floors?
fixed_t floorheight, ceilingheight;
fixed_t topheight, bottomheight; // for 3d floor usage
const fixed_t tiptop = FixedMul(MAXSTEPMOVE, player->mo->scale); // Distance you have to be above the ground in order to teeter. const fixed_t tiptop = FixedMul(MAXSTEPMOVE, player->mo->scale); // Distance you have to be above the ground in order to teeter.
if (player->mo->standingslope && player->mo->standingslope->zdelta >= (FRACUNIT/2)) // Always teeter if the slope is too steep.
teeter = true;
else // Let's do some checks...
{ {
subsector_t *subsec[4]; // changed abcd into array instead
UINT8 i; UINT8 i;
sector_t *sec;
subsec[0] = R_PointInSubsector(player->mo->x + FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y + FixedMul(5*FRACUNIT, player->mo->scale)); fixed_t highestceilingheight = INT32_MIN;
subsec[1] = R_PointInSubsector(player->mo->x - FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y + FixedMul(5*FRACUNIT, player->mo->scale)); fixed_t lowestfloorheight = INT32_MAX;
subsec[2] = R_PointInSubsector(player->mo->x + FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y - FixedMul(5*FRACUNIT, player->mo->scale));
subsec[3] = R_PointInSubsector(player->mo->x - FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y - FixedMul(5*FRACUNIT, player->mo->scale));
teeter = false; teeter = false;
roverfloor = false; roverfloor = false;
@ -2868,13 +2871,43 @@ static void P_DoTeeter(player_t *player)
{ {
ffloor_t *rover; ffloor_t *rover;
if (!(subsec[i]->sector->ffloors)) #define xsign ((i & 1) ? -1 : 1) // 0 -> 1 | 1 -> -1 | 2 -> 1 | 3 -> -1
#define ysign ((i & 2) ? 1 : -1) // 0 -> 1 | 1 -> 1 | 2 -> -1 | 3 -> -1
fixed_t checkx = player->mo->x + (xsign*FixedMul(5*FRACUNIT, player->mo->scale));
fixed_t checky = player->mo->y + (ysign*FixedMul(5*FRACUNIT, player->mo->scale));
#undef xsign
#undef ysign
sec = R_PointInSubsector(checkx, checky)->sector;
ceilingheight = sec->ceilingheight;
floorheight = sec->floorheight;
#ifdef ESLOPE
if (sec->c_slope)
ceilingheight = P_GetZAt(sec->c_slope, checkx, checky);
if (sec->f_slope)
floorheight = P_GetZAt(sec->f_slope, checkx, checky);
#endif
highestceilingheight = (ceilingheight > highestceilingheight) ? ceilingheight : highestceilingheight;
lowestfloorheight = (floorheight < lowestfloorheight) ? floorheight : lowestfloorheight;
if (!(sec->ffloors))
continue; // move on to the next subsector continue; // move on to the next subsector
for (rover = subsec[i]->sector->ffloors; rover; rover = rover->next) for (rover = sec->ffloors; rover; rover = rover->next)
{ {
if (!(rover->flags & FF_EXISTS)) continue; if (!(rover->flags & FF_EXISTS)) 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
if (P_CheckSolidLava(player->mo, rover)) if (P_CheckSolidLava(player->mo, rover))
; ;
else if (!(rover->flags & FF_BLOCKPLAYER || rover->flags & FF_QUICKSAND)) else if (!(rover->flags & FF_BLOCKPLAYER || rover->flags & FF_QUICKSAND))
@ -2882,12 +2915,12 @@ static void P_DoTeeter(player_t *player)
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{ {
if (*rover->bottomheight > subsec[i]->sector->ceilingheight) // Above the ceiling if (bottomheight > ceilingheight) // Above the ceiling
continue; continue;
if (*rover->bottomheight > player->mo->z + player->mo->height + tiptop if (bottomheight > player->mo->z + player->mo->height + tiptop
|| (*rover->topheight < player->mo->z || (topheight < player->mo->z
&& player->mo->z + player->mo->height < subsec[i]->sector->ceilingheight - tiptop)) && player->mo->z + player->mo->height < ceilingheight - tiptop))
{ {
teeter = true; teeter = true;
roverfloor = true; roverfloor = true;
@ -2901,12 +2934,12 @@ static void P_DoTeeter(player_t *player)
} }
else else
{ {
if (*rover->topheight < subsec[i]->sector->floorheight) // Below the floor if (topheight < floorheight) // Below the floor
continue; continue;
if (*rover->topheight < player->mo->z - tiptop if (topheight < player->mo->z - tiptop
|| (*rover->bottomheight > player->mo->z + player->mo->height || (bottomheight > player->mo->z + player->mo->height
&& player->mo->z > subsec[i]->sector->floorheight + tiptop)) && player->mo->z > floorheight + tiptop))
{ {
teeter = true; teeter = true;
roverfloor = true; roverfloor = true;
@ -2924,18 +2957,12 @@ static void P_DoTeeter(player_t *player)
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{ {
if (!teeter && !roverfloor && (subsec[0]->sector->ceilingheight > player->mo->ceilingz + tiptop if (!teeter && !roverfloor && (highestceilingheight > player->mo->ceilingz + tiptop))
|| subsec[1]->sector->ceilingheight > player->mo->ceilingz + tiptop
|| subsec[2]->sector->ceilingheight > player->mo->ceilingz + tiptop
|| subsec[3]->sector->ceilingheight > player->mo->ceilingz + tiptop))
teeter = true; teeter = true;
} }
else else
{ {
if (!teeter && !roverfloor && (subsec[0]->sector->floorheight < player->mo->floorz - tiptop if (!teeter && !roverfloor && (lowestfloorheight < player->mo->floorz - tiptop))
|| subsec[1]->sector->floorheight < player->mo->floorz - tiptop
|| subsec[2]->sector->floorheight < player->mo->floorz - tiptop
|| subsec[3]->sector->floorheight < player->mo->floorz - tiptop))
teeter = true; teeter = true;
} }
} }
@ -3665,7 +3692,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
{ {
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 #ifdef ESLOPE
&& (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) && (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
#endif #endif
) )
{ {
@ -3698,7 +3725,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
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->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<<FRACBITS, player->mo->scale)
#ifdef ESLOPE #ifdef ESLOPE
|| (player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2) || (player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)
#endif #endif
) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) ) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING))
{ {
@ -3714,7 +3741,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
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 #ifdef ESLOPE
&& (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) && (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
#endif #endif
) )
{ {
@ -4700,7 +4727,7 @@ static void P_3dMovement(player_t *player)
#ifdef ESLOPE #ifdef ESLOPE
if ((totalthrust.x || totalthrust.y) if ((totalthrust.x || totalthrust.y)
&& player->mo->standingslope && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) { && player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) {
// Factor thrust to slope, but only for the part pushing up it! // Factor thrust to slope, but only for the part pushing up it!
// The rest is unaffected. // The rest is unaffected.
angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection; angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection;