Slope launch physiscs adjustments

This commit is contained in:
Ashnal 2024-09-16 00:47:45 +00:00 committed by Oni
parent 9eb605da9f
commit 33a1ca5831
6 changed files with 316 additions and 258 deletions

View file

@ -12552,6 +12552,7 @@ boolean K_FastFallBounce(player_t *player)
}
player->mo->momz = bounce * P_MobjFlip(player->mo);
CONS_Printf("%s FastFallBounce %d\n", player_names[player-players], player->mo->momz);
return true;
}

View file

@ -2775,6 +2775,17 @@ fixed_t P_GetThingStepUp(mobj_t *thing, fixed_t destX, fixed_t destY)
maxstep = 0;
}
if (thing->standingslope)
{
vector3_t slopemom = {0,0,0};
slopemom.x = thing->momx;
slopemom.y = thing->momy;
slopemom.z = 0;
P_QuantizeMomentumToSlope(&slopemom, thing->standingslope);
fixed_t momentumzdelta = FixedDiv(slopemom.z, FixedHypot(slopemom.x, slopemom.y)); // so this lets us know what the zdelta is for the vector the player is travelling along, in addition to the slope's zdelta in its xydirection
maxstep += abs(momentumzdelta);
}
return maxstep;
}
@ -2793,6 +2804,13 @@ increment_move
fixed_t thingtop;
fixed_t stairjank = 0;
g_tm.floatok = false;
fixed_t oldfloorz = INT32_MAX; // Ramp detection
pslope_t *oldslope = NULL;
angle_t moveangle = R_PointToAngle2(thing->x,thing->y,x,y);
boolean samepos = false;
if (thing->x == x && thing->y == y)
samepos = true;
// reset this to 0 at the start of each trymove call as it's only used here
numspechitint = 0U;
@ -2842,6 +2860,9 @@ increment_move
boolean move_ok = P_CheckPosition(thing, tryx, tryy, result);
oldslope = thing->standingslope;
oldfloorz = thing->floorz;
if (P_MobjWasRemoved(thing))
{
return false;
@ -2956,7 +2977,7 @@ increment_move
}
else if (g_tm.floorz - g_tm.dropoffz > maxstep)
return false; // don't stand over a dropoff
}
}
}
} while (tryx != x || tryy != y);

View file

@ -29,6 +29,7 @@
//
// P_ClosestPointOnLine
// Finds the closest point on a given line to the supplied point
// Considers line length to be infinite, and can return results outside of the actual linedef bounds
//
void P_ClosestPointOnLine(fixed_t x, fixed_t y, const line_t *line, vertex_t *result)
{
@ -68,6 +69,27 @@ void P_ClosestPointOnLine(fixed_t x, fixed_t y, const line_t *line, vertex_t *re
return;
}
//
// P_ClosestPointOnLineWithinLine
// Finds the closest point on a given line to the supplied point
// Like P_ClosestPointOnLine, except the result is constrained within the actual line
//
void P_ClosestPointOnLineWithinLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result)
{
P_ClosestPointOnLine(x, y, line, result);
// Determine max and min bounds of the line
fixed_t maxx = max(line->v1->x, line->v2->x);
fixed_t maxy = max(line->v1->y, line->v2->y);
fixed_t minx = min(line->v1->x, line->v2->x);
fixed_t miny = min(line->v1->y, line->v2->y);
// Constrain result to line by ensuring x and y don't go beyond the maximums
result->x = min(max(result->x, minx),maxx);
result->y = min(max(result->y, miny),maxy);
return;
}
/// Similar to FV3_ClosestPointOnLine() except it actually works.
void P_ClosestPointOnLine3D(const vector3_t *p, const vector3_t *Line, vector3_t *result)
{
@ -527,6 +549,107 @@ static boolean P_MidtextureIsSolid(line_t *linedef, mobj_t *mobj)
return ((linedef->flags & ML_MIDSOLID) == ML_MIDSOLID);
}
boolean P_FoFOpening(sector_t *sector, line_t *linedef, mobj_t *mobj, opening_t *open, fofopening_t *fofopen)
{
fixed_t delta1, delta2;
fixed_t thingtop = mobj->z + mobj->height;
boolean ret = false; // DId we find any relevant FoFs?
// Check for frontsector's fake floors
for (ffloor_t *rover = sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight, midheight;
if (!(rover->fofflags & FOF_EXISTS))
continue;
if (P_CheckSolidFFloorSurface(mobj, rover))
;
else if (!((rover->fofflags & FOF_BLOCKPLAYER && mobj->player)
|| (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player)))
continue;
ret = true; // Found a FoF that matters
if (open->fofType != LO_FOF_ANY)
{
topheight = P_VeryTopOfFOF(rover);
bottomheight = P_VeryBottomOfFOF(rover);
}
else
{
topheight = P_GetFOFTopZ(mobj, sector, rover, g_tm.x, g_tm.y, linedef);
bottomheight = P_GetFOFBottomZ(mobj, sector, rover, g_tm.x, g_tm.y, linedef);
}
switch (open->fofType)
{
case LO_FOF_FLOORS:
{
if (mobj->z >= topheight)
{
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM)
{
if (topheight > fofopen->floor)
{
fofopen->floor = topheight;
fofopen->floorrover = rover;
}
}
}
break;
}
case LO_FOF_CEILINGS:
{
if (thingtop <= bottomheight)
{
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM)
{
if (bottomheight < fofopen->ceiling)
{
fofopen->ceiling = bottomheight;
fofopen->ceilingrover = rover;
}
}
}
break;
}
default:
{
midheight = bottomheight + (topheight - bottomheight) / 2;
delta1 = abs(mobj->z - midheight);
delta2 = abs(thingtop - midheight);
if (delta1 > delta2)
{
// thing is below FOF
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM)
{
if (bottomheight < fofopen->ceiling)
{
fofopen->ceiling = bottomheight;
fofopen->ceilingrover = rover;
}
}
}
else
{
// thing is above FOF
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM)
{
if (topheight > fofopen->floor)
{
fofopen->floor = topheight;
fofopen->floorrover = rover;
}
}
}
break;
}
}
}
return ret;
}
void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open)
{
enum { FRONT, BACK };
@ -589,7 +712,17 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open)
height[FRONT] = P_GetCeilingZ(mobj, front, g_tm.x, g_tm.y, linedef);
height[BACK] = P_GetCeilingZ(mobj, back, g_tm.x, g_tm.y, linedef);
hi = ( height[0] < height[1] );
if (height[FRONT] == height[BACK] && (front->c_slope || back->c_slope))
{
fixed_t savedradius = mobj->radius; // forgive me. Perhaps it would be better to refactor these functions to take a radius of fixed_t instead? thats all they grab from the mobj
mobj->radius = 1; // I need the same calculation, but at the center of the mobj
hi = ( P_GetCeilingZ(mobj, front, g_tm.x, g_tm.y, linedef) < P_GetCeilingZ(mobj, back, g_tm.x, g_tm.y, linedef) );
hi = !hi; // actually lets do a funny and flip these
mobj->radius = savedradius;
}
else
hi = ( height[FRONT] < height[BACK] );
lo = ! hi;
open->ceiling = height[lo];
@ -609,7 +742,17 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open)
height[FRONT] = P_GetFloorZ(mobj, front, g_tm.x, g_tm.y, linedef);
height[BACK] = P_GetFloorZ(mobj, back, g_tm.x, g_tm.y, linedef);
hi = ( height[0] < height[1] );
if (height[FRONT] == height[BACK] && (front->f_slope || back->f_slope))
{
fixed_t savedradius = mobj->radius; // forgive me. Perhaps it would be better to refactor these functions to take a radius of fixed_t instead? thats all they grab from the mobj
mobj->radius = 1; // I need the same calculation, but at the center of the mobj
hi = ( P_GetFloorZ(mobj, front, g_tm.x, g_tm.y, linedef) < P_GetFloorZ(mobj, back, g_tm.x, g_tm.y, linedef) );
hi = !hi; // actually lets do a funny and flip these
mobj->radius = savedradius;
}
else
hi = ( height[FRONT] < height[BACK] );
lo = ! hi;
open->floor = height[hi];
@ -760,261 +903,104 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open)
// Check for fake floors in the sector.
if (front->ffloors || back->ffloors)
{
ffloor_t *rover;
fixed_t delta1, delta2;
/* yuck */
struct
{
fixed_t ceiling;
fixed_t floor;
ffloor_t * ceilingrover;
ffloor_t * floorrover;
} fofopen[2] = {
boolean anyfrontfofs, anybackfofs;
fofopening_t fofopen[2] = {
{ INT32_MAX, INT32_MIN, NULL, NULL },
{ INT32_MAX, INT32_MIN, NULL, NULL },
};
// Check for frontsector's fake floors
for (rover = front->ffloors; rover; rover = rover->next)
anyfrontfofs = P_FoFOpening(front, linedef, mobj, open, &fofopen[FRONT]);
anybackfofs = P_FoFOpening(back, linedef, mobj, open, &fofopen[BACK]);
if (anyfrontfofs || anybackfofs) // if all front and back fofs are irrelevant then skip
{
fixed_t topheight, bottomheight, midheight;
if (!(rover->fofflags & FOF_EXISTS))
continue;
if (P_CheckSolidFFloorSurface(mobj, rover))
;
else if (!((rover->fofflags & FOF_BLOCKPLAYER && mobj->player)
|| (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player)))
continue;
if (open->fofType != LO_FOF_ANY)
if (fofopen[FRONT].ceiling == fofopen[BACK].ceiling && ((fofopen[FRONT].ceilingrover && *fofopen[FRONT].ceilingrover->b_slope) || (fofopen[BACK].ceilingrover && *fofopen[BACK].ceilingrover->b_slope)))
{
topheight = P_VeryTopOfFOF(rover);
bottomheight = P_VeryBottomOfFOF(rover);
fixed_t savedradius = mobj->radius; // forgive me. Perhaps it would be better to refactor these functions to take a radius of fixed_t instead? thats all they grabn from the mobj
mobj->radius = 1; // I need the same calculation, but at the center of the mobj
fofopening_t temp[2] = {
{ INT32_MAX, INT32_MIN, NULL, NULL },
{ INT32_MAX, INT32_MIN, NULL, NULL }
};
P_FoFOpening(front, linedef, mobj, open, &temp[FRONT]);
P_FoFOpening(back, linedef, mobj, open, &temp[BACK]);
hi = ( temp[FRONT].ceiling < temp[BACK].ceiling );
mobj->radius = savedradius;
}
else
{
topheight = P_GetFOFTopZ(mobj, front, rover, g_tm.x, g_tm.y, linedef);
bottomheight = P_GetFOFBottomZ(mobj, front, rover, g_tm.x, g_tm.y, linedef);
}
hi = ( fofopen[FRONT].ceiling < fofopen[BACK].ceiling );
switch (open->fofType)
{
case LO_FOF_FLOORS:
{
if (mobj->z >= topheight)
{
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM)
{
if (topheight > fofopen[FRONT].floor)
{
fofopen[FRONT].floor = topheight;
fofopen[FRONT].floorrover = rover;
}
}
}
break;
}
case LO_FOF_CEILINGS:
{
if (thingtop <= bottomheight)
{
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM)
{
if (bottomheight < fofopen[FRONT].ceiling)
{
fofopen[FRONT].ceiling = bottomheight;
fofopen[FRONT].ceilingrover = rover;
}
}
}
break;
}
default:
{
midheight = bottomheight + (topheight - bottomheight) / 2;
delta1 = abs(mobj->z - midheight);
delta2 = abs(thingtop - midheight);
lo = ! hi;
if (delta1 > delta2)
{
// thing is below FOF
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM)
{
if (bottomheight < fofopen[FRONT].ceiling)
{
fofopen[FRONT].ceiling = bottomheight;
fofopen[FRONT].ceilingrover = rover;
}
}
}
else
{
// thing is above FOF
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM)
{
if (topheight > fofopen[FRONT].floor)
{
fofopen[FRONT].floor = topheight;
fofopen[FRONT].floorrover = rover;
}
}
}
break;
if (fofopen[lo].ceiling <= open->ceiling)
{
topedge[lo] = P_GetFFloorBottomZAt(fofopen[lo].ceilingrover, cross.x, cross.y);
if (fofopen[hi].ceiling < open->ceiling)
{
topedge[hi] = P_GetFFloorBottomZAt(fofopen[hi].ceilingrover, cross.x, cross.y);
}
open->ceiling = fofopen[lo].ceiling;
open->ceilingrover = fofopen[lo].ceilingrover;
open->ceilingslope = *fofopen[lo].ceilingrover->b_slope;
open->ceilingpic = *fofopen[lo].ceilingrover->bottompic;
open->ceilingstep = ( thingtop - topedge[lo] );
open->ceilingdrop = ( topedge[hi] - topedge[lo] );
if (fofopen[hi].ceiling < open->highceiling)
{
open->highceiling = fofopen[hi].ceiling;
}
}
}
// Check for backsectors fake floors
for (rover = back->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight, midheight;
if (!(rover->fofflags & FOF_EXISTS))
continue;
if (P_CheckSolidFFloorSurface(mobj, rover))
;
else if (!((rover->fofflags & FOF_BLOCKPLAYER && mobj->player)
|| (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player)))
continue;
if (open->fofType != LO_FOF_ANY)
else if (fofopen[lo].ceiling < open->highceiling)
{
topheight = P_VeryTopOfFOF(rover);
bottomheight = P_VeryBottomOfFOF(rover);
open->highceiling = fofopen[lo].ceiling;
}
if (fofopen[FRONT].floor == fofopen[BACK].floor && ((fofopen[FRONT].floorrover && *fofopen[FRONT].floorrover->t_slope) || (fofopen[BACK].floorrover && *fofopen[BACK].floorrover->t_slope)))
{
fixed_t savedradius = mobj->radius; // forgive me. Perhaps it would be better to refactor these functions to take a radius of fixed_t instead? thats all they grabn from the mobj
mobj->radius = 1; // I need the same calculation, but at the center of the mobj
fofopening_t temp[2] = {
{ INT32_MAX, INT32_MIN, NULL, NULL },
{ INT32_MAX, INT32_MIN, NULL, NULL }
};
P_FoFOpening(front, linedef, mobj, open, &temp[FRONT]);
P_FoFOpening(back, linedef, mobj, open, &temp[BACK]);
hi = ( temp[FRONT].ceiling < temp[BACK].ceiling );
mobj->radius = savedradius;
}
else
{
topheight = P_GetFOFTopZ(mobj, back, rover, g_tm.x, g_tm.y, linedef);
bottomheight = P_GetFOFBottomZ(mobj, back, rover, g_tm.x, g_tm.y, linedef);
}
hi = ( fofopen[FRONT].floor < fofopen[BACK].floor );
switch (open->fofType)
{
case LO_FOF_FLOORS:
{
if (mobj->z >= topheight)
{
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM)
{
if (topheight > fofopen[BACK].floor)
{
fofopen[BACK].floor = topheight;
fofopen[BACK].floorrover = rover;
}
}
}
break;
}
case LO_FOF_CEILINGS:
{
if (thingtop <= bottomheight)
{
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM)
{
if (bottomheight < fofopen[BACK].ceiling)
{
fofopen[BACK].ceiling = bottomheight;
fofopen[BACK].ceilingrover = rover;
}
}
}
break;
}
default:
{
midheight = bottomheight + (topheight - bottomheight) / 2;
delta1 = abs(mobj->z - midheight);
delta2 = abs(thingtop - midheight);
lo = ! hi;
if (delta1 > delta2)
{
// thing is below FOF
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM)
{
if (bottomheight < fofopen[BACK].ceiling)
{
fofopen[BACK].ceiling = bottomheight;
fofopen[BACK].ceilingrover = rover;
}
}
}
else
{
// thing is above FOF
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM)
{
if (topheight > fofopen[BACK].floor)
{
fofopen[BACK].floor = topheight;
fofopen[BACK].floorrover = rover;
}
}
}
break;
if (fofopen[hi].floor >= open->floor)
{
botedge[hi] = P_GetFFloorTopZAt(fofopen[hi].floorrover, cross.x, cross.y);
if (fofopen[lo].floor > open->floor)
{
botedge[lo] = P_GetFFloorTopZAt(fofopen[lo].floorrover, cross.x, cross.y);
}
open->floor = fofopen[hi].floor;
open->floorrover = fofopen[hi].floorrover;
open->floorslope = *fofopen[hi].floorrover->t_slope;
open->floorpic = *fofopen[hi].floorrover->toppic;
open->floorstep = ( botedge[hi] - mobj->z );
open->floordrop = ( botedge[hi] - botedge[lo] );
if (fofopen[lo].floor > open->lowfloor)
{
open->lowfloor = fofopen[lo].floor;
}
}
}
hi = ( fofopen[0].ceiling < fofopen[1].ceiling );
lo = ! hi;
if (fofopen[lo].ceiling <= open->ceiling)
{
topedge[lo] = P_GetFFloorBottomZAt(fofopen[lo].ceilingrover, cross.x, cross.y);
if (fofopen[hi].ceiling < open->ceiling)
else if (fofopen[hi].floor > open->lowfloor)
{
topedge[hi] = P_GetFFloorBottomZAt(fofopen[hi].ceilingrover, cross.x, cross.y);
open->lowfloor = fofopen[hi].floor;
}
open->ceiling = fofopen[lo].ceiling;
open->ceilingrover = fofopen[lo].ceilingrover;
open->ceilingslope = *fofopen[lo].ceilingrover->b_slope;
open->ceilingpic = *fofopen[lo].ceilingrover->bottompic;
open->ceilingstep = ( thingtop - topedge[lo] );
open->ceilingdrop = ( topedge[hi] - topedge[lo] );
if (fofopen[hi].ceiling < open->highceiling)
{
open->highceiling = fofopen[hi].ceiling;
}
}
else if (fofopen[lo].ceiling < open->highceiling)
{
open->highceiling = fofopen[lo].ceiling;
}
hi = ( fofopen[0].floor < fofopen[1].floor );
lo = ! hi;
if (fofopen[hi].floor >= open->floor)
{
botedge[hi] = P_GetFFloorTopZAt(fofopen[hi].floorrover, cross.x, cross.y);
if (fofopen[lo].floor > open->floor)
{
botedge[lo] = P_GetFFloorTopZAt(fofopen[lo].floorrover, cross.x, cross.y);
}
open->floor = fofopen[hi].floor;
open->floorrover = fofopen[hi].floorrover;
open->floorslope = *fofopen[hi].floorrover->t_slope;
open->floorpic = *fofopen[hi].floorrover->toppic;
open->floorstep = ( botedge[hi] - mobj->z );
open->floordrop = ( botedge[hi] - botedge[lo] );
if (fofopen[lo].floor > open->lowfloor)
{
open->lowfloor = fofopen[lo].floor;
}
}
else if (fofopen[hi].floor > open->lowfloor)
{
open->lowfloor = fofopen[hi].floor;
}
}
}

View file

@ -48,6 +48,7 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2,
#define P_AproxDistance(dx, dy) FixedHypot(dx, dy)
void P_ClosestPointOnLine(fixed_t x, fixed_t y, const line_t *line, vertex_t *result);
void P_ClosestPointOnLineWithinLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result);
void P_ClosestPointOnLine3D(const vector3_t *p, const vector3_t *line, vector3_t *result);
INT32 P_PointOnLineSide(fixed_t x, fixed_t y, const line_t *line);
void P_MakeDivline(const line_t *li, divline_t *dl);
@ -74,10 +75,19 @@ struct opening_t
UINT8 fofType; // LO_FOF_ types for forcing FOF collide
};
struct fofopening_t
{
fixed_t ceiling;
fixed_t floor;
ffloor_t * ceilingrover;
ffloor_t * floorrover;
};
#define LO_FOF_ANY (0)
#define LO_FOF_FLOORS (1)
#define LO_FOF_CEILINGS (2)
boolean P_FoFOpening(sector_t *sector, line_t *linedef, mobj_t *mobj, opening_t *open, fofopening_t *fofopen);
void P_LineOpening(line_t *plinedef, mobj_t *mobj, opening_t *open);
typedef enum

View file

@ -1613,8 +1613,9 @@ boolean P_XYMovement(mobj_t *mo)
boolean moved;
pslope_t *oldslope = NULL;
vector3_t slopemom = {0,0,0};
fixed_t predictedz = 0;
fixed_t predictedz = INT32_MAX; // Need a sentinel value
TryMoveResult_t result = {0};
fixed_t momentumzdelta = INT32_MAX;
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
@ -1650,11 +1651,13 @@ boolean P_XYMovement(mobj_t *mo)
}
// adjust various things based on slope
if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8)
if (mo->standingslope && mo->standingslope->zdelta != 0)
{
if (!P_IsObjectOnGround(mo))
{
// We fell off at some point? Do the twisty thing!
// if (mo->player)
// CONS_Printf("Twisty thing launch?\n");
P_SlopeLaunch(mo);
xmove = mo->momx;
ymove = mo->momy;
@ -1670,9 +1673,16 @@ boolean P_XYMovement(mobj_t *mo)
xmove = slopemom.x;
ymove = slopemom.y;
predictedz = mo->z + slopemom.z; // We'll use this later...
momentumzdelta = FixedDiv(slopemom.z, FixedHypot(xmove, ymove)); // so this lets us know what the zdelta is for the vector the player is travelling along, in addition to the slope's zdelta in its xydirection
oldslope = mo->standingslope;
// if (mo->player)
// CONS_Printf("%s zdelta %d momzdelta %d\n",player_names[mo->player-players], mo->standingslope->zdelta, momentumzdelta);
if (abs(momentumzdelta) >= FRACUNIT/6)
predictedz = mo->z + slopemom.z;
else
predictedz = mo->z;
}
} else if (P_IsObjectOnGround(mo) && !mo->momz)
predictedz = mo->z;
@ -1752,7 +1762,7 @@ boolean P_XYMovement(mobj_t *mo)
// 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
if (oldslope && (P_MobjFlip(mo)*slopemom.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.
@ -1906,27 +1916,34 @@ boolean P_XYMovement(mobj_t *mo)
mo->standingslope = oldslope;
P_SetPitchRollFromSlope(mo, mo->standingslope);
P_SlopeLaunch(mo);
//CONS_Printf("launched off of slope - ");
if (mo->player)
CONS_Printf("%s Slope change launch old angle %f - new angle %f = %f\n",
player_names[mo->player-players],
FIXED_TO_FLOAT(AngleFixed(oldangle)),
FIXED_TO_FLOAT(AngleFixed(newangle)),
FIXED_TO_FLOAT(AngleFixed(oldangle-newangle))
);
}
/*
CONS_Printf("old angle %f - new angle %f = %f\n",
FIXED_TO_FLOAT(AngleFixed(oldangle)),
FIXED_TO_FLOAT(AngleFixed(newangle)),
FIXED_TO_FLOAT(AngleFixed(oldangle-newangle))
);
*/
}
else if (predictedz - mo->z > abs(slopemom.z / 2))
else
{
// Now check if we were supposed to stick to this slope
//CONS_Printf("%d-%d > %d\n", (predictedz), (mo->z), (slopemom.z/2));
P_SlopeLaunch(mo);
// if (mo->player)
// CONS_Printf("Ramp Launch %d %d+%d > 0 && %d-%d > %d ", mo->scale, FixedDiv(slopemom.z, mo->scale), P_GetMobjGravity(mo)*24, predictedz, mo->z, slopemom.z/2);
if ( // If slope aligned momz is more than gravity, and mobj clipped along ramp edge instead of following slope plane, then launch
( !(mo->eflags & MFE_VERTICALFLIP) && FixedDiv(slopemom.z, mo->scale) + P_GetMobjGravity(mo)*24 > 0 && predictedz - mo->z > slopemom.z*4/5 )
|| ( (mo->eflags & MFE_VERTICALFLIP) && FixedDiv(slopemom.z, mo->scale) + P_GetMobjGravity(mo)*24 < 0 && predictedz - mo->z < slopemom.z*4/5 )
)
{
if (mo->player)
CONS_Printf("%s Ramp Launch %d %d %d+%d > 0 && %d-%d > %d True\n", player_names[mo->player-players], mo->scale, momentumzdelta, FixedDiv(slopemom.z, mo->scale), P_GetMobjGravity(mo)*24, predictedz, mo->z, slopemom.z*4/5);
P_SlopeLaunch(mo);
}
// else
// if (mo->player)
// CONS_Printf("False\n");
}
}
else if (moved && mo->standingslope && predictedz)
else if (moved && mo->standingslope && predictedz != INT32_MAX) // Predicted z must be changed
{
angle_t moveangle = K_MomentumAngle(mo);
angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT));
@ -2264,7 +2281,11 @@ boolean P_ZMovement(mobj_t *mo)
if (mo->flags & MF_NOCLIPHEIGHT)
mo->standingslope = NULL;
else if (!onground)
{
if (mo->player)
// CONS_Printf("ZMovement launch?\n");
P_SlopeLaunch(mo);
}
}
switch (mo->type)
@ -2798,6 +2819,20 @@ void P_PlayerZMovement(mobj_t *mo)
mo->eflags &= ~MFE_APPLYPMOMZ;
}
if (mo->eflags & MFE_JUSTSTEPPEDDOWN && abs(mo->momz) > 1)
{
CONS_Printf("%s Check Step up momz reset %d < %d + %d", player_names[mo->player-players], abs(mo->momz), P_GetThingStepUp(mo, mo->x, mo->y)/6, abs(P_GetMobjGravity(mo)*3));
if (abs(mo->momz) < P_GetThingStepUp(mo, mo->x, mo->y)/6 + abs(P_GetMobjGravity(mo)*3))
{
CONS_Printf(" True\n");
mo->momz = 0;
}
else
{
CONS_Printf(" False\n");
}
}
mo->z += mo->momz;
onground = P_IsObjectOnGround(mo);
@ -2811,7 +2846,11 @@ void P_PlayerZMovement(mobj_t *mo)
if (mo->flags & MF_NOCLIPHEIGHT)
mo->standingslope = NULL;
else if (!onground)
{
CONS_Printf("%s PlayerZMovement launch %d ", player_names[mo->player-players], mo->momz);
P_SlopeLaunch(mo);
CONS_Printf("%d\n", mo->momz);
}
}
// clip movement

View file

@ -301,6 +301,7 @@ TYPEDEF (BasicFF_t);
TYPEDEF (divline_t);
TYPEDEF (intercept_t);
TYPEDEF (opening_t);
TYPEDEF (fofopening_t);
// p_mobj.h
TYPEDEF (mobj_t);