From 19d77bfc531794c77d78831e982e36ec74574c4b Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 2 May 2020 12:50:09 +0200 Subject: [PATCH 01/10] P_PlayerMobjThinker: Move crumbling platforms check into its own function --- src/p_mobj.c | 61 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 29fe1a57c..17734096f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3780,9 +3780,41 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled return false; } -// -// P_PlayerMobjThinker -// +static void P_CheckCrumblingPlatforms(mobj_t *mobj) +{ + msecnode_t *node; + + if (netgame && mobj->player->spectator) + return; + + for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next) + { + ffloor_t *rover; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!(rover->flags & FF_CRUMBLE)) + continue; + + if (mobj->eflags & MFE_VERTICALFLIP) + { + if (P_GetSpecialBottomZ(mobj, sectors + rover->secnum, node->m_sector) != mobj->z + mobj->height) + continue; + } + else + { + if (P_GetSpecialTopZ(mobj, sectors + rover->secnum, node->m_sector) != mobj->z) + continue; + } + + EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), mobj->player, rover->alpha, !(rover->flags & FF_NORETURN)); + } + } +} + static void P_PlayerMobjThinker(mobj_t *mobj) { msecnode_t *node; @@ -3839,28 +3871,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) else P_TryMove(mobj, mobj->x, mobj->y, true); - if (!(netgame && mobj->player->spectator)) - { - // Crumbling platforms - for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next) - { - fixed_t topheight, bottomheight; - ffloor_t *rover; - - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_CRUMBLE)) - continue; - - topheight = P_GetSpecialTopZ(mobj, sectors + rover->secnum, node->m_sector); - bottomheight = P_GetSpecialBottomZ(mobj, sectors + rover->secnum, node->m_sector); - - if ((topheight == mobj->z && !(mobj->eflags & MFE_VERTICALFLIP)) - || (bottomheight == mobj->z + mobj->height && mobj->eflags & MFE_VERTICALFLIP)) // You nut. - EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), mobj->player, rover->alpha, !(rover->flags & FF_NORETURN)); - } - } - } + P_CheckCrumblingPlatforms(mobj); // Check for floating water platforms and bounce them if (CheckForFloatBob && P_MobjFlip(mobj)*mobj->momz < 0) From 2605f29bd45e53a7e070fd9ddac3275721048a16 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 2 May 2020 13:08:13 +0200 Subject: [PATCH 02/10] P_PlayerMobjThinker: Move check for floatbob platforms into its own function --- src/p_mobj.c | 121 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 72 insertions(+), 49 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 17734096f..eb6a1a125 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3815,10 +3815,79 @@ static void P_CheckCrumblingPlatforms(mobj_t *mobj) } } -static void P_PlayerMobjThinker(mobj_t *mobj) +static boolean P_MobjTouchesSectorWithWater(mobj_t *mobj) { msecnode_t *node; + for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next) + { + ffloor_t *rover; + + if (!node->m_sector->ffloors) + continue; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!(rover->flags & FF_SWIMMABLE)) + continue; + + return true; + } + } + + return false; +} + +// Check for floating water platforms and bounce them +static void P_CheckFloatbobPlatforms(mobj_t *mobj) +{ + msecnode_t *node; + + // Can't land on anything if you're not moving downwards + if (P_MobjFlip(mobj)*mobj->momz >= 0) + return; + + if (!P_MobjTouchesSectorWithWater(mobj)) + return; + + for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next) + { + ffloor_t *rover; + + if (!node->m_sector->ffloors) + continue; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!(rover->flags & FF_FLOATBOB)) + continue; + + + if (mobj->eflags & MFE_VERTICALFLIP) + { + if (abs(*rover->bottomheight - (mobj->z + mobj->height)) > abs(mobj->momz)) + continue; + } + else + { + if (abs(*rover->topheight - mobj->z) > abs(mobj->momz)) + continue; + } + + // Initiate a 'bouncy' elevator function which slowly diminishes. + EV_BounceSector(rover->master->frontsector, -mobj->momz, rover->master); + } + } +} + +static void P_PlayerMobjThinker(mobj_t *mobj) +{ I_Assert(mobj != NULL); I_Assert(mobj->player != NULL); I_Assert(!P_MobjWasRemoved(mobj)); @@ -3873,54 +3942,8 @@ static void P_PlayerMobjThinker(mobj_t *mobj) P_CheckCrumblingPlatforms(mobj); - // Check for floating water platforms and bounce them - if (CheckForFloatBob && P_MobjFlip(mobj)*mobj->momz < 0) - { - boolean thereiswater = false; - - for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next) - { - if (node->m_sector->ffloors) - { - ffloor_t *rover; - // Get water boundaries first - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS)) - continue; - - if (rover->flags & FF_SWIMMABLE) // Is there water? - { - thereiswater = true; - break; - } - } - } - } - if (thereiswater) - { - for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next) - { - if (node->m_sector->ffloors) - { - ffloor_t *rover; - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_FLOATBOB)) - continue; - - if ((!(mobj->eflags & MFE_VERTICALFLIP) && abs(*rover->topheight-mobj->z) <= abs(mobj->momz)) // The player is landing on the cheese! - || (mobj->eflags & MFE_VERTICALFLIP && abs(*rover->bottomheight-(mobj->z+mobj->height)) <= abs(mobj->momz))) - { - // Initiate a 'bouncy' elevator function - // which slowly diminishes. - EV_BounceSector(rover->master->frontsector, -mobj->momz, rover->master); - } - } - } - } - } // Ugly ugly billions of braces! Argh! - } + if (CheckForFloatBob) + P_CheckFloatbobPlatforms(mobj); // always do the gravity bit now, that's simpler // BUT CheckPosition only if wasn't done before. From afc63788680bd75654504e0b0f0a1c7a0f04187b Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 2 May 2020 13:34:24 +0200 Subject: [PATCH 03/10] P_PlayerZMovement: Move checks for Mario blocks into their own function --- src/p_mobj.c | 70 +++++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index eb6a1a125..91cb3dc9e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2798,6 +2798,43 @@ static boolean P_ZMovement(mobj_t *mo) return true; } +// Check for "Mario" blocks to hit and bounce them +static void P_CheckMarioBlocks(mobj_t *mo) +{ + msecnode_t *node; + + if (netgame && mo->player->spectator) + return; + + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) + { + ffloor_t *rover; + + if (!node->m_sector->ffloors) + continue; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!(rover->flags & FF_MARIO)) + continue; + + if (mo->eflags & MFE_VERTICALFLIP) + continue; // if you were flipped, your head isn't actually hitting your ceilingz is it? + + if (*rover->bottomheight != mo->ceilingz) + continue; + + if (rover->flags & FF_SHATTERBOTTOM) // Brick block! + EV_CrumbleChain(node->m_sector, rover); + else // Question block! + EV_MarioBlock(rover, node->m_sector, mo); + } + } +} + static void P_PlayerZMovement(mobj_t *mo) { boolean onground; @@ -3022,39 +3059,10 @@ nightsdone: } } - // Check for "Mario" blocks to hit and bounce them if (P_MobjFlip(mo)*mo->momz > 0) { - msecnode_t *node; - - if (CheckForMarioBlocks && !(netgame && mo->player->spectator)) // Only let the player punch - { - // Search the touching sectors, from side-to-side... - for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) - { - ffloor_t *rover; - if (!node->m_sector->ffloors) - continue; - - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS)) - continue; - - // Come on, it's time to go... - if (rover->flags & FF_MARIO - && !(mo->eflags & MFE_VERTICALFLIP) // if you were flipped, your head isn't actually hitting your ceilingz is it? - && *rover->bottomheight == mo->ceilingz) // The player's head hit the bottom! - { - // DO THE MARIO! - if (rover->flags & FF_SHATTERBOTTOM) // Brick block! - EV_CrumbleChain(node->m_sector, rover); - else // Question block! - EV_MarioBlock(rover, node->m_sector, mo); - } - } - } // Ugly ugly billions of braces! Argh! - } + if (CheckForMarioBlocks) + P_CheckMarioBlocks(mo); // hit the ceiling if (mariomode) From a67c8786aedbab4b9dca8301b62249e0e6f620cd Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 2 May 2020 13:49:16 +0200 Subject: [PATCH 04/10] P_PlayerZMovement: Move PolyObject handling code into its own function --- src/p_mobj.c | 111 ++++++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4a9f4ec95..fab6c193f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2835,6 +2835,57 @@ static void P_CheckMarioBlocks(mobj_t *mo) } } +// Check if we're on a polyobject that triggers a linedef executor. +static boolean P_PlayerPolyObjectZMovement(mobj_t *mo) +{ + msecnode_t *node; + boolean stopmovecut = false; + + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) + { + sector_t *sec = node->m_sector; + subsector_t *newsubsec; + size_t i; + + for (i = 0; i < numsubsectors; i++) + { + polyobj_t *po; + sector_t *polysec; + newsubsec = &subsectors[i]; + + if (newsubsec->sector != sec) + continue; + + for (po = newsubsec->polyList; po; po = (polyobj_t *)(po->link.next)) + { + if (!(po->flags & POF_SOLID)) + continue; + + if (!P_MobjInsidePolyobj(po, mo)) + continue; + + polysec = po->lines[0]->backsector; + + // Moving polyobjects should act like conveyors if the player lands on one. (I.E. none of the momentum cut thing below) -Red + if ((mo->z == polysec->ceilingheight || mo->z + mo->height == polysec->floorheight) && po->thinker) + stopmovecut = true; + + if (!(po->flags & POF_LDEXEC)) + continue; + + if (mo->z != polysec->ceilingheight) + continue; + + // We're landing on a PO, so check for a linedef executor. + // Trigger tags are 32000 + the PO's ID number. + P_LinedefExecute((INT16)(32000 + po->id), mo, NULL); + } + } + } + + return stopmovecut; +} + static void P_PlayerZMovement(mobj_t *mo) { boolean onground; @@ -2931,66 +2982,8 @@ static void P_PlayerZMovement(mobj_t *mo) mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack + if (!P_PlayerPolyObjectZMovement(mo)) { - // Check if we're on a polyobject - // that triggers a linedef executor. - msecnode_t *node; - boolean stopmovecut = false; - - for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) - { - sector_t *sec = node->m_sector; - subsector_t *newsubsec; - size_t i; - - for (i = 0; i < numsubsectors; i++) - { - newsubsec = &subsectors[i]; - - if (newsubsec->sector != sec) - continue; - - if (newsubsec->polyList) - { - polyobj_t *po = newsubsec->polyList; - sector_t *polysec; - - while(po) - { - if (!P_MobjInsidePolyobj(po, mo) || !(po->flags & POF_SOLID)) - { - po = (polyobj_t *)(po->link.next); - continue; - } - - // We're inside it! Yess... - polysec = po->lines[0]->backsector; - - // Moving polyobjects should act like conveyors if the player lands on one. (I.E. none of the momentum cut thing below) -Red - if ((mo->z == polysec->ceilingheight || mo->z+mo->height == polysec->floorheight) && po->thinker) - stopmovecut = true; - - if (!(po->flags & POF_LDEXEC)) - { - po = (polyobj_t *)(po->link.next); - continue; - } - - if (mo->z == polysec->ceilingheight) - { - // We're landing on a PO, so check for - // a linedef executor. - // Trigger tags are 32000 + the PO's ID number. - P_LinedefExecute((INT16)(32000 + po->id), mo, NULL); - } - - po = (polyobj_t *)(po->link.next); - } - } - } - } - - if (!stopmovecut) // Cut momentum in half when you hit the ground and // aren't pressing any controls. if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING)) From 929064b998b908fe444693251baa773c2d2ab9f7 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 2 May 2020 15:21:53 +0200 Subject: [PATCH 05/10] Refactor PTR_SlideTraverse --- src/p_map.c | 279 ++++++++++++++++++++++++++-------------------------- 1 file changed, 139 insertions(+), 140 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 0fade4847..3f1f6caf5 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3310,9 +3310,139 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) return false; } -// -// PTR_SlideTraverse -// +static boolean PTR_LineIsBlocking(line_t *li) +{ + // one-sided linedefs are always solid to sliding movement. + if (!li->backsector) + return !P_PointOnLineSide(slidemo->x, slidemo->y, li); + + if (!(slidemo->flags & MF_MISSILE)) + { + if (li->flags & ML_IMPASSIBLE) + return true; + + if ((slidemo->flags & (MF_ENEMY|MF_BOSS)) && li->flags & ML_BLOCKMONSTERS) + return true; + } + + // set openrange, opentop, openbottom + P_LineOpening(li, slidemo); + + if (openrange < slidemo->height) + return true; // doesn't fit + + if (opentop - slidemo->z < slidemo->height) + return true; // mobj is too high + + if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, slidemo->scale)) + return true; // too big a step up + + return false; +} + +static void PTR_GlideClimbTraverse(line_t *li) +{ + line_t *checkline = li; + sector_t *checksector; + ffloor_t *rover; + fixed_t topheight, bottomheight; + boolean fofline = false; + INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); + + if (!side && li->backsector) + checksector = li->backsector; + else + checksector = li->frontsector; + + if (checksector->ffloors) + { + for (rover = checksector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) + continue; + + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); + + if (topheight < slidemo->z) + continue; + + if (bottomheight > slidemo->z + slidemo->height) + continue; + + // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? + if (rover->master->flags & ML_TFERLINE) + { + size_t linenum = li-checksector->lines[0]; + checkline = rover->master->frontsector->lines[0] + linenum; + fofline = true; + } + + break; + } + } + + // see about climbing on the wall + if (!(checkline->flags & ML_NOCLIMB) && checkline->special != HORIZONSPECIAL) + { + boolean canclimb; + angle_t climbangle, climbline; + INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); + + climbangle = climbline = R_PointToAngle2(li->v1->x, li->v1->y, li->v2->x, li->v2->y); + + if (whichside) // on second side? + climbline += ANGLE_180; + + 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)) + && canclimb) + { + slidemo->angle = climbangle; + /*if (!demoplayback || P_ControlStyle(slidemo->player) == CS_LMAOGALOG) + { + if (slidemo->player == &players[consoleplayer]) + localangle = slidemo->angle; + else if (slidemo->player == &players[secondarydisplayplayer]) + localangle2 = slidemo->angle; + }*/ + + if (!slidemo->player->climbing) + { + S_StartSound(slidemo->player->mo, sfx_s3k4a); + slidemo->player->climbing = 5; + } + + slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED); + slidemo->player->glidetime = 0; + slidemo->player->secondjump = 0; + + if (slidemo->player->climbing > 1) + slidemo->momz = slidemo->momx = slidemo->momy = 0; + + if (fofline) + whichside = 0; + + if (!whichside) + { + slidemo->player->lastsidehit = checkline->sidenum[whichside]; + slidemo->player->lastlinehit = (INT16)(checkline - lines); + } + + P_Thrust(slidemo, slidemo->angle, FixedMul(5*FRACUNIT, slidemo->scale)); + } + } +} + static boolean PTR_SlideTraverse(intercept_t *in) { line_t *li; @@ -3321,151 +3451,20 @@ static boolean PTR_SlideTraverse(intercept_t *in) li = in->d.line; - // one-sided linedefs are always solid to sliding movement. - // one-sided linedef - if (!li->backsector) - { - if (P_PointOnLineSide(slidemo->x, slidemo->y, li)) - return true; // don't hit the back side - goto isblocking; - } + if (!PTR_LineIsBlocking(li)) + return true; - if (!(slidemo->flags & MF_MISSILE)) - { - if (li->flags & ML_IMPASSIBLE) - goto isblocking; - - if ((slidemo->flags & (MF_ENEMY|MF_BOSS)) && li->flags & ML_BLOCKMONSTERS) - goto isblocking; - } - - // set openrange, opentop, openbottom - P_LineOpening(li, slidemo); - - if (openrange < slidemo->height) - goto isblocking; // doesn't fit - - if (opentop - slidemo->z < slidemo->height) - goto isblocking; // mobj is too high - - if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, slidemo->scale)) - goto isblocking; // too big a step up - - // this line doesn't block movement - return true; - - // the line does block movement, + // the line blocks movement, // see if it is closer than best so far -isblocking: if (li->polyobj && slidemo->player) { if ((li->polyobj->lines[0]->backsector->flags & SF_TRIGGERSPECIAL_TOUCH) && !(li->polyobj->flags & POF_NOSPECIALS)) P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector); } - if (slidemo->player && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing) - && slidemo->player->charability == CA_GLIDEANDCLIMB) - { - line_t *checkline = li; - sector_t *checksector; - ffloor_t *rover; - fixed_t topheight, bottomheight; - boolean fofline = false; - INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); - - if (!side && li->backsector) - checksector = li->backsector; - else - checksector = li->frontsector; - - if (checksector->ffloors) - { - for (rover = checksector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) - continue; - - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); - - if (topheight < slidemo->z) - continue; - - if (bottomheight > slidemo->z + slidemo->height) - continue; - - // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? - if (rover->master->flags & ML_TFERLINE) - { - size_t linenum = li-checksector->lines[0]; - checkline = rover->master->frontsector->lines[0] + linenum; - fofline = true; - } - - break; - } - } - - // see about climbing on the wall - if (!(checkline->flags & ML_NOCLIMB) && checkline->special != HORIZONSPECIAL) - { - boolean canclimb; - angle_t climbangle, climbline; - INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); - - climbangle = climbline = R_PointToAngle2(li->v1->x, li->v1->y, li->v2->x, li->v2->y); - - if (whichside) // on second side? - climbline += ANGLE_180; - - 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)) - && canclimb) - { - slidemo->angle = climbangle; - /*if (!demoplayback || P_ControlStyle(slidemo->player) == CS_LMAOGALOG) - { - if (slidemo->player == &players[consoleplayer]) - localangle = slidemo->angle; - else if (slidemo->player == &players[secondarydisplayplayer]) - localangle2 = slidemo->angle; - }*/ - - if (!slidemo->player->climbing) - { - S_StartSound(slidemo->player->mo, sfx_s3k4a); - slidemo->player->climbing = 5; - } - - slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED); - slidemo->player->glidetime = 0; - slidemo->player->secondjump = 0; - - if (slidemo->player->climbing > 1) - slidemo->momz = slidemo->momx = slidemo->momy = 0; - - if (fofline) - whichside = 0; - - if (!whichside) - { - slidemo->player->lastsidehit = checkline->sidenum[whichside]; - slidemo->player->lastlinehit = (INT16)(checkline - lines); - } - - P_Thrust(slidemo, slidemo->angle, FixedMul(5*FRACUNIT, slidemo->scale)); - } - } - } + if (slidemo->player && slidemo->player->charability == CA_GLIDEANDCLIMB + && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing)) + PTR_GlideClimbTraverse(li); if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing)) { From bc2d0dcea6690458b3f7973fbd4f5cd0b82609f6 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 2 May 2020 15:25:19 +0200 Subject: [PATCH 06/10] Some minor PTR_GlideClimbTraverse cleanup --- src/p_map.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 3f1f6caf5..db6df59dc 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3343,16 +3343,10 @@ static boolean PTR_LineIsBlocking(line_t *li) static void PTR_GlideClimbTraverse(line_t *li) { line_t *checkline = li; - sector_t *checksector; ffloor_t *rover; fixed_t topheight, bottomheight; boolean fofline = false; - INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); - - if (!side && li->backsector) - checksector = li->backsector; - else - checksector = li->frontsector; + sector_t *checksector = (li->backsector && !P_PointOnLineSide(slidemo->x, slidemo->y, li)) ? li->backsector : li->frontsector; if (checksector->ffloors) { From ddb4c2c97f3f5bfdad660f4ee3e8bc6b95998d8b Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 2 May 2020 15:30:56 +0200 Subject: [PATCH 07/10] Refactor P_PushableCheckBustables --- src/p_mobj.c | 125 ++++++++++++++++++++++++++------------------------- 1 file changed, 64 insertions(+), 61 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index fab6c193f..1d3fe8b46 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1674,77 +1674,80 @@ static void P_PushableCheckBustables(mobj_t *mo) for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) { + ffloor_t *rover; + fixed_t topheight, bottomheight; + if (!node->m_sector) break; - if (node->m_sector->ffloors) + if (!node->m_sector->ffloors) + continue; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - ffloor_t *rover; - fixed_t topheight, bottomheight; + if (!(rover->flags & FF_EXISTS)) + continue; - for (rover = node->m_sector->ffloors; rover; rover = rover->next) + if (!(rover->flags & FF_BUSTUP)) + continue; + + // Needs ML_EFFECT4 flag for pushables to break it + if (!(rover->master->flags & ML_EFFECT4)) + continue; + + if (rover->master->frontsector->crumblestate != CRUMBLE_NONE) + continue; + + topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); + bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); + + // Height checks + if (rover->flags & FF_SHATTERBOTTOM) { - if (!(rover->flags & FF_EXISTS)) continue; + if (mo->z + mo->momz + mo->height < bottomheight) + continue; - if (!(rover->flags & FF_BUSTUP)) continue; - - // Needs ML_EFFECT4 flag for pushables to break it - if (!(rover->master->flags & ML_EFFECT4)) continue; - - if (rover->master->frontsector->crumblestate == CRUMBLE_NONE) - { - topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); - bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); - // Height checks - if (rover->flags & FF_SHATTERBOTTOM) - { - if (mo->z+mo->momz + mo->height < bottomheight) - continue; - - if (mo->z+mo->height > bottomheight) - continue; - } - else if (rover->flags & FF_SPINBUST) - { - if (mo->z+mo->momz > topheight) - continue; - - if (mo->z+mo->height < bottomheight) - continue; - } - else if (rover->flags & FF_SHATTER) - { - if (mo->z+mo->momz > topheight) - continue; - - if (mo->z+mo->momz + mo->height < bottomheight) - continue; - } - else - { - if (mo->z >= topheight) - continue; - - if (mo->z+mo->height < bottomheight) - continue; - } - - EV_CrumbleChain(NULL, rover); // node->m_sector - - // Run a linedef executor?? - if (rover->master->flags & ML_EFFECT5) - P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), mo, node->m_sector); - - goto bustupdone; - } + if (mo->z + mo->height > bottomheight) + continue; } + else if (rover->flags & FF_SPINBUST) + { + if (mo->z + mo->momz > topheight) + continue; + + if (mo->z + mo->height < bottomheight) + continue; + } + else if (rover->flags & FF_SHATTER) + { + if (mo->z + mo->momz > topheight) + continue; + + if (mo->z + mo->momz + mo->height < bottomheight) + continue; + } + else + { + if (mo->z >= topheight) + continue; + + if (mo->z + mo->height < bottomheight) + continue; + } + + EV_CrumbleChain(NULL, rover); // node->m_sector + + // Run a linedef executor?? + if (rover->master->flags & ML_EFFECT5) + P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), mo, node->m_sector); + + P_UnsetThingPosition(mo); + mo->x = oldx; + mo->y = oldy; + P_SetThingPosition(mo); + return; } } -bustupdone: - P_UnsetThingPosition(mo); - mo->x = oldx; - mo->y = oldy; - P_SetThingPosition(mo); } // From 122104815a33f20c7dbad8298e629d5fb647aff9 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 2 May 2020 15:33:15 +0200 Subject: [PATCH 08/10] Revert some very incorrect refactoring --- src/p_mobj.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1d3fe8b46..301f3a8d6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1741,13 +1741,14 @@ static void P_PushableCheckBustables(mobj_t *mo) if (rover->master->flags & ML_EFFECT5) P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), mo, node->m_sector); - P_UnsetThingPosition(mo); - mo->x = oldx; - mo->y = oldy; - P_SetThingPosition(mo); - return; + goto bustupdone; } } +bustupdone: + P_UnsetThingPosition(mo); + mo->x = oldx; + mo->y = oldy; + P_SetThingPosition(mo); } // From 452fd100b8c3e15c67fafb3dfe65b718ff9920d7 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 2 May 2020 15:50:18 +0200 Subject: [PATCH 09/10] Refactor P_CheckBustableBlocks --- src/p_user.c | 244 ++++++++++++++++++++++++++++----------------------- 1 file changed, 136 insertions(+), 108 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 36a1054c6..e7dc69c1f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2532,6 +2532,72 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand return false; // No sand here, Captain! } +static boolean P_PlayerCanBust(player_t *player, ffloor_t *rover) +{ + if (!(rover->flags & FF_EXISTS)) + return false; + + if (!(rover->flags & FF_BUSTUP)) + return false; + + /*if (rover->master->frontsector->crumblestate != CRUMBLE_NONE) + return false;*/ + + // If it's an FF_SHATTER, you can break it just by touching it. + if (rover->flags & FF_SHATTER) + return true; + + // If it's an FF_SPINBUST, you can break it if you are in your spinning frames + // (either from jumping or spindashing). + if (rover->flags & FF_SPINBUST) + { + if ((player->pflags & PF_SPINNING) && !(player->pflags & PF_STARTDASH)) + return true; + + if ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE)) + return true; + } + + // Strong abilities can break even FF_STRONGBUST. + if (player->charability == CA_GLIDEANDCLIMB) + return true; + + if (player->pflags & PF_BOUNCING) + return true; + + if (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY) + return true; + + if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) + return true; + + // Everyone else is out of luck. + if (rover->flags & FF_STRONGBUST) + return false; + + // Spinning (and not jumping) + if ((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED)) + return true; + + // Super + if (player->powers[pw_super]) + return true; + + // Dashmode + if ((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) && player->dashmode >= DASHMODE_THRESHOLD) + return true; + + // NiGHTS drill + if (player->pflags & PF_DRILLING) + return true; + + // Recording for Metal Sonic + if (metalrecording) + return true; + + return false; +} + static void P_CheckBustableBlocks(player_t *player) { msecnode_t *node; @@ -2554,121 +2620,83 @@ static void P_CheckBustableBlocks(player_t *player) for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) { + ffloor_t *rover; + fixed_t topheight, bottomheight; + if (!node->m_sector) break; - if (node->m_sector->ffloors) + if (!node->m_sector->ffloors) + continue; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - ffloor_t *rover; - fixed_t topheight, bottomheight; + if (!P_PlayerCanBust(player, rover)) + continue; - for (rover = node->m_sector->ffloors; rover; rover = rover->next) + topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + + if (((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) + || ((P_MobjFlip(player->mo)*player->mo->momz < 0) && (player->pflags & PF_BOUNCING || ((player->charability2 == CA2_MELEE) && (player->panim == PA_ABILITY2))))) { - if (!(rover->flags & FF_EXISTS)) continue; - - if ((rover->flags & FF_BUSTUP)/* && rover->master->frontsector->crumblestate == CRUMBLE_NONE*/) - { - // If it's an FF_SHATTER, you can break it just by touching it. - if (rover->flags & FF_SHATTER) - goto bust; - - // If it's an FF_SPINBUST, you can break it if you are in your spinning frames - // (either from jumping or spindashing). - if (rover->flags & FF_SPINBUST - && (((player->pflags & PF_SPINNING) && !(player->pflags & PF_STARTDASH)) - || (player->pflags & PF_JUMPED && !(player->pflags & PF_NOJUMPDAMAGE)))) - goto bust; - - // You can always break it if you have CA_GLIDEANDCLIMB - // or if you are bouncing on it - // or you are using CA_TWINSPIN/CA2_MELEE. - if (player->charability == CA_GLIDEANDCLIMB - || (player->pflags & PF_BOUNCING) - || ((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) - || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) - goto bust; - - if (rover->flags & FF_STRONGBUST) - continue; - - // If it's not an FF_STRONGBUST, you can break if you are spinning (and not jumping) - // or you are super - // or you are in dashmode with SF_DASHMODE - // or you are drilling in NiGHTS - // or you are recording for Metal Sonic - if (!((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED)) - && !(player->powers[pw_super]) - && !(((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)) && (player->dashmode >= DASHMODE_THRESHOLD)) - && !(player->pflags & PF_DRILLING) - && !metalrecording) - continue; - - bust: - topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - - if (((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) - || ((P_MobjFlip(player->mo)*player->mo->momz < 0) && (player->pflags & PF_BOUNCING || ((player->charability2 == CA2_MELEE) && (player->panim == PA_ABILITY2))))) - { - topheight -= player->mo->momz; - bottomheight -= player->mo->momz; - } - - // Height checks - if (rover->flags & FF_SHATTERBOTTOM) - { - if (player->mo->z+player->mo->momz + player->mo->height < bottomheight) - continue; - - if (player->mo->z+player->mo->height > bottomheight) - continue; - } - else if (rover->flags & FF_SPINBUST) - { - if (player->mo->z+player->mo->momz > topheight) - continue; - - if (player->mo->z + player->mo->height < bottomheight) - continue; - } - else if (rover->flags & FF_SHATTER) - { - if (player->mo->z + player->mo->momz > topheight) - continue; - - if (player->mo->z+player->mo->momz + player->mo->height < bottomheight) - continue; - } - else - { - if (player->mo->z >= topheight) - continue; - - if (player->mo->z + player->mo->height < bottomheight) - continue; - } - - // Impede the player's fall a bit - if (((rover->flags & FF_SPINBUST) || (rover->flags & FF_SHATTER)) && player->mo->z >= topheight) - player->mo->momz >>= 1; - else if (rover->flags & FF_SHATTER) - { - player->mo->momx >>= 1; - player->mo->momy >>= 1; - } - - //if (metalrecording) - // G_RecordBustup(rover); - - EV_CrumbleChain(NULL, rover); // node->m_sector - - // Run a linedef executor?? - if (rover->master->flags & ML_EFFECT5) - P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), player->mo, node->m_sector); - - goto bustupdone; - } + topheight -= player->mo->momz; + bottomheight -= player->mo->momz; } + + // Height checks + if (rover->flags & FF_SHATTERBOTTOM) + { + if (player->mo->z + player->mo->momz + player->mo->height < bottomheight) + continue; + + if (player->mo->z + player->mo->height > bottomheight) + continue; + } + else if (rover->flags & FF_SPINBUST) + { + if (player->mo->z + player->mo->momz > topheight) + continue; + + if (player->mo->z + player->mo->height < bottomheight) + continue; + } + else if (rover->flags & FF_SHATTER) + { + if (player->mo->z + player->mo->momz > topheight) + continue; + + if (player->mo->z + player->mo->momz + player->mo->height < bottomheight) + continue; + } + else + { + if (player->mo->z >= topheight) + continue; + + if (player->mo->z + player->mo->height < bottomheight) + continue; + } + + // Impede the player's fall a bit + if (((rover->flags & FF_SPINBUST) || (rover->flags & FF_SHATTER)) && player->mo->z >= topheight) + player->mo->momz >>= 1; + else if (rover->flags & FF_SHATTER) + { + player->mo->momx >>= 1; + player->mo->momy >>= 1; + } + + //if (metalrecording) + // G_RecordBustup(rover); + + EV_CrumbleChain(NULL, rover); // node->m_sector + + // Run a linedef executor?? + if (rover->master->flags & ML_EFFECT5) + P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), player->mo, node->m_sector); + + goto bustupdone; } } bustupdone: From d0d25025e122abbeb5eaea121aebc8962910500e Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 3 May 2020 10:01:58 +0200 Subject: [PATCH 10/10] Refactor P_CheckBouncySectors --- src/p_user.c | 197 ++++++++++++++++++++++++--------------------------- 1 file changed, 92 insertions(+), 105 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index e7dc69c1f..3296269cb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2729,122 +2729,109 @@ static void P_CheckBouncySectors(player_t *player) for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) { + ffloor_t *rover; + if (!node->m_sector) break; - if (node->m_sector->ffloors) + if (!node->m_sector->ffloors) + continue; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - ffloor_t *rover; - boolean top = true; + fixed_t bouncestrength; fixed_t topheight, bottomheight; - for (rover = node->m_sector->ffloors; rover; rover = rover->next) + if (!(rover->flags & FF_EXISTS)) + continue; // FOFs should not be bouncy if they don't even "exist" + + if (GETSECSPECIAL(rover->master->frontsector->special, 1) != 15) + continue; // this sector type is required for FOFs to be bouncy + + topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + + if (player->mo->z > topheight) + continue; + + if (player->mo->z + player->mo->height < bottomheight) + continue; + + bouncestrength = P_AproxDistance(rover->master->dx, rover->master->dy)/100; + + if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL) + && oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)) { - if (!(rover->flags & FF_EXISTS)) - continue; // FOFs should not be bouncy if they don't even "exist" - - if (GETSECSPECIAL(rover->master->frontsector->special, 1) != 15) - continue; // this sector type is required for FOFs to be bouncy - - topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - - if (player->mo->z > topheight) - continue; - - if (player->mo->z + player->mo->height < bottomheight) - continue; - - if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL) - && oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)) - top = false; + player->mo->momx = -FixedMul(player->mo->momx,bouncestrength); + player->mo->momy = -FixedMul(player->mo->momy,bouncestrength); + if (player->pflags & PF_SPINNING) { - fixed_t linedist; - - linedist = P_AproxDistance(rover->master->v1->x-rover->master->v2->x, rover->master->v1->y-rover->master->v2->y); - - linedist = FixedDiv(linedist,100*FRACUNIT); - - if (top) - { - fixed_t newmom; - - pslope_t *slope; - if (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) { // Hit top - slope = *rover->t_slope; - } else { // Hit bottom - slope = *rover->b_slope; - } - - momentum.x = player->mo->momx; - momentum.y = player->mo->momy; - momentum.z = player->mo->momz*2; - - if (slope) - P_ReverseQuantizeMomentumToSlope(&momentum, slope); - - newmom = momentum.z = -FixedMul(momentum.z,linedist)/2; - - if (abs(newmom) < (linedist*2)) - { - goto bouncydone; - } - - if (!(rover->master->flags & ML_BOUNCY)) - { - if (newmom > 0) - { - if (newmom < 8*FRACUNIT) - newmom = 8*FRACUNIT; - } - else if (newmom > -8*FRACUNIT && newmom != 0) - newmom = -8*FRACUNIT; - } - - if (newmom > P_GetPlayerHeight(player)/2) - newmom = P_GetPlayerHeight(player)/2; - else if (newmom < -P_GetPlayerHeight(player)/2) - newmom = -P_GetPlayerHeight(player)/2; - - momentum.z = newmom*2; - - if (slope) - P_QuantizeMomentumToSlope(&momentum, slope); - - player->mo->momx = momentum.x; - player->mo->momy = momentum.y; - player->mo->momz = momentum.z/2; - - if (player->pflags & PF_SPINNING) - { - player->pflags &= ~PF_SPINNING; - player->pflags |= P_GetJumpFlags(player); - player->pflags |= PF_THOKKED; - } - } - else - { - player->mo->momx = -FixedMul(player->mo->momx,linedist); - player->mo->momy = -FixedMul(player->mo->momy,linedist); - - if (player->pflags & PF_SPINNING) - { - player->pflags &= ~PF_SPINNING; - player->pflags |= P_GetJumpFlags(player); - player->pflags |= PF_THOKKED; - } - } - - if ((player->pflags & PF_SPINNING) && player->speed < FixedMul(1<mo->scale) && player->mo->momz) - { - player->pflags &= ~PF_SPINNING; - player->pflags |= P_GetJumpFlags(player); - } - - goto bouncydone; + player->pflags &= ~PF_SPINNING; + player->pflags |= P_GetJumpFlags(player); + player->pflags |= PF_THOKKED; } } + else + { + fixed_t newmom; + pslope_t *slope = (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) ? *rover->t_slope : *rover->b_slope; + + momentum.x = player->mo->momx; + momentum.y = player->mo->momy; + momentum.z = player->mo->momz*2; + + if (slope) + P_ReverseQuantizeMomentumToSlope(&momentum, slope); + + newmom = momentum.z = -FixedMul(momentum.z,bouncestrength)/2; + + if (abs(newmom) < (bouncestrength*2)) + goto bouncydone; + + if (!(rover->master->flags & ML_BOUNCY)) + { + if (newmom > 0) + { + if (newmom < 8*FRACUNIT) + newmom = 8*FRACUNIT; + } + else if (newmom < 0) + { + if (newmom > -8*FRACUNIT) + newmom = -8*FRACUNIT; + } + } + + if (newmom > P_GetPlayerHeight(player)/2) + newmom = P_GetPlayerHeight(player)/2; + else if (newmom < -P_GetPlayerHeight(player)/2) + newmom = -P_GetPlayerHeight(player)/2; + + momentum.z = newmom*2; + + if (slope) + P_QuantizeMomentumToSlope(&momentum, slope); + + player->mo->momx = momentum.x; + player->mo->momy = momentum.y; + player->mo->momz = momentum.z/2; + + if (player->pflags & PF_SPINNING) + { + player->pflags &= ~PF_SPINNING; + player->pflags |= P_GetJumpFlags(player); + player->pflags |= PF_THOKKED; + } + } + + if ((player->pflags & PF_SPINNING) && player->speed < FixedMul(1<mo->scale) && player->mo->momz) + { + player->pflags &= ~PF_SPINNING; + player->pflags |= P_GetJumpFlags(player); + } + + goto bouncydone; } } bouncydone: