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);
|
||||
CONS_Printf("%s FastFallBounce %d\n", player_names[player-players], player->mo->momz);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
23
src/p_map.c
23
src/p_map.c
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
458
src/p_maputl.c
458
src/p_maputl.c
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
81
src/p_mobj.c
81
src/p_mobj.c
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue