diff --git a/.travis.yml b/.travis.yml index e3408cf6f..d728758ed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -98,7 +98,7 @@ matrix: - p7zip-full - gcc-6 compiler: gcc-6 - env: WFLAGS="-Wno-error=tautological-compare" + env: WFLAGS="-Wno-tautological-compare" #gcc-6 (Ubuntu 6.1.1-3ubuntu11~14.04.1) 6.1.1 20160511 - os: linux compiler: clang @@ -213,7 +213,7 @@ before_script: - 7z x $HOME/srb2_cache/SRB2-v2115-assets-2.7z -oassets - mkdir build - cd build - - export CFLAGS="-Wall -W $WFLAGS" + - export CFLAGS="-Wall -W -Werror $WFLAGS" - export CCACHE_COMPRESS=true - cmake .. -DCMAKE_BUILD_TYPE=Release diff --git a/src/doomdef.h b/src/doomdef.h index 70ec8c0d1..4428ef617 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -213,7 +213,7 @@ extern FILE *logstream; // it's only for detection of the version the player is using so the MS can alert them of an update. // Only set it higher, not lower, obviously. // Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1". -#define MODVERSION 20 +#define MODVERSION 21 // ========================================================================= @@ -435,6 +435,12 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Kalaron/Eternity Engine slope code (SRB2CB ported) #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. /// \note EXTREMELY buggy, tends to crash game. //#define DELFILE diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 1bacf9102..bbcec06d3 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -429,6 +429,16 @@ static int lib_pMobjFlip(lua_State *L) 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) { mobjtype_t type = luaL_checkinteger(L, 1); @@ -2003,6 +2013,7 @@ static luaL_Reg lib[] = { {"P_SPMAngle",lib_pSPMAngle}, {"P_SpawnPlayerMissile",lib_pSpawnPlayerMissile}, {"P_MobjFlip",lib_pMobjFlip}, + {"P_GetMobjGravity",lib_pGetMobjGravity}, {"P_WeaponOrPanel",lib_pWeaponOrPanel}, {"P_FlashPal",lib_pFlashPal}, {"P_GetClosestAxis",lib_pGetClosestAxis}, diff --git a/src/p_local.h b/src/p_local.h index 57ca425e1..a6573d487 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -251,6 +251,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 aimtype #endif void P_ColorTeamMissile(mobj_t *missile, player_t *source); SINT8 P_MobjFlip(mobj_t *mobj); +fixed_t P_GetMobjGravity(mobj_t *mo); boolean P_WeaponOrPanel(mobjtype_t type); boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled); diff --git a/src/p_map.c b/src/p_map.c index 0d4bae830..a91e5fd11 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2433,6 +2433,8 @@ isblocking: // // 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) { fixed_t platx, platy; @@ -2657,6 +2659,7 @@ isblocking: // see about climbing on the wall if (!(checkline->flags & ML_NOCLIMB)) { + boolean canclimb; // FUCK C90 angle_t climbangle, climbline; INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); @@ -2667,9 +2670,11 @@ isblocking: 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) || (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135)) - && P_IsClimbingValid(slidemo->player, climbangle)) + && canclimb) { slidemo->angle = climbangle; if (!demoplayback || P_AnalogMove(slidemo->player)) diff --git a/src/p_mobj.c b/src/p_mobj.c index d516e2528..999f2bf72 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1427,13 +1427,12 @@ static void P_PlayerFlip(mobj_t *mo) } // -// P_CheckGravity +// P_GetMobjGravity // -// Checks the current gravity state -// of the object. If affect is true, -// a gravity force will be applied. +// Returns the current gravity +// value of the object. // -void P_CheckGravity(mobj_t *mo, boolean affect) +fixed_t P_GetMobjGravity(mobj_t *mo) { fixed_t gravityadd = 0; boolean no3dfloorgrav = true; // Custom gravity @@ -1492,9 +1491,6 @@ void P_CheckGravity(mobj_t *mo, boolean affect) if (mo->eflags & MFE_UNDERWATER && !goopgravity) 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->charability == CA_FLY && (mo->player->powers[pw_tailsfly] @@ -1575,12 +1571,31 @@ void P_CheckGravity(mobj_t *mo, boolean affect) if (goopgravity) gravityadd = -gravityadd/5; - if (affect) - mo->momz += FixedMul(gravityadd, mo->scale); - if (mo->player && !!(mo->eflags & MFE_VERTICALFLIP) != wasflip) 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) { mo->momz = 0; @@ -1655,7 +1670,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy) && abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale) && (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING)) #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 ) { @@ -2329,16 +2344,6 @@ static boolean P_ZMovement(mobj_t *mo) I_Assert(mo != NULL); 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 if (mo->subsector->sector->ffloors) P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0); @@ -2353,6 +2358,16 @@ static boolean P_ZMovement(mobj_t *mo) } 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) { case MT_THROWNBOUNCE: @@ -2539,10 +2554,7 @@ static boolean P_ZMovement(mobj_t *mo) if ((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) { mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; - // Reverse quantizing might could use its own function later - mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle; - P_QuantizeMomentumToSlope(&mom, mo->standingslope); - mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle; + P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope); } #endif diff --git a/src/p_setup.c b/src/p_setup.c index 6c14e3614..e56c44c70 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1934,7 +1934,7 @@ static void P_GroupLines(void) if (sector->linecount == 0) // no lines found? { sector->lines = NULL; - CONS_Debug(DBG_SETUP, "P_GroupLines: sector %d has no lines\n", i); + CONS_Debug(DBG_SETUP, "P_GroupLines: sector %s has no lines\n", sizeu1(i)); } else { diff --git a/src/p_slopes.c b/src/p_slopes.c index 6393ca4b5..d939fee98 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -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 // 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++) { 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 // sectors. -// Kalaron: Check if dynamic slopes need recalculation // void P_SpawnSlope_Line(int linenum) { @@ -276,7 +274,6 @@ void P_SpawnSlope_Line(int linenum) 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.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 // 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; // 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; // 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; // Remember the way the slope is formed @@ -445,7 +442,7 @@ void P_SpawnSlope_Line(int linenum) fslope->refpos = 3; // 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; // Remember the way the slope is formed @@ -488,7 +485,7 @@ void P_SpawnSlope_Line(int linenum) cslope->refpos = 4; // 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; // 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; } - 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 for (i = 0; i < 3; 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) mt->z = mt->options; else @@ -623,265 +615,10 @@ pslope_t *P_SlopeById(UINT16 id) 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 = §ors[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 void P_ResetDynamicSlopes(void) { 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; #endif @@ -894,7 +631,7 @@ void P_ResetDynamicSlopes(void) { { 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");} case 386: 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 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.y = slope->d.x; axis.z = 0; @@ -1026,24 +767,38 @@ void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) 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 // // Handles slope ejection for objects void P_SlopeLaunch(mobj_t *mo) { - // Double the pre-rotation Z, then halve the post-rotation Z. This reduces the - // vertical launch given from slopes while increasing the horizontal launch - // given. Good for SRB2's gravity and horizontal speeds. - vector3_t slopemom; - slopemom.x = mo->momx; - slopemom.y = mo->momy; - slopemom.z = mo->momz*2; - P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); + if (!(mo->standingslope->flags & SL_NOPHYSICS)) // If there's physics, time for launching. + { + // Double the pre-rotation Z, then halve the post-rotation Z. This reduces the + // vertical launch given from slopes while increasing the horizontal launch + // given. Good for SRB2's gravity and horizontal speeds. + vector3_t slopemom; + slopemom.x = mo->momx; + slopemom.y = mo->momy; + slopemom.z = mo->momz*2; + P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); - mo->momx = slopemom.x; - mo->momy = slopemom.y; - mo->momz = slopemom.z/2; + mo->momx = slopemom.x; + mo->momy = slopemom.y; + mo->momz = slopemom.z/2; + } //CONS_Printf("Launched off of slope.\n"); mo->standingslope = NULL; @@ -1052,17 +807,21 @@ void P_SlopeLaunch(mobj_t *mo) // Function to help handle landing on slopes 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.y = thing->momy; mom.z = thing->momz*2; - //CONS_Printf("langing on slope\n"); - - // 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; + P_ReverseQuantizeMomentumToSlope(&mom, slope); if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope thing->momx = mom.x; @@ -1082,6 +841,9 @@ void P_ButteredSlope(mobj_t *mo) if (!mo->standingslope) return; + if (mo->standingslope->flags & SL_NOPHYSICS) + return; // No physics, no butter. + 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 @@ -1106,8 +868,6 @@ void P_ButteredSlope(mobj_t *mo) mult = FINECOSINE(angle >> ANGLETOFINESHIFT); } - //CONS_Printf("%d\n", mult); - 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); // This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down - // Multiply by gravity - thrust = FixedMul(thrust, gravity); // TODO account for per-sector gravity etc - // Multiply by scale (gravity strength depends on mobj scale) - thrust = FixedMul(thrust, mo->scale); + // Let's get the gravity strength for the object... + thrust = FixedMul(thrust, abs(P_GetMobjGravity(mo))); + + // ... 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); } diff --git a/src/p_slopes.h b/src/p_slopes.h index 80921a84b..de38f1d9e 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -21,26 +21,6 @@ void P_RunDynamicSlopes(void); // 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 // @@ -55,6 +35,7 @@ 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_ReverseQuantizeMomentumToSlope(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); diff --git a/src/p_user.c b/src/p_user.c index 6b7c9d4ed..09941745b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1852,12 +1852,8 @@ static void P_CheckBouncySectors(player_t *player) 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; - } + if (slope) + P_ReverseQuantizeMomentumToSlope(&momentum, slope); newmom = momentum.z = -FixedMul(momentum.z,linedist)/2; #else @@ -2279,9 +2275,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)); 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 thrust; @@ -2293,299 +2289,304 @@ static void P_DoClimbing(player_t *player) boostup = false; skyclimber = false; -#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) { - ffloor_t *rover; - fixed_t topheight, bottomheight; // 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 - 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)) - continue; + ffloor_t *rover; + 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 - 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; + 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; + bottomheight = *rover->bottomheight; + topheight = *rover->topheight; #endif - // 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 ((!(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)))) + // 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 (cmd->forwardmove != 0) - player->mo->momz += rover->master->frontsector->floorspeed; - else + 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)))) { - player->mo->momz = rover->master->frontsector->floorspeed; - climb = false; + if (cmd->forwardmove != 0) + 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. - 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)) + // Gravity is flipped, so the comments are, too. + if (player->mo->eflags & MFE_VERTICALFLIP) { - fixed_t bottomheight2; - 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) + // 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)) { - if (!(roverbelow->flags & FF_EXISTS) || !(roverbelow->flags & FF_BLOCKPLAYER) || (roverbelow->flags & FF_BUSTUP)) - continue; + fixed_t bottomheight2; + ffloor_t *roverbelow; + boolean foundfof = false; + floorclimb = true; + boostup = false; - if (roverbelow == rover) - continue; + // 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 - 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 - bottomheight2 = *roverbelow->bottomheight; + bottomheight2 = *roverbelow->bottomheight; #endif - if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale)) - foundfof = true; + if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale)) + foundfof = true; + } + + if (!foundfof) + player->mo->momz = 0; } - if (!foundfof) - player->mo->momz = 0; - } - - // 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) + // Below the FOF + if (topheight <= player->mo->z) { - if (!(roverbelow->flags & FF_EXISTS) || !(roverbelow->flags & FF_BLOCKPLAYER) || (roverbelow->flags & FF_BUSTUP)) - continue; + floorclimb = false; + boostup = false; + thrust = false; + } - if (roverbelow == rover) - continue; + // 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)) + continue; + + if (roverbelow == rover) + continue; #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 - topheight2 = *roverbelow->topheight; + topheight2 = *roverbelow->topheight; #endif - if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) - foundfof = true; + if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) + foundfof = true; + } + + if (!foundfof) + player->mo->momz = 0; } - if (!foundfof) - player->mo->momz = 0; + // Below the FOF + 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 (bottomheight >= player->mo->z + player->mo->height) + if (floorclimb) { - floorclimb = false; - boostup = false; - thrust = false; + 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; } - - // 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. - 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)) + // Gravity is flipped, so are comments. + if (player->mo->eflags & MFE_VERTICALFLIP) { - boolean foundfof = false; - floorclimb = true; - - // Is there a FOF directly below that we can move onto? - if (glidesector->sector->ffloors) + // 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)) { - fixed_t bottomheight; - ffloor_t *rover; - for (rover = glidesector->sector->ffloors; rover; rover = rover->next) + boolean foundfof = false; + floorclimb = true; + + // 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)) - continue; + fixed_t bottomheight; + 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 - 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 - bottomheight = *rover->bottomheight; + bottomheight = *rover->bottomheight; #endif - if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) - { - foundfof = true; - break; + if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) + { + foundfof = true; + break; + } } } + + if (!foundfof) + player->mo->momz = 0; } - if (!foundfof) - player->mo->momz = 0; + // Reached the top of the lower texture area + 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 - 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)))) + // Trying to climb on the sky + if ((ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum) { - thrust = true; - boostup = true; - // Play climb-up animation here + 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; + + 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 - { - // 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; - 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) { thinker_t *think; @@ -2846,16 +2847,18 @@ static void P_DoTeeter(player_t *player) { boolean teeter = false; 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. + 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; - - subsec[0] = R_PointInSubsector(player->mo->x + FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y + FixedMul(5*FRACUNIT, player->mo->scale)); - subsec[1] = R_PointInSubsector(player->mo->x - FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y + FixedMul(5*FRACUNIT, player->mo->scale)); - 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)); + sector_t *sec; + fixed_t highestceilingheight = INT32_MIN; + fixed_t lowestfloorheight = INT32_MAX; teeter = false; roverfloor = false; @@ -2863,13 +2866,43 @@ static void P_DoTeeter(player_t *player) { 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 - for (rover = subsec[i]->sector->ffloors; rover; rover = rover->next) + for (rover = sec->ffloors; rover; rover = rover->next) { 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)) ; else if (!(rover->flags & FF_BLOCKPLAYER || rover->flags & FF_QUICKSAND)) @@ -2877,12 +2910,12 @@ static void P_DoTeeter(player_t *player) if (player->mo->eflags & MFE_VERTICALFLIP) { - if (*rover->bottomheight > subsec[i]->sector->ceilingheight) // Above the ceiling + if (bottomheight > ceilingheight) // Above the ceiling continue; - if (*rover->bottomheight > player->mo->z + player->mo->height + tiptop - || (*rover->topheight < player->mo->z - && player->mo->z + player->mo->height < subsec[i]->sector->ceilingheight - tiptop)) + if (bottomheight > player->mo->z + player->mo->height + tiptop + || (topheight < player->mo->z + && player->mo->z + player->mo->height < ceilingheight - tiptop)) { teeter = true; roverfloor = true; @@ -2896,12 +2929,12 @@ static void P_DoTeeter(player_t *player) } else { - if (*rover->topheight < subsec[i]->sector->floorheight) // Below the floor + if (topheight < floorheight) // Below the floor continue; - if (*rover->topheight < player->mo->z - tiptop - || (*rover->bottomheight > player->mo->z + player->mo->height - && player->mo->z > subsec[i]->sector->floorheight + tiptop)) + if (topheight < player->mo->z - tiptop + || (bottomheight > player->mo->z + player->mo->height + && player->mo->z > floorheight + tiptop)) { teeter = true; roverfloor = true; @@ -2919,18 +2952,12 @@ static void P_DoTeeter(player_t *player) if (player->mo->eflags & MFE_VERTICALFLIP) { - if (!teeter && !roverfloor && (subsec[0]->sector->ceilingheight > 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)) + if (!teeter && !roverfloor && (highestceilingheight > player->mo->ceilingz + tiptop)) teeter = true; } else { - if (!teeter && !roverfloor && (subsec[0]->sector->floorheight < 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)) + if (!teeter && !roverfloor && (lowestfloorheight < player->mo->floorz - tiptop)) teeter = true; } } @@ -3682,7 +3709,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) { if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<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) + && (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) #endif ) { @@ -3718,7 +3745,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)) && !player->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<mo->scale) #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 ) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) { @@ -3734,7 +3761,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH) && player->speed < FixedMul(5*FRACUNIT,player->mo->scale) #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 ) { @@ -4723,7 +4750,7 @@ static void P_3dMovement(player_t *player) #ifdef ESLOPE 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! // The rest is unaffected. angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection;