Merge branch 'spring-terrain' into 'master'

Spring terrain

Closes #362

See merge request KartKrew/Kart!820
This commit is contained in:
Sal 2022-12-19 05:27:40 +00:00
commit 3d33b95094
4 changed files with 180 additions and 72 deletions

View file

@ -554,6 +554,63 @@ void K_ProcessTerrainEffect(mobj_t *mo)
}
}
// Spring
if (terrain->springStrength)
{
sector_t *sector = player->mo->subsector->sector;
const pslope_t *slope;
angle_t angle = 0;
fixed_t co = FRACUNIT;
fixed_t si = 0;
// FIXME: come up with a better way to get the touched
// texture's slope to this function. At least this
// will work for 90% of scenarios...
if (player->mo->eflags & MFE_VERTICALFLIP)
{
if (player->mo->ceilingrover != NULL)
{
slope = *player->mo->ceilingrover->b_slope;
}
else
{
slope = sector->c_slope;
}
}
else
{
if (player->mo->floorrover != NULL)
{
slope = *player->mo->ceilingrover->t_slope;
}
else
{
slope = sector->f_slope;
}
}
if (slope)
{
const angle_t fa = (slope->zangle >> ANGLETOFINESHIFT);
co = FINECOSINE(fa) * P_MobjFlip(player->mo);
si = -(FINESINE(fa));
angle = slope->xydirection;
}
P_DoSpringEx(player->mo, mapobjectscale,
FixedMul(terrain->springStrength, co),
FixedMul(terrain->springStrength, si),
angle, terrain->springStarColor);
sector->soundorg.z = player->mo->z;
S_StartSound(&sector->soundorg, sfx_s3kb1);
}
// Bumpy floor
if (terrain->flags & TRF_STAIRJANK)
{
@ -1487,6 +1544,8 @@ static void K_TerrainDefaults(terrain_t *terrain)
terrain->trickPanel = 0;
terrain->speedPad = 0;
terrain->speedPadAngle = 0;
terrain->springStrength = 0;
terrain->springStarColor = SKINCOLOR_NONE;
terrain->flags = 0;
}
@ -1565,6 +1624,27 @@ static void K_ParseTerrainParameter(size_t i, char *param, char *val)
{
terrain->speedPadAngle = FixedAngle(FLOAT_TO_FIXED(atof(val)));
}
else if (stricmp(param, "springStrength") == 0)
{
const double fval = atof(val);
if (fpclassify(fval) == FP_ZERO)
{
terrain->springStrength = 0;
}
else
{
// Springs increase in stength by 1.6 times the
// previous strength. Grey spring is 25 and
// 25/1.6 = 15.625
terrain->springStrength =
FLOAT_TO_FIXED(15.625 * pow(1.6, fval));
}
}
else if (stricmp(param, "springStarColor") == 0)
{
terrain->springStarColor = get_number(val);
}
else if (stricmp(param, "floorClip") == 0)
{
terrain->floorClip = FLOAT_TO_FIXED(atof(val));

View file

@ -116,6 +116,8 @@ struct terrain_t
fixed_t trickPanel; // Trick panel strength
fixed_t speedPad; // Speed pad strength
angle_t speedPadAngle; // Speed pad angle
fixed_t springStrength; // Spring strength
UINT16 springStarColor; // Spring star color
fixed_t floorClip; // Offset for sprites on this ground
UINT32 flags; // Flag values (see: terrain_flags_t)
};

View file

@ -170,7 +170,7 @@ boolean P_IsObjectInGoop(mobj_t *mo);
boolean P_IsObjectOnGround(mobj_t *mo);
boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec);
boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec); // SRB2Kart
#define P_IsObjectFlipped(o) ((o)->eflags & MFE_VERTICALFLIP)
#define P_IsObjectFlipped(o) (((o)->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP)
boolean P_InQuicksand(mobj_t *mo);
boolean P_PlayerHitFloor(player_t *player, boolean fromAir, angle_t oldPitch, angle_t oldRoll);
@ -473,6 +473,7 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height);
fixed_t P_CeilingzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height);
BlockItReturn_t PIT_PushableMoved(mobj_t *thing);
void P_DoSpringEx(mobj_t *object, fixed_t scaleVal, fixed_t vertispeed, fixed_t horizspeed, angle_t finalAngle, UINT16 starcolor);
boolean P_DoSpring(mobj_t *spring, mobj_t *object);
fixed_t P_GetFOFTopZAt (ffloor_t *rover, fixed_t x, fixed_t y);

View file

