mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-21 22:22:32 +00:00
Improve shadow code yet again by testing highest value of slopes
This makes it follow the sprites a bit better on slopes. Also split into a sub-function so that Banana doesn't need the duplicated code anymore. The accuracy can be further improved on by doing the calculation 3 extra times for every surface, for each corner of the hitbox -- it wouldn't be THAT much more expensive, but it would only make subtle differences on sector boundaries that we usually zoom past anyway, so I figured it wasn't worth it. (It'll be easy enough to do so if we decide that we want the uber-accuracy)
This commit is contained in:
parent
f3f0b5edda
commit
24feb81671
3 changed files with 170 additions and 199 deletions
77
src/k_kart.c
77
src/k_kart.c
|
|
@ -4527,82 +4527,11 @@ static void K_MoveHeldObjects(player_t *player)
|
|||
P_TeleportMove(cur, targx, targy, cur->z);
|
||||
|
||||
#ifdef ESLOPE
|
||||
// We gotta do ALL of this... just so that bananas can tilt in OGL :V
|
||||
if (P_IsObjectOnGround(cur))
|
||||
{
|
||||
pslope_t *slope = NULL;
|
||||
sector_t *sec = R_PointInSubsector(cur->x, cur->y)->sector;
|
||||
boolean flip = (cur->eflags & MFE_VERTICALFLIP);
|
||||
|
||||
if (flip)
|
||||
{
|
||||
if (sec->c_slope)
|
||||
{
|
||||
slope = sec->c_slope;
|
||||
targz = P_GetZAt(sec->c_slope, cur->x, cur->y);
|
||||
}
|
||||
else
|
||||
targz = sec->ceilingheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sec->f_slope)
|
||||
{
|
||||
slope = sec->f_slope;
|
||||
targz = P_GetZAt(sec->f_slope, cur->x, cur->y);
|
||||
}
|
||||
else
|
||||
targz = sec->floorheight;
|
||||
}
|
||||
|
||||
// Check FOFs for a better suited slope
|
||||
if (sec->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
||||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t surface;
|
||||
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (!((rover->flags & FF_BLOCKOTHERS) || (rover->flags & FF_QUICKSAND)) || (rover->flags & FF_SWIMMABLE))
|
||||
continue;
|
||||
|
||||
if (flip)
|
||||
{
|
||||
surface = *rover->bottomheight;
|
||||
if (*rover->b_slope)
|
||||
surface = P_GetZAt(*rover->b_slope, cur->x, cur->y);
|
||||
|
||||
if (surface < targz && surface > (cur->z + cur->height))
|
||||
{
|
||||
targz = surface;
|
||||
if (*rover->b_slope)
|
||||
slope = *rover->b_slope;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
surface = *rover->topheight;
|
||||
if (*rover->t_slope)
|
||||
surface = P_GetZAt(*rover->t_slope, cur->x, cur->y);
|
||||
|
||||
if (surface > targz && surface < cur->z)
|
||||
{
|
||||
targz = surface;
|
||||
if (*rover->t_slope)
|
||||
slope = *rover->t_slope;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur->standingslope = slope;
|
||||
#ifdef HWRENDER
|
||||
cur->modeltilt = cur->standingslope;
|
||||
#endif
|
||||
// Slope values are set in the function, but we DON'T want to use its return value.
|
||||
P_CalculateShadowFloor(cur, cur->x, cur->y, cur->z,
|
||||
cur->radius, cur->height, (cur->eflags & MFE_VERTICALFLIP), false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
|
|||
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
|
||||
//void P_RunShields(void);
|
||||
void P_RunOverlays(void);
|
||||
fixed_t P_CalculateShadowFloor(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player);
|
||||
void P_RunShadows(void);
|
||||
void P_MobjThinker(mobj_t *mobj);
|
||||
boolean P_RailThinker(mobj_t *mobj);
|
||||
|
|
|
|||
291
src/p_mobj.c
291
src/p_mobj.c
|
|
@ -6205,6 +6205,170 @@ static void P_RemoveOverlay(mobj_t *thing)
|
|||
}
|
||||
}
|
||||
|
||||
// Simplified version of a code bit in P_MobjFloorZ
|
||||
static fixed_t P_ShadowSlopeZ(pslope_t *slope, fixed_t x, fixed_t y, fixed_t radius, boolean ceiling)
|
||||
{
|
||||
fixed_t testx, testy;
|
||||
|
||||
if (slope->d.x < 0)
|
||||
testx = radius;
|
||||
else
|
||||
testx = -radius;
|
||||
|
||||
if (slope->d.y < 0)
|
||||
testy = radius;
|
||||
else
|
||||
testy = -radius;
|
||||
|
||||
if ((slope->zdelta > 0) ^ !!(ceiling))
|
||||
{
|
||||
testx = -testx;
|
||||
testy = -testy;
|
||||
}
|
||||
|
||||
testx += x;
|
||||
testy += y;
|
||||
|
||||
return P_GetZAt(slope, testx, testy);
|
||||
}
|
||||
|
||||
// Sets standingslope/modeltilt, returns z position for shadows; used also for stuff like bananas
|
||||
// (I would've preferred to be able to return both the slope & z, but I'll take what I can get...)
|
||||
fixed_t P_CalculateShadowFloor(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player)
|
||||
{
|
||||
fixed_t newz;
|
||||
sector_t *sec;
|
||||
#ifdef ESLOPE
|
||||
pslope_t *slope = NULL;
|
||||
#endif
|
||||
|
||||
sec = R_PointInSubsector(x, y)->sector;
|
||||
|
||||
if (flip)
|
||||
{
|
||||
#ifdef ESLOPE
|
||||
if (sec->c_slope)
|
||||
{
|
||||
slope = sec->c_slope;
|
||||
newz = P_ShadowSlopeZ(slope, x, y, radius, true);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
newz = sec->ceilingheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef ESLOPE
|
||||
if (sec->f_slope)
|
||||
{
|
||||
slope = sec->f_slope;
|
||||
newz = P_ShadowSlopeZ(slope, x, y, radius, false);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
newz = sec->floorheight;
|
||||
}
|
||||
|
||||
// Check FOFs for a better suited slope
|
||||
if (sec->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
||||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t top, bottom;
|
||||
fixed_t d1, d2;
|
||||
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if ((!(((rover->flags & FF_BLOCKPLAYER && player)
|
||||
|| (rover->flags & FF_BLOCKOTHERS && !player))
|
||||
|| (rover->flags & FF_QUICKSAND))
|
||||
|| (rover->flags & FF_SWIMMABLE)))
|
||||
continue;
|
||||
|
||||
#ifdef ESLOPE
|
||||
if (*rover->t_slope)
|
||||
top = P_ShadowSlopeZ(*rover->t_slope, x, y, radius, false);
|
||||
else
|
||||
#endif
|
||||
top = *rover->topheight;
|
||||
|
||||
#ifdef ESLOPE
|
||||
if (*rover->b_slope)
|
||||
bottom = P_ShadowSlopeZ(*rover->b_slope, x, y, radius, true);
|
||||
else
|
||||
#endif
|
||||
bottom = *rover->bottomheight;
|
||||
|
||||
if (flip)
|
||||
{
|
||||
if (rover->flags & FF_QUICKSAND)
|
||||
{
|
||||
if (z < top && (z + height) > bottom)
|
||||
{
|
||||
if (newz > (z + height))
|
||||
{
|
||||
newz = (z + height);
|
||||
slope = NULL;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
d1 = (z + height) - (top + ((bottom - top)/2));
|
||||
d2 = z - (top + ((bottom - top)/2));
|
||||
|
||||
if (bottom < newz && abs(d1) < abs(d2))
|
||||
{
|
||||
newz = bottom;
|
||||
#ifdef ESLOPE
|
||||
if (*rover->b_slope)
|
||||
slope = *rover->b_slope;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rover->flags & FF_QUICKSAND)
|
||||
{
|
||||
if (z < top && (z + height) > bottom)
|
||||
{
|
||||
if (newz < z)
|
||||
{
|
||||
newz = z;
|
||||
slope = NULL;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
d1 = z - (bottom + ((top - bottom)/2));
|
||||
d2 = (z + height) - (bottom + ((top - bottom)/2));
|
||||
|
||||
if (top > newz && abs(d1) < abs(d2))
|
||||
{
|
||||
newz = top;
|
||||
#ifdef ESLOPE
|
||||
if (*rover->t_slope)
|
||||
slope = *rover->t_slope;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
mobj->standingslope = slope;
|
||||
#endif
|
||||
#ifdef HWRENDER
|
||||
mobj->modeltilt = slope;
|
||||
#endif
|
||||
|
||||
return newz;
|
||||
}
|
||||
|
||||
void P_RunShadows(void)
|
||||
{
|
||||
mobj_t *mobj, *next, *dest;
|
||||
|
|
@ -6213,10 +6377,6 @@ void P_RunShadows(void)
|
|||
{
|
||||
boolean flip;
|
||||
fixed_t newz;
|
||||
sector_t *sec;
|
||||
#ifdef ESLOPE
|
||||
pslope_t *slope = NULL;
|
||||
#endif
|
||||
|
||||
next = mobj->hnext;
|
||||
P_SetTarget(&mobj->hnext, NULL);
|
||||
|
|
@ -6230,127 +6390,8 @@ void P_RunShadows(void)
|
|||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
flip = (mobj->eflags & MFE_VERTICALFLIP);
|
||||
|
||||
sec = R_PointInSubsector(mobj->target->x, mobj->target->y)->sector;
|
||||
|
||||
if (flip)
|
||||
{
|
||||
#ifdef ESLOPE
|
||||
if (sec->c_slope)
|
||||
{
|
||||
slope = sec->c_slope;
|
||||
newz = P_GetZAt(sec->c_slope, mobj->target->x, mobj->target->y);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
newz = sec->ceilingheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef ESLOPE
|
||||
if (sec->f_slope)
|
||||
{
|
||||
slope = sec->f_slope;
|
||||
newz = P_GetZAt(sec->f_slope, mobj->target->x, mobj->target->y);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
newz = sec->floorheight;
|
||||
}
|
||||
|
||||
// Check FOFs for a better suited slope
|
||||
if (sec->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
||||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t top, bottom;
|
||||
fixed_t d1, d2;
|
||||
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if ((!(((rover->flags & FF_BLOCKPLAYER && mobj->target->player)
|
||||
|| (rover->flags & FF_BLOCKOTHERS && !mobj->target->player))
|
||||
|| (rover->flags & FF_QUICKSAND))
|
||||
|| (rover->flags & FF_SWIMMABLE)))
|
||||
continue;
|
||||
|
||||
#ifdef ESLOPE
|
||||
if (*rover->t_slope)
|
||||
top = P_GetZAt(*rover->t_slope, mobj->target->x, mobj->target->y);
|
||||
else
|
||||
#endif
|
||||
top = *rover->topheight;
|
||||
|
||||
#ifdef ESLOPE
|
||||
if (*rover->b_slope)
|
||||
bottom = P_GetZAt(*rover->b_slope, mobj->target->x, mobj->target->y);
|
||||
else
|
||||
#endif
|
||||
bottom = *rover->bottomheight;
|
||||
|
||||
if (flip)
|
||||
{
|
||||
if (rover->flags & FF_QUICKSAND)
|
||||
{
|
||||
if (mobj->target->z < top && (mobj->target->z + mobj->target->height) > bottom)
|
||||
{
|
||||
if (newz > (mobj->target->z + mobj->target->height))
|
||||
{
|
||||
newz = (mobj->target->z + mobj->target->height);
|
||||
slope = NULL;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
d1 = (mobj->target->z + mobj->target->height) - (top + ((bottom - top)/2));
|
||||
d2 = mobj->target->z - (top + ((bottom - top)/2));
|
||||
|
||||
if (bottom < newz && abs(d1) < abs(d2))
|
||||
{
|
||||
newz = bottom;
|
||||
#ifdef ESLOPE
|
||||
if (*rover->b_slope)
|
||||
slope = *rover->b_slope;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rover->flags & FF_QUICKSAND)
|
||||
{
|
||||
if (mobj->target->z < top && (mobj->target->z + mobj->target->height) > bottom)
|
||||
{
|
||||
if (newz < mobj->target->z)
|
||||
{
|
||||
newz = mobj->target->z;
|
||||
slope = NULL;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
d1 = mobj->target->z - (bottom + ((top - bottom)/2));
|
||||
d2 = (mobj->target->z + mobj->target->height) - (bottom + ((top - bottom)/2));
|
||||
|
||||
if (top > newz && abs(d1) < abs(d2))
|
||||
{
|
||||
newz = top;
|
||||
#ifdef ESLOPE
|
||||
if (*rover->t_slope)
|
||||
slope = *rover->t_slope;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mobj->standingslope = slope;
|
||||
#ifdef HWRENDER
|
||||
mobj->modeltilt = mobj->standingslope;
|
||||
#endif
|
||||
newz = P_CalculateShadowFloor(mobj, mobj->target->x, mobj->target->y, mobj->target->z,
|
||||
mobj->target->radius, mobj->target->height, flip, (mobj->target->player != NULL));
|
||||
|
||||
if (flip)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue