Readd walltransfer and toss it behind a define

This is going to be turned into a mapheader option later on to keep compat with RR maps
This commit is contained in:
NepDisk 2024-09-08 13:56:45 -04:00
parent 96bac94e41
commit be5cbdcc9f
3 changed files with 72 additions and 3 deletions

View file

@ -1625,7 +1625,6 @@ void P_XYMovement(mobj_t *mo)
S_StartSound(mo, mo->info->activesound);
//{ SRB2kart - Orbinaut, Ballhog
// Ballhog dies on contact with walls
if (mo->type == MT_ORBINAUT || mo->type == MT_BALLHOG)
{
mobj_t *fx;
@ -1735,12 +1734,44 @@ void P_XYMovement(mobj_t *mo)
return;
}
}
if (mo->flags & MF_SLIDEME|MF_PUSHABLE)
{
if (player || mo->flags & MF_SLIDEME|MF_PUSHABLE)
{ // try to slide along it
#ifdef WALLTRANSFER
// Wall transfer part 1.
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);
if (((transferslope->zangle < ANGLE_180) ? transferslope->zangle : InvAngle(transferslope->zangle)) >= ANGLE_45) // Prevent some weird stuff going on on shallow slopes.
transfermomz = P_GetWallTransferMomZ(mo, transferslope);
}
#endif
P_SlideMove(mo);
if (P_MobjWasRemoved(mo))
return;
xmove = ymove = 0;
#ifdef WALLTRANSFER
// Wall transfer part 2.
if (transfermomz && transferslope) // Are we "transferring onto the wall" (really just a disguised vertical launch)?
{
angle_t relation; // Scale transfer momentum based on how head-on it is to the slope.
if (mo->momx || mo->momy) // "Guess" the angle of the wall you hit using new momentum
relation = transferslope->xydirection - R_PointToAngle2(0, 0, mo->momx, mo->momy);
else // Give it for free, I guess.
relation = ANGLE_90;
transfermomz = FixedMul(transfermomz,
abs(FINESINE((relation >> ANGLETOFINESHIFT) & FINEMASK)));
if (P_MobjFlip(mo)*(transfermomz - mo->momz) > 2*FRACUNIT) // Do the actual launch!
{
mo->momz = transfermomz;
mo->standingslope = NULL;
}
}
#endif
}
//
}

View file

@ -1015,6 +1015,41 @@ void P_SlopeLaunch(mobj_t *mo)
mo->terrain = NULL;
}
#ifdef WALLTRANSFER
//
// P_GetWallTransferMomZ
//
// It would be nice to have a single function that does everything necessary for slope-to-wall transfer.
// However, it needs to be seperated out in P_XYMovement to take into account momentum before and after hitting the wall.
// This just performs the necessary calculations for getting the base vertical momentum; the horizontal is already reasonably calculated by P_SlideMove.
fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope)
{
vector3_t slopemom, axis;
angle_t ang;
if (mo->standingslope->flags & SL_NOPHYSICS)
return 0;
// 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);
}
#endif
// Function to help handle landing on slopes
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
{

View file

@ -101,6 +101,9 @@ boolean P_CanApplySlopePhysics(mobj_t *mo, pslope_t *slope);
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
void P_SlopeLaunch(mobj_t *mo);
#ifdef WALLTRANSFER
fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope);
#endif
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope);
void P_ButteredSlope(mobj_t *mo);