@ -268,6 +268,96 @@ static boolean P_SpecialIsLinedefCrossType(line_t *ld)
return linedefcrossspecial;
}
void
P_DoSpringEx
( mobj_t * object,
fixed_t scaleVal,
fixed_t vertispeed,
fixed_t horizspeed,
angle_t finalAngle,
UINT16 starcolor)
{
if (horizspeed < 0)
{
horizspeed = -(horizspeed);
finalAngle += ANGLE_180;
}
object->standingslope = NULL; // Okay, now we know it's not going to be relevant - no launching off at silly angles for you.
object->terrain = NULL;
object->eflags |= MFE_SPRUNG; // apply this flag asap!
if ((vertispeed < 0) ^ P_IsObjectFlipped(object))
vertispeed *= 2;
if (vertispeed)
{
object->momz = FixedMul(vertispeed, scaleVal);
}
if (horizspeed)
{
fixed_t finalSpeed = FixedMul(horizspeed, scaleVal);
fixed_t objectSpeed;
if (object->player)
objectSpeed = object->player->speed;
else
objectSpeed = R_PointToDist2(0, 0, object->momx, object->momy);
if (!vertispeed)
{
// Scale to gamespeed
finalSpeed = FixedMul(finalSpeed, K_GetKartGameSpeedScalar(gamespeed));
// Reflect your momentum angle against the surface of horizontal springs.
// This makes it a bit more interesting & unique than just being a speed boost in a pre-defined direction
if (object->momx || object->momy)
{
finalAngle = K_ReflectAngle(
R_PointToAngle2(0, 0, object->momx, object->momy), finalAngle,
objectSpeed, finalSpeed
);
}
}
// Horizontal speed is used as a minimum thrust, not a direct replacement
finalSpeed = max(objectSpeed, finalSpeed);
P_InstaThrust(object, finalAngle, finalSpeed);
}
if (object->player)
{
K_TumbleInterrupt(object->player);
P_ResetPlayer(object->player);
object->player->springstars = max(abs(vertispeed), horizspeed) / FRACUNIT / 2;
object->player->springcolor = starcolor;
// Less friction when hitting springs
if (!object->player->tiregrease)
{
UINT8 i;
for (i = 0; i < 2; i++)
{
mobj_t *grease;
grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE);
P_SetTarget(&grease->target, object);
grease->angle = K_MomentumAngle(object);
grease->extravalue1 = i;
K_ReduceVFX(grease, object->player);
}
}
if (object->player->tiregrease < greasetics)
{
object->player->tiregrease = greasetics;
}
}
}
//
// P_DoSpring
//
@ -282,8 +372,8 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
fixed_t vertispeed = spring->info->mass;
fixed_t horizspeed = spring->info->damage;
UINT16 starcolor = (spring->info->painchance % numskincolors);
fixed_t savemomx = 0;
fixed_t savemomy = 0;
fixed_t savemomx = object->momx;
fixed_t savemomy = object->momy;
statenum_t raisestate = spring->info->raisestate;
// Object was already sprung this tic
@ -312,18 +402,11 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
return false;
}
object->standingslope = NULL; // Okay, now we know it's not going to be relevant - no launching off at silly angles for you.
object->terrain = NULL;
object->eflags |= MFE_SPRUNG; // apply this flag asap!
spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
if (spring->eflags & MFE_VERTICALFLIP)
vertispeed *= -1;
if ((spring->eflags ^ object->eflags) & MFE_VERTICALFLIP)
vertispeed *= 2;
// Vertical springs teleport you on TOP of them.
if (vertispeed > 0)
{
@ -355,43 +438,11 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
P_TryMove(object, spring->x + offx, spring->y + offy, true, NULL);
}
if (vertispeed)
{
object->momz = FixedMul(vertispeed, scaleVal);
}
object->momx = savemomx;
object->momy = savemomy;
if (horizspeed)
{
angle_t finalAngle = spring->angle;
fixed_t finalSpeed = FixedMul(horizspeed, scaleVal);
fixed_t objectSpeed;
if (object->player)
objectSpeed = object->player->speed;
else
objectSpeed = R_PointToDist2(0, 0, savemomx, savemomy);
if (!vertispeed)
{
// Scale to gamespeed
finalSpeed = FixedMul(finalSpeed, K_GetKartGameSpeedScalar(gamespeed));
// Reflect your momentum angle against the surface of horizontal springs.
// This makes it a bit more interesting & unique than just being a speed boost in a pre-defined direction
if (savemomx || savemomy)
{
finalAngle = K_ReflectAngle(
R_PointToAngle2(0, 0, savemomx, savemomy), finalAngle,
objectSpeed, finalSpeed
);
}
}
// Horizontal speed is used as a minimum thrust, not a direct replacement
finalSpeed = max(objectSpeed, finalSpeed);
P_InstaThrust(object, finalAngle, finalSpeed);
}
P_DoSpringEx(object, scaleVal, vertispeed, horizspeed,
spring->angle, starcolor);
// Re-solidify
spring->flags |= (spring->info->flags & (MF_SPRING|MF_SPECIAL));
@ -403,32 +454,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
P_SetTarget(&spring->target, object);
}
K_TumbleInterrupt(object->player);
P_ResetPlayer(object->player);
object->player->springstars = max(abs(vertispeed), horizspeed) / FRACUNIT / 2;
object->player->springcolor = starcolor;
// Less friction when hitting springs
if (!object->player->tiregrease)
{
UINT8 i;
for (i = 0; i < 2; i++)
{
mobj_t *grease;
grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE);
P_SetTarget(&grease->target, object);
grease->angle = K_MomentumAngle(object);
grease->extravalue1 = i;
K_ReduceVFX(grease, object->player);
}
}
if (object->player->tiregrease < greasetics)
{
object->player->tiregrease = greasetics;
}
if (spring->type == MT_POGOSPRING)
{
if (spring->reactiontime == 0)