From 12da89b1ce2993a52cd17402d530be51827332da Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 23 Jan 2017 01:39:12 +0000 Subject: [PATCH] Late night commit! * Seriously reworked a lot of stuff behind the scenes, thanks to Red's comments. * More consistent behaviour. * Launching power is now scaled to the slope's angle relative to the wall you hit, so no massive launches when you hit the side of a steep slope. * The code is a lot messier and the function name doesn't make any sense any more, so I need to clean that up in the morning. * Need to figure out how to prevent tiny launches that uncurl you when spindashing up against walls. * Spindashing trails now takes into account vertical momentum as well as horizontal - it was stupid not seeing your spintrail just because you weren't moving very fast horizontally! No exe uploaded because it's almost 2am. --- src/p_mobj.c | 28 +++++++++++++++++++++++----- src/p_slopes.c | 37 ++++++++++++++++++++++--------------- src/p_slopes.h | 2 +- src/p_user.c | 2 +- 4 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 0c4ae6488..38e88da90 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2121,14 +2121,19 @@ void P_XYMovement(mobj_t *mo) if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !(mo->eflags & MFE_SPRUNG)) { +#ifdef ESLOPE + pslope_t *transferslope = NULL; + fixed_t transfermomz = 0; + if (oldslope && (P_MobjFlip(mo)*(predictedz - mo->z) > 0)) // Only for moving up (relative to gravity), otherwise there's a failed launch when going down slopes and hitting walls + { + transferslope = ((mo->standingslope) ? mo->standingslope : oldslope); + transfermomz = P_PrepareSlopeToWallTransfer(mo, transferslope); // This isn't the end of it; momz will be scaled based upon the angle of movement after collision, and then it'll be applied. + } +#endif + // blocked move moved = false; -#ifdef ESLOPE - if (oldslope && predictedz > mo->z) // Only for moving up, otherwise there's a failed launch when going down slopes and hitting walls - P_SlopeToWallTransfer(mo); -#endif - if (player) { if (player->bot) B_MoveBlocked(player); @@ -2185,6 +2190,19 @@ void P_XYMovement(mobj_t *mo) { // try to slide along it P_SlideMove(mo); xmove = ymove = 0; +#ifdef ESLOPE + if (transfermomz && transferslope) // Scale transfer momentum based on how head-on it is to the slope. + { + angle_t relation = (transferslope->xydirection - R_PointToAngle2(0, 0, mo->momx, mo->momy)); + fixed_t scalefactor = abs(FINESINE((relation >> ANGLETOFINESHIFT) & FINEMASK)); + transfermomz = FixedMul(transfermomz, scalefactor); + if ((P_MobjFlip(mo)*(transfermomz - mo->momz)) > 2*FRACUNIT) // Do the actual launch! + { + mo->standingslope = NULL; + mo->momz = transfermomz; + } + } +#endif } else if (mo->type == MT_SPINFIRE) { diff --git a/src/p_slopes.c b/src/p_slopes.c index 69f0b756a..3afd51cba 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -808,24 +808,31 @@ void P_SlopeLaunch(mobj_t *mo) // P_SlopeToWallTransfer // // Handles slope-to-wall transfer for objects. -void P_SlopeToWallTransfer(mobj_t *mo) +fixed_t P_PrepareSlopeToWallTransfer(mobj_t *mo, pslope_t *slope) { - if (!(mo->standingslope->flags & SL_NOPHYSICS)) // If there's physics, time for launching. - { - // Doesn't kill the vertical momentum as much as P_SlopeLaunch does. - vector3_t slopemom; - slopemom.x = mo->momx; - slopemom.y = mo->momy; - slopemom.z = 3*(mo->momz/2); - P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); + vector3_t slopemom, axis; + angle_t ang; - mo->momx = slopemom.x; - mo->momy = slopemom.y; - mo->momz = 2*(slopemom.z/3); - } + if (mo->standingslope->flags & SL_NOPHYSICS) + return 0; - //CONS_Printf("Transferred off of slope.\n"); - mo->standingslope = NULL; + // If there's physics, time for launching. + // Doesn't kill the vertical momentum as much as P_SlopeLaunch does. + ang = slope->zangle + ANG15*((slope->zangle > 0) ? 1 : -1); + if (ang > ANGLE_90 && ang < ANGLE_180) + ang = ((slope->zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards + + slopemom.x = mo->momx; + slopemom.y = mo->momy; + slopemom.z = 3*(mo->momz/2); + + axis.x = -slope->d.y; + axis.y = slope->d.x; + axis.z = 0; + + FV3_Rotate(&slopemom, &axis, ang >> ANGLETOFINESHIFT); + + return 2*(slopemom.z/3); } // Function to help handle landing on slopes diff --git a/src/p_slopes.h b/src/p_slopes.h index 6975516ed..ab102fcc0 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -37,7 +37,7 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y); 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_SlopeToWallTransfer(mobj_t *mo); +fixed_t P_PrepareSlopeToWallTransfer(mobj_t *mo, pslope_t *slope); 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 09fec73c0..32f8d5e89 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6895,7 +6895,7 @@ static void P_MovePlayer(player_t *player) P_ResetScore(player); // Show the "THOK!" graphic when spinning quickly across the ground. (even applies to non-spinners, in the case of zoom tubes) - if (player->pflags & PF_SPINNING && player->speed > FixedMul(15<mo->scale) && !(player->pflags & PF_JUMPED)) + if (player->pflags & PF_SPINNING && P_AproxDistance(player->speed, player->mo->momz) > FixedMul(15<mo->scale) && !(player->pflags & PF_JUMPED)) { P_SpawnSpinMobj(player, player->spinitem); if (demorecording)