diff --git a/src/p_local.h b/src/p_local.h index a5f3d313c..a029b67b6 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -168,6 +168,7 @@ boolean P_AutoPause(void); void P_DoJumpShield(player_t *player); void P_DoBubbleBounce(player_t *player); +boolean P_TryClimb(player_t *player, line_t *line); void P_DoAbilityBounce(player_t *player, boolean changemomz); void P_TwinSpinRejuvenate(player_t *player, mobjtype_t type); void P_BlackOw(player_t *player); diff --git a/src/p_map.c b/src/p_map.c index 40fee7b46..2314b7964 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3262,129 +3262,6 @@ isblocking: return false; // stop } -// -// 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; - subsector_t *glidesector; - fixed_t floorz, ceilingz; - - platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); - platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); - - glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); - -#ifdef ESLOPE - floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight; - ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight; -#else - floorz = glidesector->sector->floorheight; - ceilingz = glidesector->sector->ceilingheight; -#endif - - if (glidesector->sector != player->mo->subsector->sector) - { - boolean floorclimb = false; - fixed_t topheight, bottomheight; - - 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)) - continue; - - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - -#ifdef ESLOPE - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y); -#endif - - floorclimb = true; - - if (player->mo->eflags & MFE_VERTICALFLIP) - { - if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight)) - { - floorclimb = true; - } - if (topheight < player->mo->z) // Waaaay below the ledge. - { - floorclimb = false; - } - if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) - { - floorclimb = false; - } - } - else - { - if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight)) - { - floorclimb = true; - } - if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. - { - floorclimb = false; - } - if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) - { - floorclimb = false; - } - } - - if (floorclimb) - break; - } - } - - if (player->mo->eflags & MFE_VERTICALFLIP) - { - if ((floorz <= player->mo->z + player->mo->height) - && ((player->mo->z + player->mo->height - player->mo->momz) <= floorz)) - floorclimb = true; - - if ((floorz > player->mo->z) - && glidesector->sector->floorpic == skyflatnum) - return false; - - if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz) - || (player->mo->z + player->mo->height <= floorz)) - floorclimb = true; - } - else - { - if ((ceilingz >= player->mo->z) - && ((player->mo->z - player->mo->momz) >= ceilingz)) - floorclimb = true; - - if ((ceilingz < player->mo->z+player->mo->height) - && glidesector->sector->ceilingpic == skyflatnum) - return false; - - if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < floorz) - || (player->mo->z >= ceilingz)) - floorclimb = true; - } - - if (!floorclimb) - return false; - - return true; - } - - return false; -} - // // PTR_SlideTraverse // @@ -3438,111 +3315,7 @@ isblocking: 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; - -#ifdef ESLOPE - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); -#endif - - if (topheight < slidemo->z) - continue; - - 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)); - } - } - } + P_TryClimb(slidemo->player, li); if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing)) { diff --git a/src/p_user.c b/src/p_user.c index 898286490..f029f7f72 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4907,6 +4907,246 @@ void P_DoBubbleBounce(player_t *player) player->mo->momz = FixedMul(player->mo->momz, 5*FRACUNIT/4); } +// +// 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; + subsector_t *glidesector; + fixed_t floorz, ceilingz; + + platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); + platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); + + glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); + +#ifdef ESLOPE + floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight; + ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight; +#else + floorz = glidesector->sector->floorheight; + ceilingz = glidesector->sector->ceilingheight; +#endif + + if (glidesector->sector != player->mo->subsector->sector) + { + boolean floorclimb = false; + fixed_t topheight, bottomheight; + + 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)) + continue; + + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y); +#endif + + floorclimb = true; + + if (player->mo->eflags & MFE_VERTICALFLIP) + { + if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight)) + { + floorclimb = true; + } + if (topheight < player->mo->z) // Waaaay below the ledge. + { + floorclimb = false; + } + if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) + { + floorclimb = false; + } + } + else + { + if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight)) + { + floorclimb = true; + } + if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. + { + floorclimb = false; + } + if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) + { + floorclimb = false; + } + } + + if (floorclimb) + break; + } + } + + if (player->mo->eflags & MFE_VERTICALFLIP) + { + if ((floorz <= player->mo->z + player->mo->height) + && ((player->mo->z + player->mo->height - player->mo->momz) <= floorz)) + floorclimb = true; + + if ((floorz > player->mo->z) + && glidesector->sector->floorpic == skyflatnum) + return false; + + if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz) + || (player->mo->z + player->mo->height <= floorz)) + floorclimb = true; + } + else + { + if ((ceilingz >= player->mo->z) + && ((player->mo->z - player->mo->momz) >= ceilingz)) + floorclimb = true; + + if ((ceilingz < player->mo->z+player->mo->height) + && glidesector->sector->ceilingpic == skyflatnum) + return false; + + if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < floorz) + || (player->mo->z >= ceilingz)) + floorclimb = true; + } + + if (!floorclimb) + return false; + + return true; + } + + return false; +} + +// P_TryClimb +// +// Attempts to climb a line from the player's current position +// Returns whether or not the line was climbed +// +boolean P_TryClimb(player_t *player, line_t *line) +{ + if (player && (player->pflags & PF_GLIDING || player->climbing) + && player->charability == CA_GLIDEANDCLIMB) + { + mobj_t *mo = player->mo; + line_t *checkline = line; + sector_t *checksector; + ffloor_t *rover; + fixed_t topheight, bottomheight; + boolean fofline = false; + INT32 side = P_PointOnLineSide(mo->x, mo->y, line); + + if (!side && line->backsector) + checksector = line->backsector; + else + checksector = line->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; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, mo->x, mo->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, mo->x, mo->y); +#endif + + if (topheight < mo->z) + continue; + + if (bottomheight > mo->z + mo->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 = line-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(mo->x, mo->y, line); + + climbangle = climbline = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y); + + if (whichside) // on second side? + climbline += ANGLE_180; + + climbangle += (ANGLE_90 * (whichside ? -1 : 1)); + + canclimb = (line->backsector ? P_IsClimbingValid(player, climbangle) : true); + + if (((!player->climbing && abs((signed)(mo->angle - ANGLE_90 - climbline)) < ANGLE_45) + || (player->climbing == 1 && abs((signed)(mo->angle - climbline)) < ANGLE_135)) + && canclimb) + { + mo->angle = climbangle; + /*if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) + { + if (player == &players[consoleplayer]) + localangle = mo->angle; + else if (player == &players[secondarydisplayplayer]) + localangle2 = mo->angle; + }*/ + + if (!player->climbing) + { + S_StartSound(player->mo, sfx_s3k4a); + player->climbing = 5; + } + + player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED); + player->glidetime = 0; + player->secondjump = 0; + + if (player->climbing > 1) + mo->momz = mo->momx = mo->momy = 0; + + if (fofline) + whichside = 0; + + if (!whichside) + { + player->lastsidehit = checkline->sidenum[whichside]; + player->lastlinehit = (INT16)(checkline - lines); + } + + P_Thrust(mo, mo->angle, FixedMul(5*FRACUNIT, mo->scale)); + return true; + } + } + } + return false; +} + // // P_DoAbilityBounce //