From b76c87005b37a0960f15cda6bb040a4784b9e48b Mon Sep 17 00:00:00 2001 From: NepDisk <16447892+NepDisk@users.noreply.github.com> Date: Tue, 3 Sep 2024 21:18:12 -0400 Subject: [PATCH] Fix kartspeed in udmf maps and implement spring terrain type --- src/k_kart.c | 41 +++++++++++++++---------- src/k_terrain.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ src/k_terrain.h | 2 ++ src/p_local.h | 3 +- src/p_map.c | 58 ++++++++++++++++++++++------------- 5 files changed, 147 insertions(+), 37 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 249f6ccf4..9a51032da 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2877,24 +2877,41 @@ fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed) fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower, boolean dorubberband) { + fixed_t k_speed = 150; + fixed_t g_cc = FRACUNIT; + fixed_t xspd = 3072; // 4.6875 aka 3/64 UINT8 kartspeed = player->kartspeed; - fixed_t finalspeed = 0; - const boolean mobjValid = (player->mo != NULL && P_MobjWasRemoved(player->mo) == false); + fixed_t finalspeed; if (doboostpower && !player->pogospring && !P_IsObjectOnGround(player->mo)) return (75*mapobjectscale); // air speed cap - + + switch (gamespeed) + { + case 0: + g_cc = 53248 + xspd; // 50cc = 81.25 + 4.69 = 85.94% + break; + case 2: + g_cc = 77824 + xspd; // 150cc = 118.75 + 4.69 = 123.44% + break; + default: + g_cc = 65536 + xspd; // 100cc = 100.00 + 4.69 = 104.69% + break; + } + if ((gametyperules & GTR_KARMA) && (player->bumpers <= 0)) kartspeed = 1; - finalspeed = K_GetKartSpeedFromStat(kartspeed); + k_speed += kartspeed*3; // 153 - 177 + finalspeed = FixedMul(FixedMul(k_speed<<14, g_cc), player->mo->scale); + if (player->spheres > 0) { fixed_t sphereAdd = (FRACUNIT/60); // 66% at max finalspeed = FixedMul(finalspeed, FRACUNIT + (sphereAdd * player->spheres)); } - + if (K_PlayerUsesBotMovement(player)) { // Increase bot speed by 1-10% depending on difficulty @@ -2908,22 +2925,14 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower, boolean dorubberb } } - if (doboostpower == true) - { - if (mobjValid == true) - { - // Scale with the player. - finalspeed = FixedMul(finalspeed, player->mo->scale); - } - - finalspeed = FixedMul(finalspeed, player->boostpower + player->speedboost); - } - if (dorubberband == true && player->botvars.rubberband < FRACUNIT && K_PlayerUsesBotMovement(player) == true) { finalspeed = FixedMul(finalspeed, player->botvars.rubberband); } + if (doboostpower) + finalspeed = FixedMul(finalspeed, player->boostpower+player->speedboost); + return finalspeed; } diff --git a/src/k_terrain.c b/src/k_terrain.c index bfdb5cb57..d4e74fcd9 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -581,6 +581,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); + + sector->soundorg.z = player->mo->z; + S_StartSound(§or->soundorg, sfx_s3kb1); + } + // Pogospring panel if (terrain->pogoSpring > 0 && !(mo->eflags & MFE_SPRUNG)) { @@ -1463,6 +1520,8 @@ static void K_TerrainDefaults(terrain_t *terrain) terrain->pogoSpring = 0; terrain->speedPad = 0; terrain->speedPadAngle = 0; + terrain->springStrength = 0; + terrain->springStarColor = SKINCOLOR_NONE; terrain->flags = 0; } @@ -1545,6 +1604,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)); diff --git a/src/k_terrain.h b/src/k_terrain.h index adc52cdb9..91560bb91 100644 --- a/src/k_terrain.h +++ b/src/k_terrain.h @@ -116,6 +116,8 @@ typedef struct terrain_s UINT8 pogoSpring; // Is this panel a pogo spring? 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) } terrain_t; diff --git a/src/p_local.h b/src/p_local.h index 419f80cde..8e94c61c5 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -176,7 +176,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); @@ -450,6 +450,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); boolean P_DoSpring(mobj_t *spring, mobj_t *object); fixed_t P_GetFOFTopZAt (ffloor_t *rover, fixed_t x, fixed_t y); diff --git a/src/p_map.c b/src/p_map.c index c8715f820..df881a947 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -272,6 +272,42 @@ 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) +{ + const fixed_t hscale = mapobjectscale + (mapobjectscale - object->scale); + const fixed_t vscale = mapobjectscale + (object->scale - mapobjectscale); + + 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) + object->momz = FixedMul(vertispeed,FixedSqrt(FixedMul(vscale, scaleVal))); + + if (horizspeed) + { + if (!object->player) + P_InstaThrust(object, finalAngle, FixedMul(horizspeed,FixedSqrt(FixedMul(hscale, scaleVal)))); + else + { + fixed_t finalSpeed = FixedDiv(horizspeed, hscale); + fixed_t pSpeed = object->player->speed; + + if (pSpeed > finalSpeed) + finalSpeed = pSpeed; + + P_InstaThrust(object, finalAngle, FixedMul(finalSpeed,FixedSqrt(FixedMul(hscale, scaleVal)))); + } + } +} + // // P_DoSpring // @@ -298,6 +334,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->standingslope = NULL; // Okay, now we can't return - no launching off at silly angles for you. object->eflags |= MFE_SPRUNG; // apply this flag asap! + spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify if (horizspeed && vertispeed) // Mimic SA @@ -337,25 +374,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) P_TryMove(object, spring->x + offx, spring->y + offy, true); } - if (vertispeed) - object->momz = FixedMul(vertispeed,FixedSqrt(FixedMul(vscale, spring->scale))); - - if (horizspeed) - { - if (!object->player) - P_InstaThrust(object, spring->angle, FixedMul(horizspeed,FixedSqrt(FixedMul(hscale, spring->scale)))); - else - { - fixed_t finalSpeed = FixedDiv(horizspeed, hscale); - fixed_t pSpeed = object->player->speed; - - if (pSpeed > finalSpeed) - finalSpeed = pSpeed; - - P_InstaThrust(object, spring->angle, FixedMul(finalSpeed,FixedSqrt(FixedMul(hscale, spring->scale)))); - } - } - + P_DoSpringEx(object, mapobjectscale, vertispeed, horizspeed, spring->angle); // Re-solidify spring->flags |= (spring->info->flags & (MF_SPECIAL|MF_SOLID)); @@ -365,7 +384,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { if (spring->flags & MF_ENEMY) // Spring shells P_SetTarget(&spring->target, object); - if (horizspeed && object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0) { object->angle = spring->angle;