mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-27 21:01:04 +00:00
Add a bunch of slope physics
I know giant commits all at once like this are a bad thing, but too bad I worked without staging commits and now it's all here at once :)
This commit is contained in:
parent
1f0f6b64c1
commit
db883f6a23
5 changed files with 187 additions and 48 deletions
|
@ -409,6 +409,50 @@ angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byt
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// RotateVector
|
||||||
|
//
|
||||||
|
// Rotates a vector around another vector
|
||||||
|
//
|
||||||
|
void M_VecRotate(v3fixed_t *rotVec, const v3fixed_t *axisVec, const angle_t angle)
|
||||||
|
{
|
||||||
|
// Rotate the point (x,y,z) around the vector (u,v,w)
|
||||||
|
fixed_t ux = FixedMul(axisVec->x, rotVec->x);
|
||||||
|
fixed_t uy = FixedMul(axisVec->x, rotVec->y);
|
||||||
|
fixed_t uz = FixedMul(axisVec->x, rotVec->z);
|
||||||
|
fixed_t vx = FixedMul(axisVec->y, rotVec->x);
|
||||||
|
fixed_t vy = FixedMul(axisVec->y, rotVec->y);
|
||||||
|
fixed_t vz = FixedMul(axisVec->y, rotVec->z);
|
||||||
|
fixed_t wx = FixedMul(axisVec->z, rotVec->x);
|
||||||
|
fixed_t wy = FixedMul(axisVec->z, rotVec->y);
|
||||||
|
fixed_t wz = FixedMul(axisVec->z, rotVec->z);
|
||||||
|
fixed_t sa = FINESINE(angle>>ANGLETOFINESHIFT);
|
||||||
|
fixed_t ca = FINECOSINE(angle>>ANGLETOFINESHIFT);
|
||||||
|
fixed_t ua = ux+vy+wz;
|
||||||
|
fixed_t ax = FixedMul(axisVec->x,ua);
|
||||||
|
fixed_t ay = FixedMul(axisVec->y,ua);
|
||||||
|
fixed_t az = FixedMul(axisVec->z,ua);
|
||||||
|
fixed_t xs = FixedMul(axisVec->x,axisVec->x);
|
||||||
|
fixed_t ys = FixedMul(axisVec->y,axisVec->y);
|
||||||
|
fixed_t zs = FixedMul(axisVec->z,axisVec->z);
|
||||||
|
fixed_t bx = FixedMul(rotVec->x,ys+zs);
|
||||||
|
fixed_t by = FixedMul(rotVec->y,xs+zs);
|
||||||
|
fixed_t bz = FixedMul(rotVec->z,xs+ys);
|
||||||
|
fixed_t cx = FixedMul(axisVec->x,vy+wz);
|
||||||
|
fixed_t cy = FixedMul(axisVec->y,ux+wz);
|
||||||
|
fixed_t cz = FixedMul(axisVec->z,ux+vy);
|
||||||
|
fixed_t dx = FixedMul(bx-cx, ca);
|
||||||
|
fixed_t dy = FixedMul(by-cy, ca);
|
||||||
|
fixed_t dz = FixedMul(bz-cz, ca);
|
||||||
|
fixed_t ex = FixedMul(vz-wy, sa);
|
||||||
|
fixed_t ey = FixedMul(wx-uz, sa);
|
||||||
|
fixed_t ez = FixedMul(uy-vx, sa);
|
||||||
|
|
||||||
|
rotVec->x = ax+dx+ex;
|
||||||
|
rotVec->y = ay+dy+ey;
|
||||||
|
rotVec->z = az+dz+ez;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -977,50 +1021,6 @@ boolean FV_IntersectedPolygon(const fvector_t *vPoly, const fvector_t *vLine, co
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// RotateVector
|
|
||||||
//
|
|
||||||
// Rotates a vector around another vector
|
|
||||||
//
|
|
||||||
void FV_Rotate(fvector_t *rotVec, const fvector_t *axisVec, const angle_t angle)
|
|
||||||
{
|
|
||||||
// Rotate the point (x,y,z) around the vector (u,v,w)
|
|
||||||
fixed_t ux = FixedMul(axisVec->x, rotVec->x);
|
|
||||||
fixed_t uy = FixedMul(axisVec->x, rotVec->y);
|
|
||||||
fixed_t uz = FixedMul(axisVec->x, rotVec->z);
|
|
||||||
fixed_t vx = FixedMul(axisVec->y, rotVec->x);
|
|
||||||
fixed_t vy = FixedMul(axisVec->y, rotVec->y);
|
|
||||||
fixed_t vz = FixedMul(axisVec->y, rotVec->z);
|
|
||||||
fixed_t wx = FixedMul(axisVec->z, rotVec->x);
|
|
||||||
fixed_t wy = FixedMul(axisVec->z, rotVec->y);
|
|
||||||
fixed_t wz = FixedMul(axisVec->z, rotVec->z);
|
|
||||||
fixed_t sa = FINESINE(angle);
|
|
||||||
fixed_t ca = FINECOSINE(angle);
|
|
||||||
fixed_t ua = ux+vy+wz;
|
|
||||||
fixed_t ax = FixedMul(axisVec->x,ua);
|
|
||||||
fixed_t ay = FixedMul(axisVec->y,ua);
|
|
||||||
fixed_t az = FixedMul(axisVec->z,ua);
|
|
||||||
fixed_t xs = FixedMul(axisVec->x,axisVec->x);
|
|
||||||
fixed_t ys = FixedMul(axisVec->y,axisVec->y);
|
|
||||||
fixed_t zs = FixedMul(axisVec->z,axisVec->z);
|
|
||||||
fixed_t bx = FixedMul(rotVec->x,ys+zs);
|
|
||||||
fixed_t by = FixedMul(rotVec->y,xs+zs);
|
|
||||||
fixed_t bz = FixedMul(rotVec->z,xs+ys);
|
|
||||||
fixed_t cx = FixedMul(axisVec->x,vy+wz);
|
|
||||||
fixed_t cy = FixedMul(axisVec->y,ux+wz);
|
|
||||||
fixed_t cz = FixedMul(axisVec->z,ux+vy);
|
|
||||||
fixed_t dx = FixedMul(bx-cx, ca);
|
|
||||||
fixed_t dy = FixedMul(by-cy, ca);
|
|
||||||
fixed_t dz = FixedMul(bz-cz, ca);
|
|
||||||
fixed_t ex = FixedMul(vz-wy, sa);
|
|
||||||
fixed_t ey = FixedMul(wx-uz, sa);
|
|
||||||
fixed_t ez = FixedMul(uy-vx, sa);
|
|
||||||
|
|
||||||
rotVec->x = ax+dx+ex;
|
|
||||||
rotVec->y = ay+dy+ey;
|
|
||||||
rotVec->z = az+dz+ez;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FM_Rotate(fmatrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z)
|
void FM_Rotate(fmatrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z)
|
||||||
{
|
{
|
||||||
#define M(row,col) dest->m[row * 4 + col]
|
#define M(row,col) dest->m[row * 4 + col]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Emacs style mode select -*- C++ -*-
|
// Emacs style mode select -*- C++ -*-
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Copyright(C) 2004 Stephen McGranahan
|
// Copyright(C) 2004 Stephen McGranahan
|
||||||
|
@ -7,12 +7,12 @@
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
@ -114,6 +114,8 @@ float M_VectorYaw(v3float_t v);
|
||||||
float M_VectorPitch(v3float_t v);
|
float M_VectorPitch(v3float_t v);
|
||||||
angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byte AngleAxis, float Rate);
|
angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byte AngleAxis, float Rate);
|
||||||
|
|
||||||
|
void M_VecRotate(v3fixed_t *rotVec, const v3fixed_t *axisVec, const angle_t angle);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
71
src/p_mobj.c
71
src/p_mobj.c
|
@ -1239,7 +1239,11 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
|
||||||
}
|
}
|
||||||
else if (abs(player->rmomx) < FixedMul(STOPSPEED, mo->scale)
|
else if (abs(player->rmomx) < FixedMul(STOPSPEED, mo->scale)
|
||||||
&& abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale)
|
&& abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale)
|
||||||
&& (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING)))
|
&& (!(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)
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// if in a walking frame, stop moving
|
// if in a walking frame, stop moving
|
||||||
if (player->panim == PA_WALK)
|
if (player->panim == PA_WALK)
|
||||||
|
@ -1383,6 +1387,11 @@ void P_XYMovement(mobj_t *mo)
|
||||||
fixed_t xmove, ymove;
|
fixed_t xmove, ymove;
|
||||||
fixed_t oldx, oldy; // reducing bobbing/momentum on ice when up against walls
|
fixed_t oldx, oldy; // reducing bobbing/momentum on ice when up against walls
|
||||||
boolean moved;
|
boolean moved;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
pslope_t *oldslope = NULL;
|
||||||
|
v3fixed_t slopemom;
|
||||||
|
fixed_t predictedz;
|
||||||
|
#endif
|
||||||
|
|
||||||
I_Assert(mo != NULL);
|
I_Assert(mo != NULL);
|
||||||
I_Assert(!P_MobjWasRemoved(mo));
|
I_Assert(!P_MobjWasRemoved(mo));
|
||||||
|
@ -1414,6 +1423,29 @@ void P_XYMovement(mobj_t *mo)
|
||||||
oldx = mo->x;
|
oldx = mo->x;
|
||||||
oldy = mo->y;
|
oldy = mo->y;
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
// adjust various things based on slope
|
||||||
|
if (mo->standingslope) {
|
||||||
|
if (!P_IsObjectOnGround(mo)) { // We fell off at some point? Do the twisty thing!
|
||||||
|
P_SlopeLaunch(mo);
|
||||||
|
xmove = mo->momx;
|
||||||
|
ymove = mo->momy;
|
||||||
|
} else { // Still on the ground.
|
||||||
|
slopemom.x = xmove;
|
||||||
|
slopemom.y = ymove;
|
||||||
|
slopemom.z = 0;
|
||||||
|
P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
|
||||||
|
|
||||||
|
xmove = slopemom.x;
|
||||||
|
ymove = slopemom.y;
|
||||||
|
|
||||||
|
predictedz = mo->z + slopemom.z; // We'll use this later...
|
||||||
|
|
||||||
|
oldslope = mo->standingslope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Pushables can break some blocks
|
// Pushables can break some blocks
|
||||||
if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE)
|
if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE)
|
||||||
P_PushableCheckBustables(mo);
|
P_PushableCheckBustables(mo);
|
||||||
|
@ -1534,6 +1566,29 @@ void P_XYMovement(mobj_t *mo)
|
||||||
if (P_MobjWasRemoved(mo)) // MF_SPECIAL touched a player! O_o;;
|
if (P_MobjWasRemoved(mo)) // MF_SPECIAL touched a player! O_o;;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (moved && oldslope) { // Check to see if we ran off
|
||||||
|
if (oldslope != mo->standingslope) { // First, compare different slopes
|
||||||
|
// Start by quantizing momentum on this slope
|
||||||
|
v3fixed_t test;
|
||||||
|
test.x = mo->momx;
|
||||||
|
test.y = mo->momy;
|
||||||
|
test.z = 0;
|
||||||
|
if (mo->standingslope) // Don't fuss with the rotation if we don't HAVE a slope
|
||||||
|
P_QuantizeMomentumToSlope(&test, mo->standingslope);
|
||||||
|
|
||||||
|
// Now compare the Zs of the different quantizations
|
||||||
|
if (slopemom.z - test.z > 2*FRACUNIT) { // Allow for a bit of sticking - this value can be adjusted later
|
||||||
|
mo->standingslope = oldslope;
|
||||||
|
P_SlopeLaunch(mo);
|
||||||
|
}
|
||||||
|
} else if (predictedz-mo->z > 2*FRACUNIT) { // Now check if we were supposed to stick to this slope
|
||||||
|
mo->standingslope = oldslope;
|
||||||
|
P_SlopeLaunch(mo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check the gravity status.
|
// Check the gravity status.
|
||||||
P_CheckGravity(mo, false);
|
P_CheckGravity(mo, false);
|
||||||
|
|
||||||
|
@ -1819,6 +1874,11 @@ static boolean P_ZMovement(mobj_t *mo)
|
||||||
I_Assert(mo != NULL);
|
I_Assert(mo != NULL);
|
||||||
I_Assert(!P_MobjWasRemoved(mo));
|
I_Assert(!P_MobjWasRemoved(mo));
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (mo->standingslope && !P_IsObjectOnGround(mo))
|
||||||
|
P_SlopeLaunch(mo);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Intercept the stupid 'fall through 3dfloors' bug
|
// Intercept the stupid 'fall through 3dfloors' bug
|
||||||
if (mo->subsector->sector->ffloors)
|
if (mo->subsector->sector->ffloors)
|
||||||
P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0);
|
P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0);
|
||||||
|
@ -2231,6 +2291,11 @@ static void P_PlayerZMovement(mobj_t *mo)
|
||||||
if (!mo->player)
|
if (!mo->player)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (mo->standingslope && !P_IsObjectOnGround(mo))
|
||||||
|
P_SlopeLaunch(mo);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Intercept the stupid 'fall through 3dfloors' bug
|
// Intercept the stupid 'fall through 3dfloors' bug
|
||||||
if (mo->subsector->sector->ffloors)
|
if (mo->subsector->sector->ffloors)
|
||||||
P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0);
|
P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0);
|
||||||
|
@ -3183,6 +3248,10 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|
||||||
|
|
||||||
P_MobjCheckWater(mobj);
|
P_MobjCheckWater(mobj);
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
P_ButteredSlope(mobj);
|
||||||
|
#endif
|
||||||
|
|
||||||
// momentum movement
|
// momentum movement
|
||||||
mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN;
|
mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN;
|
||||||
|
|
||||||
|
|
|
@ -768,6 +768,69 @@ float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori,
|
||||||
(point->z - pori->z) * pnormal->z;
|
(point->z - pori->z) * pnormal->z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// P_QuantizeMomentumToSlope
|
||||||
|
//
|
||||||
|
// When given a vector, rotates it and aligns it to a slope
|
||||||
|
void P_QuantizeMomentumToSlope(v3fixed_t *momentum, pslope_t *slope)
|
||||||
|
{
|
||||||
|
v3fixed_t axis;
|
||||||
|
axis.x = -slope->d.y;
|
||||||
|
axis.y = slope->d.x;
|
||||||
|
axis.z = 0;
|
||||||
|
|
||||||
|
M_VecRotate(momentum, &axis, 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.
|
||||||
|
v3fixed_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;
|
||||||
|
|
||||||
|
CONS_Printf("Launched off of slope.\n");
|
||||||
|
mo->standingslope = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://yourlogicalfallacyis.com/slippery-slope
|
||||||
|
// Handles sliding down slopes, like if they were made of butter :)
|
||||||
|
void P_ButteredSlope(mobj_t *mo)
|
||||||
|
{
|
||||||
|
fixed_t thrust;
|
||||||
|
|
||||||
|
if (!mo->standingslope)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (abs(mo->standingslope->zdelta) < FRACUNIT/2)
|
||||||
|
return; // Don't apply physics to slopes that aren't steep enough
|
||||||
|
|
||||||
|
thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1);
|
||||||
|
|
||||||
|
if (!(mo->player && (mo->player->pflags & PF_SPINNING))) {
|
||||||
|
if (mo->momx || mo->momy) // Slightly increase thrust based on the object's speed parallel to the slope direction
|
||||||
|
thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/4);
|
||||||
|
// This solves the issue of being able to zigzag up steep slopes
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiply by gravity
|
||||||
|
thrust = FixedMul(thrust, FRACUNIT/2); // TODO actually get this
|
||||||
|
|
||||||
|
P_Thrust(mo, mo->standingslope->xydirection, thrust);
|
||||||
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
#endif // #ifdef ESLOPE
|
#endif // #ifdef ESLOPE
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,11 @@ float P_GetZAtf(pslope_t *slope, float x, float y);
|
||||||
float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori,
|
float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori,
|
||||||
const v3float_t *pnormal);
|
const v3float_t *pnormal);
|
||||||
|
|
||||||
|
// Lots of physics-based bullshit
|
||||||
|
void P_QuantizeMomentumToSlope(v3fixed_t *momentum, pslope_t *slope);
|
||||||
|
void P_SlopeLaunch(mobj_t *mo);
|
||||||
|
void P_ButteredSlope(mobj_t *mo);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
Loading…
Reference in a new issue