mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-27 22:52:41 +00:00
Improve slope physics on solid middle textures
This commit is contained in:
parent
3a62ebbe3e
commit
e67e225ff2
10 changed files with 189 additions and 35 deletions
|
@ -399,6 +399,7 @@ extern camera_t *mapcampointer;
|
|||
extern fixed_t tmx;
|
||||
extern fixed_t tmy;
|
||||
extern pslope_t *tmfloorslope, *tmceilingslope;
|
||||
extern line_t *tmfloorline, *tmceilingline;
|
||||
|
||||
/* cphipps 2004/08/30 */
|
||||
extern void P_MapStart(void);
|
||||
|
|
27
src/p_map.c
27
src/p_map.c
|
@ -55,6 +55,7 @@ mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz
|
|||
mobj_t *tmhitthing; // the solid thing you bumped into (for collisions)
|
||||
ffloor_t *tmfloorrover, *tmceilingrover;
|
||||
pslope_t *tmfloorslope, *tmceilingslope;
|
||||
line_t *tmfloorline, *tmceilingline;
|
||||
|
||||
// keep track of the line that lowers the ceiling,
|
||||
// so missiles don't explode against sky hack walls
|
||||
|
@ -1760,6 +1761,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing)
|
|||
tmfloorz = thing->z + thing->height;
|
||||
tmfloorrover = NULL;
|
||||
tmfloorslope = NULL;
|
||||
tmfloorline = NULL;
|
||||
}
|
||||
return CHECKTHING_COLLIDE;
|
||||
}
|
||||
|
@ -1779,6 +1781,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing)
|
|||
tmfloorz = tmceilingz = topz; // block while in air
|
||||
tmceilingrover = NULL;
|
||||
tmceilingslope = NULL;
|
||||
tmceilingline = NULL;
|
||||
tmfloorthing = thing; // needed for side collision
|
||||
|
||||
collide = CHECKTHING_COLLIDE;
|
||||
|
@ -1788,6 +1791,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing)
|
|||
tmceilingz = topz;
|
||||
tmceilingrover = NULL;
|
||||
tmceilingslope = NULL;
|
||||
tmceilingline = NULL;
|
||||
tmfloorthing = thing; // thing we may stand on
|
||||
|
||||
collide = CHECKTHING_COLLIDE;
|
||||
|
@ -1805,6 +1809,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing)
|
|||
tmceilingz = thing->z;
|
||||
tmceilingrover = NULL;
|
||||
tmceilingslope = NULL;
|
||||
tmceilingline = NULL;
|
||||
}
|
||||
return CHECKTHING_COLLIDE;
|
||||
}
|
||||
|
@ -1824,6 +1829,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing)
|
|||
tmfloorz = tmceilingz = topz; // block while in air
|
||||
tmfloorrover = NULL;
|
||||
tmfloorslope = NULL;
|
||||
tmfloorline = NULL;
|
||||
tmfloorthing = thing; // needed for side collision
|
||||
|
||||
collide = CHECKTHING_COLLIDE;
|
||||
|
@ -1833,6 +1839,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing)
|
|||
tmfloorz = topz;
|
||||
tmfloorrover = NULL;
|
||||
tmfloorslope = NULL;
|
||||
tmfloorline = NULL;
|
||||
tmfloorthing = thing; // thing we may stand on
|
||||
|
||||
collide = CHECKTHING_COLLIDE;
|
||||
|
@ -2000,6 +2007,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
|||
ceilingline = ld;
|
||||
tmceilingrover = openceilingrover;
|
||||
tmceilingslope = opentopslope;
|
||||
tmceilingline = opentopline;
|
||||
}
|
||||
|
||||
if (openbottom > tmfloorz)
|
||||
|
@ -2007,6 +2015,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
|||
tmfloorz = openbottom;
|
||||
tmfloorrover = openfloorrover;
|
||||
tmfloorslope = openbottomslope;
|
||||
tmfloorline = openbottomline;
|
||||
}
|
||||
|
||||
if (highceiling > tmdrpoffceilz)
|
||||
|
@ -2057,6 +2066,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight;
|
||||
tmfloorrover = NULL;
|
||||
tmceilingrover = NULL;
|
||||
tmfloorline = NULL;
|
||||
tmceilingline = NULL;
|
||||
tmfloorslope = newsubsec->sector->f_slope;
|
||||
tmceilingslope = newsubsec->sector->c_slope;
|
||||
|
||||
|
@ -2642,6 +2653,8 @@ boolean PIT_PushableMoved(mobj_t *thing)
|
|||
ffloor_t *oldceilrover = tmceilingrover;
|
||||
pslope_t *oldfslope = tmfloorslope;
|
||||
pslope_t *oldcslope = tmceilingslope;
|
||||
line_t *oldfline = tmfloorline;
|
||||
line_t *oldcline = tmceilingline;
|
||||
|
||||
// Move the player
|
||||
P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true);
|
||||
|
@ -2658,6 +2671,8 @@ boolean PIT_PushableMoved(mobj_t *thing)
|
|||
tmceilingrover = oldceilrover;
|
||||
tmfloorslope = oldfslope;
|
||||
tmceilingslope = oldcslope;
|
||||
tmfloorline = oldfline;
|
||||
tmceilingline = oldcline;
|
||||
thing->momz = stand->momz;
|
||||
}
|
||||
else
|
||||
|
@ -2899,11 +2914,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
// Assign thing's standingslope if needed
|
||||
if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) {
|
||||
if (!startingonground && tmfloorslope)
|
||||
P_HandleSlopeLanding(thing, tmfloorslope);
|
||||
P_HandleSlopeLanding(thing, tmfloorslope, tmfloorline);
|
||||
|
||||
if (thing->momz <= 0)
|
||||
{
|
||||
thing->standingslope = tmfloorslope;
|
||||
thing->standingline = tmfloorline;
|
||||
P_SetPitchRollFromSlope(thing, thing->standingslope);
|
||||
|
||||
if (thing->momz == 0 && thing->player && !startingonground)
|
||||
|
@ -2912,11 +2928,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
}
|
||||
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) {
|
||||
if (!startingonground && tmceilingslope)
|
||||
P_HandleSlopeLanding(thing, tmceilingslope);
|
||||
P_HandleSlopeLanding(thing, tmceilingslope, tmceilingline);
|
||||
|
||||
if (thing->momz >= 0)
|
||||
{
|
||||
thing->standingslope = tmceilingslope;
|
||||
thing->standingline = tmceilingline;
|
||||
P_SetPitchRollFromSlope(thing, thing->standingslope);
|
||||
|
||||
if (thing->momz == 0 && thing->player && !startingonground)
|
||||
|
@ -2924,8 +2941,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
}
|
||||
}
|
||||
}
|
||||
else // don't set standingslope if you're not going to clip against it
|
||||
else
|
||||
{
|
||||
// don't set standingslope or standingline if you're not going to clip against them
|
||||
thing->standingslope = NULL;
|
||||
thing->standingline = NULL;
|
||||
}
|
||||
|
||||
thing->x = x;
|
||||
thing->y = y;
|
||||
|
|
|
@ -280,6 +280,7 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1)
|
|||
fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
|
||||
pslope_t *opentopslope, *openbottomslope;
|
||||
ffloor_t *openfloorrover, *openceilingrover;
|
||||
line_t *opentopline, *openbottomline;
|
||||
|
||||
// P_CameraLineOpening
|
||||
// P_LineOpening, but for camera
|
||||
|
@ -440,6 +441,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
I_Assert(back != NULL);
|
||||
|
||||
openfloorrover = openceilingrover = NULL;
|
||||
opentopline = openbottomline = NULL;
|
||||
|
||||
if (linedef->polyobj)
|
||||
{
|
||||
// set these defaults so that polyobjects don't interfere with collision above or below them
|
||||
|
@ -544,6 +547,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if ((linedef->flags & ML_MIDPEG) != 0) {
|
||||
opentopslope = openbottomslope;
|
||||
}
|
||||
opentopline = linedef;
|
||||
}
|
||||
} else { // Above
|
||||
if (openbottom < textop) {
|
||||
|
@ -551,6 +555,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if ((linedef->flags & ML_MIDPEG) == 0) {
|
||||
openbottomslope = opentopslope;
|
||||
}
|
||||
openbottomline = linedef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y);
|
|||
extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
|
||||
extern pslope_t *opentopslope, *openbottomslope;
|
||||
extern ffloor_t *openfloorrover, *openceilingrover;
|
||||
extern line_t *opentopline, *openbottomline;
|
||||
|
||||
void P_LineOpening(line_t *plinedef, mobj_t *mobj);
|
||||
|
||||
|
|
31
src/p_mobj.c
31
src/p_mobj.c
|
@ -1672,6 +1672,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
fixed_t oldx, oldy; // reducing bobbing/momentum on ice when up against walls
|
||||
boolean moved;
|
||||
pslope_t *oldslope = NULL;
|
||||
line_t *oldstandingline = NULL;
|
||||
vector3_t slopemom = {0,0,0};
|
||||
fixed_t predictedz = 0;
|
||||
|
||||
|
@ -1704,7 +1705,10 @@ void P_XYMovement(mobj_t *mo)
|
|||
oldy = mo->y;
|
||||
|
||||
if (mo->flags & MF_NOCLIPHEIGHT)
|
||||
{
|
||||
mo->standingslope = NULL;
|
||||
mo->standingline = NULL;
|
||||
}
|
||||
|
||||
// adjust various things based on slope
|
||||
if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) {
|
||||
|
@ -1716,7 +1720,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
slopemom.x = xmove;
|
||||
slopemom.y = ymove;
|
||||
slopemom.z = 0;
|
||||
P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
|
||||
P_QuantizeObjectMomentumToSlope(mo, &slopemom);
|
||||
|
||||
xmove = slopemom.x;
|
||||
ymove = slopemom.y;
|
||||
|
@ -1724,6 +1728,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
predictedz = mo->z + slopemom.z; // We'll use this later...
|
||||
|
||||
oldslope = mo->standingslope;
|
||||
oldstandingline = mo->standingline;
|
||||
}
|
||||
} else if (P_IsObjectOnGround(mo) && !mo->momz)
|
||||
predictedz = mo->z;
|
||||
|
@ -1799,12 +1804,16 @@ void P_XYMovement(mobj_t *mo)
|
|||
{ // try to slide along it
|
||||
// Wall transfer part 1.
|
||||
pslope_t *transferslope = NULL;
|
||||
line_t *transferline = 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
|
||||
{
|
||||
angle_t zangle;
|
||||
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);
|
||||
transferline = ((mo->standingline) ? mo->standingline : oldstandingline);
|
||||
zangle = P_GetStandingSlopeZAngle(transferslope, transferline);
|
||||
if (((zangle < ANGLE_180) ? zangle : InvAngle(zangle)) >= ANGLE_45) // Prevent some weird stuff going on on shallow slopes.
|
||||
transfermomz = P_GetWallTransferMomZ(mo, transferslope, transferline);
|
||||
}
|
||||
|
||||
P_SlideMove(mo);
|
||||
|
@ -1817,7 +1826,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
{
|
||||
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);
|
||||
relation = P_GetStandingSlopeDirection(transferslope, transferline) - R_PointToAngle2(0, 0, mo->momx, mo->momy);
|
||||
else // Give it for free, I guess.
|
||||
relation = ANGLE_90;
|
||||
transfermomz = FixedMul(transfermomz,
|
||||
|
@ -1826,6 +1835,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
{
|
||||
mo->momz = transfermomz;
|
||||
mo->standingslope = NULL;
|
||||
mo->standingline = NULL;
|
||||
if (player)
|
||||
{
|
||||
player->powers[pw_justlaunched] = 2;
|
||||
|
@ -1875,7 +1885,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
oldangle = FixedMul((signed)oldslope->zangle, FINECOSINE((moveangle - oldslope->xydirection) >> ANGLETOFINESHIFT));
|
||||
|
||||
if (mo->standingslope)
|
||||
newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT));
|
||||
newangle = FixedMul((signed)P_GetObjectStandingSlopeZAngle(mo), FINECOSINE((moveangle - P_GetObjectStandingSlopeDirection(mo)) >> ANGLETOFINESHIFT));
|
||||
else
|
||||
newangle = 0;
|
||||
|
||||
|
@ -1899,7 +1909,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
}
|
||||
} else if (moved && mo->standingslope && predictedz) {
|
||||
angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
|
||||
angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT));
|
||||
angle_t newangle = FixedMul((signed)P_GetObjectStandingSlopeZAngle(mo), FINECOSINE((moveangle - P_GetObjectStandingSlopeDirection(mo)) >> ANGLETOFINESHIFT));
|
||||
|
||||
/*CONS_Printf("flat to angle %f - predicted z of %f\n",
|
||||
FIXED_TO_FLOAT(AngleFixed(ANGLE_MAX-newangle)),
|
||||
|
@ -2432,8 +2442,9 @@ boolean P_ZMovement(mobj_t *mo)
|
|||
if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM))
|
||||
{
|
||||
mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
|
||||
mo->standingline = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingline : tmfloorline;
|
||||
P_SetPitchRollFromSlope(mo, mo->standingslope);
|
||||
P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope);
|
||||
P_ReverseQuantizeObjectMomentumToSlope(mo, &mom);
|
||||
}
|
||||
|
||||
// hit the floor
|
||||
|
@ -2579,7 +2590,7 @@ boolean P_ZMovement(mobj_t *mo)
|
|||
mom.z = tmfloorthing->momz;
|
||||
|
||||
if (mo->standingslope) { // MT_STEAM will never have a standingslope, see above.
|
||||
P_QuantizeMomentumToSlope(&mom, mo->standingslope);
|
||||
P_QuantizeObjectMomentumToSlope(mo, &mom);
|
||||
}
|
||||
|
||||
mo->momx = mom.x;
|
||||
|
@ -2825,7 +2836,9 @@ void P_PlayerZMovement(mobj_t *mo)
|
|||
|
||||
if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) {
|
||||
// Handle landing on slope during Z movement
|
||||
P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope));
|
||||
P_HandleSlopeLanding(mo,
|
||||
(mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope),
|
||||
(mo->eflags & MFE_VERTICALFLIP ? tmceilingline : tmfloorline));
|
||||
}
|
||||
|
||||
if (P_MobjFlip(mo)*mo->momz < 0) // falling
|
||||
|
|
|
@ -412,7 +412,9 @@ typedef struct mobj_s
|
|||
INT32 cusval;
|
||||
INT32 cvmem;
|
||||
|
||||
struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?)
|
||||
struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) (it does)
|
||||
|
||||
struct line_s *standingline; // The line that the object is standing on
|
||||
|
||||
boolean resetinterp; // if true, some fields should not be interpolated (see R_InterpolateMobjState implementation)
|
||||
boolean colorized; // Whether the mobj uses the rainbow colormap
|
||||
|
|
|
@ -1746,7 +1746,8 @@ typedef enum
|
|||
MD2_DISPOFFSET = 1<<23,
|
||||
MD2_DRAWONLYFORPLAYER = 1<<24,
|
||||
MD2_DONTDRAWFORVIEWMOBJ = 1<<25,
|
||||
MD2_TRANSLATION = 1<<26
|
||||
MD2_TRANSLATION = 1<<26,
|
||||
MD2_STANDINGLINE = 1<<27
|
||||
} mobj_diff2_t;
|
||||
|
||||
typedef enum
|
||||
|
@ -1953,6 +1954,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
diff2 |= MD2_CEILINGROVER;
|
||||
if (mobj->standingslope)
|
||||
diff2 |= MD2_SLOPE;
|
||||
if (mobj->standingline)
|
||||
diff2 |= MD2_STANDINGLINE;
|
||||
if (mobj->colorized)
|
||||
diff2 |= MD2_COLORIZED;
|
||||
if (mobj->mirrored)
|
||||
|
@ -2125,6 +2128,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
WRITEUINT32(save_p, mobj->hprev->mobjnum);
|
||||
if (diff2 & MD2_SLOPE)
|
||||
WRITEUINT16(save_p, mobj->standingslope->id);
|
||||
if (diff2 & MD2_STANDINGLINE)
|
||||
WRITEUINT32(save_p, SaveLine(mobj->standingline));
|
||||
if (diff2 & MD2_COLORIZED)
|
||||
WRITEUINT8(save_p, mobj->colorized);
|
||||
if (diff2 & MD2_MIRRORED)
|
||||
|
@ -3181,6 +3186,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
|
||||
if (diff2 & MD2_SLOPE)
|
||||
mobj->standingslope = P_SlopeById(READUINT16(save_p));
|
||||
if (diff2 & MD2_STANDINGLINE)
|
||||
mobj->standingline = LoadLine(READUINT32(save_p));
|
||||
if (diff2 & MD2_COLORIZED)
|
||||
mobj->colorized = READUINT8(save_p);
|
||||
if (diff2 & MD2_MIRRORED)
|
||||
|
|
126
src/p_slopes.c
126
src/p_slopes.c
|
@ -859,11 +859,10 @@ fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y)
|
|||
// When given a vector, rotates it and aligns it to a slope
|
||||
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
|
||||
{
|
||||
vector3_t axis; // Fuck you, C90.
|
||||
|
||||
if (slope->flags & SL_NOPHYSICS)
|
||||
return; // No physics, no quantizing.
|
||||
|
||||
vector3_t axis;
|
||||
axis.x = -slope->d.y;
|
||||
axis.y = slope->d.x;
|
||||
axis.z = 0;
|
||||
|
@ -877,9 +876,91 @@ void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
|
|||
// When given a vector, rotates and aligns it to a flat surface (from being relative to a given slope)
|
||||
void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
|
||||
{
|
||||
slope->zangle = InvAngle(slope->zangle);
|
||||
P_QuantizeMomentumToSlope(momentum, slope);
|
||||
slope->zangle = InvAngle(slope->zangle);
|
||||
if (slope->flags & SL_NOPHYSICS)
|
||||
return; // No physics, no quantizing.
|
||||
|
||||
vector3_t axis;
|
||||
axis.x = -slope->d.y;
|
||||
axis.y = slope->d.x;
|
||||
axis.z = 0;
|
||||
|
||||
FV3_Rotate(momentum, &axis, InvAngle(slope->zangle) >> ANGLETOFINESHIFT);
|
||||
}
|
||||
|
||||
angle_t P_GetStandingSlopeZAngle(pslope_t *slope, line_t *line)
|
||||
{
|
||||
angle_t zangle = slope->zangle;
|
||||
|
||||
if (line)
|
||||
{
|
||||
zangle = R_PointToAngle2(0, P_GetSlopeZAt(slope, line->v1->x, line->v1->y),
|
||||
R_PointToDist2(line->v1->x, line->v1->y, line->v2->x, line->v2->y), P_GetSlopeZAt(slope, line->v2->x, line->v2->y));
|
||||
}
|
||||
|
||||
return zangle;
|
||||
}
|
||||
|
||||
angle_t P_GetStandingSlopeDirection(pslope_t *slope, line_t *line)
|
||||
{
|
||||
angle_t xydirection = slope->xydirection;
|
||||
|
||||
if (line)
|
||||
{
|
||||
xydirection = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y);
|
||||
}
|
||||
|
||||
return xydirection;
|
||||
}
|
||||
|
||||
angle_t P_GetObjectStandingSlopeZAngle(mobj_t *mo)
|
||||
{
|
||||
return P_GetStandingSlopeZAngle(mo->standingslope, mo->standingline);
|
||||
}
|
||||
|
||||
angle_t P_GetObjectStandingSlopeDirection(mobj_t *mo)
|
||||
{
|
||||
return P_GetStandingSlopeDirection(mo->standingslope, mo->standingline);
|
||||
}
|
||||
|
||||
static void QuantizeMomentumToSlope(pslope_t *slope, line_t *line, vector3_t *momentum, boolean reverse)
|
||||
{
|
||||
if (!slope || slope->flags & SL_NOPHYSICS)
|
||||
return;
|
||||
|
||||
angle_t zangle = P_GetStandingSlopeZAngle(slope, line);
|
||||
|
||||
if (reverse)
|
||||
zangle = InvAngle(zangle);
|
||||
|
||||
vector3_t axis;
|
||||
axis.z = 0;
|
||||
|
||||
if (line)
|
||||
{
|
||||
fixed_t len = R_PointToDist2(0, 0, line->dx, line->dy);
|
||||
axis.x = FixedDiv(line->dy, len);
|
||||
axis.y = -FixedDiv(line->dx, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
axis.x = -slope->d.y;
|
||||
axis.y = slope->d.x;
|
||||
}
|
||||
|
||||
FV3_Rotate(momentum, &axis, zangle >> ANGLETOFINESHIFT);
|
||||
}
|
||||
|
||||
// Given a vector of the object's momentum, rotates it and aligns it to the slope the object is standing on
|
||||
void P_QuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum)
|
||||
{
|
||||
QuantizeMomentumToSlope(mo->standingslope, mo->standingline, momentum, false);
|
||||
}
|
||||
|
||||
// Given a vector of the object's momentum, rotates and aligns it to a flat surface
|
||||
// (from being relative to the slope the object is standing on)
|
||||
void P_ReverseQuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum)
|
||||
{
|
||||
QuantizeMomentumToSlope(mo->standingslope, mo->standingline, momentum, true);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -899,7 +980,7 @@ void P_SlopeLaunch(mobj_t *mo)
|
|||
slopemom.x = mo->momx;
|
||||
slopemom.y = mo->momy;
|
||||
slopemom.z = mo->momz*2;
|
||||
P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
|
||||
P_QuantizeObjectMomentumToSlope(mo, &slopemom);
|
||||
|
||||
mo->momx = slopemom.x;
|
||||
mo->momy = slopemom.y;
|
||||
|
@ -919,7 +1000,7 @@ void P_SlopeLaunch(mobj_t *mo)
|
|||
// 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)
|
||||
fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope, line_t *line)
|
||||
{
|
||||
vector3_t slopemom, axis;
|
||||
angle_t ang;
|
||||
|
@ -927,18 +1008,30 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope)
|
|||
if (slope->flags & SL_NOPHYSICS)
|
||||
return 0;
|
||||
|
||||
angle_t zangle = P_GetStandingSlopeZAngle(slope, line);
|
||||
|
||||
// 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);
|
||||
ang = zangle + ANG15*((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
|
||||
ang = ((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);
|
||||
|
||||
if (line)
|
||||
{
|
||||
fixed_t len = R_PointToDist2(0, 0, line->dx, line->dy);
|
||||
axis.x = FixedDiv(line->dy, len);
|
||||
axis.y = -FixedDiv(line->dx, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
axis.x = -slope->d.y;
|
||||
axis.y = slope->d.x;
|
||||
}
|
||||
|
||||
axis.z = 0;
|
||||
|
||||
FV3_Rotate(&slopemom, &axis, ang >> ANGLETOFINESHIFT);
|
||||
|
@ -947,7 +1040,7 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope)
|
|||
}
|
||||
|
||||
// Function to help handle landing on slopes
|
||||
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
||||
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope, line_t *line)
|
||||
{
|
||||
vector3_t mom; // Ditto.
|
||||
if (slope->flags & SL_NOPHYSICS || (slope->normal.x == 0 && slope->normal.y == 0)) { // No physics, no need to make anything complicated.
|
||||
|
@ -966,12 +1059,13 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
|||
mom.y = thing->momy;
|
||||
mom.z = thing->momz*2;
|
||||
|
||||
P_ReverseQuantizeMomentumToSlope(&mom, slope);
|
||||
QuantizeMomentumToSlope(slope, line, &mom, true);
|
||||
|
||||
if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope
|
||||
thing->momx = mom.x;
|
||||
thing->momy = mom.y;
|
||||
thing->standingslope = slope;
|
||||
thing->standingline = line;
|
||||
P_SetPitchRollFromSlope(thing, slope);
|
||||
if (!thing->player || !(thing->player->pflags & PF_BOUNCING))
|
||||
thing->momz = -P_MobjFlip(thing);
|
||||
|
@ -983,6 +1077,7 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
|||
void P_ButteredSlope(mobj_t *mo)
|
||||
{
|
||||
fixed_t thrust;
|
||||
angle_t zangle, xydirection;
|
||||
|
||||
if (!mo->standingslope)
|
||||
return;
|
||||
|
@ -1001,12 +1096,15 @@ void P_ButteredSlope(mobj_t *mo)
|
|||
return; // Allow the player to stand still on slopes below a certain steepness
|
||||
}
|
||||
|
||||
thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 3 / 2 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1);
|
||||
zangle = P_GetStandingSlopeZAngle(mo->standingslope, mo->standingline);
|
||||
xydirection = P_GetStandingSlopeDirection(mo->standingslope, mo->standingline);
|
||||
|
||||
thrust = FINESINE(zangle>>ANGLETOFINESHIFT) * 3 / 2 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1);
|
||||
|
||||
if (mo->player && (mo->player->pflags & PF_SPINNING)) {
|
||||
fixed_t mult = 0;
|
||||
if (mo->momx || mo->momy) {
|
||||
angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - mo->standingslope->xydirection;
|
||||
angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - xydirection;
|
||||
|
||||
if (P_MobjFlip(mo) * mo->standingslope->zdelta < 0)
|
||||
angle ^= ANGLE_180;
|
||||
|
@ -1027,5 +1125,5 @@ void P_ButteredSlope(mobj_t *mo)
|
|||
// ... and its friction against the ground for good measure (divided by original friction to keep behaviour for normal slopes the same).
|
||||
thrust = FixedMul(thrust, FixedDiv(mo->friction, ORIG_FRICTION));
|
||||
|
||||
P_Thrust(mo, mo->standingslope->xydirection, thrust);
|
||||
P_Thrust(mo, xydirection, thrust);
|
||||
}
|
||||
|
|
|
@ -84,9 +84,15 @@ fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y);
|
|||
// Lots of physics-based bullshit
|
||||
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
|
||||
void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
|
||||
void P_QuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum);
|
||||
void P_ReverseQuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum);
|
||||
angle_t P_GetStandingSlopeZAngle(pslope_t *slope, line_t *line);
|
||||
angle_t P_GetStandingSlopeDirection(pslope_t *slope, line_t *line);
|
||||
angle_t P_GetObjectStandingSlopeZAngle(mobj_t *mo);
|
||||
angle_t P_GetObjectStandingSlopeDirection(mobj_t *mo);
|
||||
void P_SlopeLaunch(mobj_t *mo);
|
||||
fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope);
|
||||
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope);
|
||||
fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope, line_t *line);
|
||||
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope, line_t *line);
|
||||
void P_ButteredSlope(mobj_t *mo);
|
||||
|
||||
pslope_t *P_MakeSlopeViaEquationConstants(const double a, const double b, const double c, const double d);
|
||||
|
|
|
@ -6257,15 +6257,15 @@ static void P_3dMovement(player_t *player)
|
|||
&& player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) {
|
||||
// Factor thrust to slope, but only for the part pushing up it!
|
||||
// The rest is unaffected.
|
||||
angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection;
|
||||
angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-P_GetObjectStandingSlopeDirection(player->mo);
|
||||
|
||||
if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face toward
|
||||
if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270) {
|
||||
P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope);
|
||||
P_QuantizeObjectMomentumToSlope(player->mo, &totalthrust);
|
||||
}
|
||||
} else { // Direction goes up, so thrustangle needs to face away
|
||||
if (thrustangle > ANGLE_90 && thrustangle < ANGLE_270) {
|
||||
P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope);
|
||||
P_QuantizeObjectMomentumToSlope(player->mo, &totalthrust);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue