mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Slope launch physiscs adjustments
This commit is contained in:
parent
9eb605da9f
commit
33a1ca5831
6 changed files with 316 additions and 258 deletions
|
|
@ -12552,6 +12552,7 @@ boolean K_FastFallBounce(player_t *player)
|
||||||
}
|
}
|
||||||
|
|
||||||
player->mo->momz = bounce * P_MobjFlip(player->mo);
|
player->mo->momz = bounce * P_MobjFlip(player->mo);
|
||||||
|
CONS_Printf("%s FastFallBounce %d\n", player_names[player-players], player->mo->momz);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
21
src/p_map.c
21
src/p_map.c
|
|
@ -2775,6 +2775,17 @@ fixed_t P_GetThingStepUp(mobj_t *thing, fixed_t destX, fixed_t destY)
|
||||||
maxstep = 0;
|
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;
|
return maxstep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2793,6 +2804,13 @@ increment_move
|
||||||
fixed_t thingtop;
|
fixed_t thingtop;
|
||||||
fixed_t stairjank = 0;
|
fixed_t stairjank = 0;
|
||||||
g_tm.floatok = false;
|
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
|
// reset this to 0 at the start of each trymove call as it's only used here
|
||||||
numspechitint = 0U;
|
numspechitint = 0U;
|
||||||
|
|
@ -2842,6 +2860,9 @@ increment_move
|
||||||
|
|
||||||
boolean move_ok = P_CheckPosition(thing, tryx, tryy, result);
|
boolean move_ok = P_CheckPosition(thing, tryx, tryy, result);
|
||||||
|
|
||||||
|
oldslope = thing->standingslope;
|
||||||
|
oldfloorz = thing->floorz;
|
||||||
|
|
||||||
if (P_MobjWasRemoved(thing))
|
if (P_MobjWasRemoved(thing))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
374
src/p_maputl.c
374
src/p_maputl.c
|
|
@ -29,6 +29,7 @@
|
||||||
//
|
//
|
||||||
// P_ClosestPointOnLine
|
// P_ClosestPointOnLine
|
||||||
// Finds the closest point on a given line to the supplied point
|
// 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)
|
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;
|
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.
|
/// Similar to FV3_ClosestPointOnLine() except it actually works.
|
||||||
void P_ClosestPointOnLine3D(const vector3_t *p, const vector3_t *Line, vector3_t *result)
|
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);
|
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)
|
void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open)
|
||||||
{
|
{
|
||||||
enum { FRONT, BACK };
|
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[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);
|
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;
|
lo = ! hi;
|
||||||
|
|
||||||
open->ceiling = height[lo];
|
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[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);
|
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;
|
lo = ! hi;
|
||||||
|
|
||||||
open->floor = height[hi];
|
open->floor = height[hi];
|
||||||
|
|
@ -760,206 +903,33 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open)
|
||||||
// Check for fake floors in the sector.
|
// Check for fake floors in the sector.
|
||||||
if (front->ffloors || back->ffloors)
|
if (front->ffloors || back->ffloors)
|
||||||
{
|
{
|
||||||
ffloor_t *rover;
|
boolean anyfrontfofs, anybackfofs;
|
||||||
fixed_t delta1, delta2;
|
fofopening_t fofopen[2] = {
|
||||||
|
|
||||||
/* yuck */
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
fixed_t ceiling;
|
|
||||||
fixed_t floor;
|
|
||||||
ffloor_t * ceilingrover;
|
|
||||||
ffloor_t * floorrover;
|
|
||||||
} fofopen[2] = {
|
|
||||||
{ INT32_MAX, INT32_MIN, NULL, NULL },
|
{ INT32_MAX, INT32_MIN, NULL, NULL },
|
||||||
{ INT32_MAX, INT32_MIN, NULL, NULL },
|
{ INT32_MAX, INT32_MIN, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check for frontsector's fake floors
|
anyfrontfofs = P_FoFOpening(front, linedef, mobj, open, &fofopen[FRONT]);
|
||||||
for (rover = front->ffloors; rover; rover = rover->next)
|
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 (fofopen[FRONT].ceiling == fofopen[BACK].ceiling && ((fofopen[FRONT].ceilingrover && *fofopen[FRONT].ceilingrover->b_slope) || (fofopen[BACK].ceilingrover && *fofopen[BACK].ceilingrover->b_slope)))
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
topheight = P_VeryTopOfFOF(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
|
||||||
bottomheight = P_VeryBottomOfFOF(rover);
|
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
|
else
|
||||||
{
|
hi = ( fofopen[FRONT].ceiling < fofopen[BACK].ceiling );
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
{
|
|
||||||
topheight = P_VeryTopOfFOF(rover);
|
|
||||||
bottomheight = P_VeryBottomOfFOF(rover);
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hi = ( fofopen[0].ceiling < fofopen[1].ceiling );
|
|
||||||
lo = ! hi;
|
lo = ! hi;
|
||||||
|
|
||||||
if (fofopen[lo].ceiling <= open->ceiling)
|
if (fofopen[lo].ceiling <= open->ceiling)
|
||||||
|
|
@ -988,7 +958,22 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open)
|
||||||
open->highceiling = fofopen[lo].ceiling;
|
open->highceiling = fofopen[lo].ceiling;
|
||||||
}
|
}
|
||||||
|
|
||||||
hi = ( fofopen[0].floor < fofopen[1].floor );
|
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
|
||||||
|
hi = ( fofopen[FRONT].floor < fofopen[BACK].floor );
|
||||||
|
|
||||||
lo = ! hi;
|
lo = ! hi;
|
||||||
|
|
||||||
if (fofopen[hi].floor >= open->floor)
|
if (fofopen[hi].floor >= open->floor)
|
||||||
|
|
@ -1019,6 +1004,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open->range = (open->ceiling - open->floor);
|
open->range = (open->ceiling - open->floor);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
#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_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);
|
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);
|
INT32 P_PointOnLineSide(fixed_t x, fixed_t y, const line_t *line);
|
||||||
void P_MakeDivline(const line_t *li, divline_t *dl);
|
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
|
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_ANY (0)
|
||||||
#define LO_FOF_FLOORS (1)
|
#define LO_FOF_FLOORS (1)
|
||||||
#define LO_FOF_CEILINGS (2)
|
#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);
|
void P_LineOpening(line_t *plinedef, mobj_t *mobj, opening_t *open);
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
|
||||||
73
src/p_mobj.c
73
src/p_mobj.c
|
|
@ -1613,8 +1613,9 @@ boolean P_XYMovement(mobj_t *mo)
|
||||||
boolean moved;
|
boolean moved;
|
||||||
pslope_t *oldslope = NULL;
|
pslope_t *oldslope = NULL;
|
||||||
vector3_t slopemom = {0,0,0};
|
vector3_t slopemom = {0,0,0};
|
||||||
fixed_t predictedz = 0;
|
fixed_t predictedz = INT32_MAX; // Need a sentinel value
|
||||||
TryMoveResult_t result = {0};
|
TryMoveResult_t result = {0};
|
||||||
|
fixed_t momentumzdelta = INT32_MAX;
|
||||||
|
|
||||||
I_Assert(mo != NULL);
|
I_Assert(mo != NULL);
|
||||||
I_Assert(!P_MobjWasRemoved(mo));
|
I_Assert(!P_MobjWasRemoved(mo));
|
||||||
|
|
@ -1650,11 +1651,13 @@ boolean P_XYMovement(mobj_t *mo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust various things based on slope
|
// 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))
|
if (!P_IsObjectOnGround(mo))
|
||||||
{
|
{
|
||||||
// We fell off at some point? Do the twisty thing!
|
// We fell off at some point? Do the twisty thing!
|
||||||
|
// if (mo->player)
|
||||||
|
// CONS_Printf("Twisty thing launch?\n");
|
||||||
P_SlopeLaunch(mo);
|
P_SlopeLaunch(mo);
|
||||||
xmove = mo->momx;
|
xmove = mo->momx;
|
||||||
ymove = mo->momy;
|
ymove = mo->momy;
|
||||||
|
|
@ -1670,9 +1673,16 @@ boolean P_XYMovement(mobj_t *mo)
|
||||||
xmove = slopemom.x;
|
xmove = slopemom.x;
|
||||||
ymove = slopemom.y;
|
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;
|
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)
|
} else if (P_IsObjectOnGround(mo) && !mo->momz)
|
||||||
predictedz = mo->z;
|
predictedz = mo->z;
|
||||||
|
|
@ -1752,7 +1762,7 @@ boolean P_XYMovement(mobj_t *mo)
|
||||||
// Wall transfer part 1.
|
// Wall transfer part 1.
|
||||||
pslope_t *transferslope = NULL;
|
pslope_t *transferslope = NULL;
|
||||||
fixed_t transfermomz = 0;
|
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);
|
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.
|
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;
|
mo->standingslope = oldslope;
|
||||||
P_SetPitchRollFromSlope(mo, mo->standingslope);
|
P_SetPitchRollFromSlope(mo, mo->standingslope);
|
||||||
P_SlopeLaunch(mo);
|
P_SlopeLaunch(mo);
|
||||||
|
if (mo->player)
|
||||||
//CONS_Printf("launched off of slope - ");
|
CONS_Printf("%s Slope change launch old angle %f - new angle %f = %f\n",
|
||||||
}
|
player_names[mo->player-players],
|
||||||
|
|
||||||
/*
|
|
||||||
CONS_Printf("old angle %f - new angle %f = %f\n",
|
|
||||||
FIXED_TO_FLOAT(AngleFixed(oldangle)),
|
FIXED_TO_FLOAT(AngleFixed(oldangle)),
|
||||||
FIXED_TO_FLOAT(AngleFixed(newangle)),
|
FIXED_TO_FLOAT(AngleFixed(newangle)),
|
||||||
FIXED_TO_FLOAT(AngleFixed(oldangle-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
|
// if (mo->player)
|
||||||
//CONS_Printf("%d-%d > %d\n", (predictedz), (mo->z), (slopemom.z/2));
|
// 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);
|
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 moveangle = K_MomentumAngle(mo);
|
||||||
angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT));
|
angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT));
|
||||||
|
|
@ -2264,8 +2281,12 @@ boolean P_ZMovement(mobj_t *mo)
|
||||||
if (mo->flags & MF_NOCLIPHEIGHT)
|
if (mo->flags & MF_NOCLIPHEIGHT)
|
||||||
mo->standingslope = NULL;
|
mo->standingslope = NULL;
|
||||||
else if (!onground)
|
else if (!onground)
|
||||||
|
{
|
||||||
|
if (mo->player)
|
||||||
|
// CONS_Printf("ZMovement launch?\n");
|
||||||
P_SlopeLaunch(mo);
|
P_SlopeLaunch(mo);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (mo->type)
|
switch (mo->type)
|
||||||
{
|
{
|
||||||
|
|
@ -2798,6 +2819,20 @@ void P_PlayerZMovement(mobj_t *mo)
|
||||||
mo->eflags &= ~MFE_APPLYPMOMZ;
|
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;
|
mo->z += mo->momz;
|
||||||
onground = P_IsObjectOnGround(mo);
|
onground = P_IsObjectOnGround(mo);
|
||||||
|
|
||||||
|
|
@ -2811,7 +2846,11 @@ void P_PlayerZMovement(mobj_t *mo)
|
||||||
if (mo->flags & MF_NOCLIPHEIGHT)
|
if (mo->flags & MF_NOCLIPHEIGHT)
|
||||||
mo->standingslope = NULL;
|
mo->standingslope = NULL;
|
||||||
else if (!onground)
|
else if (!onground)
|
||||||
|
{
|
||||||
|
CONS_Printf("%s PlayerZMovement launch %d ", player_names[mo->player-players], mo->momz);
|
||||||
P_SlopeLaunch(mo);
|
P_SlopeLaunch(mo);
|
||||||
|
CONS_Printf("%d\n", mo->momz);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clip movement
|
// clip movement
|
||||||
|
|
|
||||||
|
|
@ -301,6 +301,7 @@ TYPEDEF (BasicFF_t);
|
||||||
TYPEDEF (divline_t);
|
TYPEDEF (divline_t);
|
||||||
TYPEDEF (intercept_t);
|
TYPEDEF (intercept_t);
|
||||||
TYPEDEF (opening_t);
|
TYPEDEF (opening_t);
|
||||||
|
TYPEDEF (fofopening_t);
|
||||||
|
|
||||||
// p_mobj.h
|
// p_mobj.h
|
||||||
TYPEDEF (mobj_t);
|
TYPEDEF (mobj_t);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue