From f3bb8833a1fb64698d6069d632047b39d8400106 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Mar 2022 17:10:27 -0400 Subject: [PATCH 01/26] Tumble when not landing upright on slopes --- src/k_kart.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/k_kart.h | 1 + src/p_local.h | 2 +- src/p_map.c | 16 ++++++---- src/p_mobj.c | 6 +++- src/p_user.c | 11 +++++-- 6 files changed, 109 insertions(+), 10 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 58cb6fe31..7bd45c029 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3407,6 +3407,89 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) P_StartQuake(64<angle >> ANGLETOFINESHIFT); + fixed_t rollMul = FINECOSINE(mobj->angle >> ANGLETOFINESHIFT); + + return FixedMul(pitch, pitchMul) + FixedMul(roll, rollMul); +} + +#define STEEP_VAL (ANG60) + +void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll) +{ + fixed_t gravityadjust; + angle_t oldSlope, newSlope; + angle_t slopeDelta; + angle_t oldSteepness; + + // If you don't land upright on a slope, then you tumble, + // kinda like Kirby Air Ride + + if (player->tumbleBounces) + { + // Already tumbling. + return; + } + + oldSlope = K_TumbleSlope(player->mo, oldPitch, oldRoll); + + oldSteepness = oldSlope; + if (oldSteepness > ANGLE_180) + { + oldSteepness = InvAngle(oldSteepness); + } + + if (oldSteepness <= STEEP_VAL) + { + // Transferring from flat ground to a steep slope + // is a free action. (The other way around isn't, though.) + return; + } + + newSlope = K_TumbleSlope(player->mo, player->mo->pitch, player->mo->roll); + slopeDelta = AngleDelta(oldSlope, newSlope); + + if (slopeDelta <= STEEP_VAL) + { + // Needs to be VERY steep before we'll punish this. + return; + } + + // Oh jeez, you landed on your side. + // You get to tumble. + +#if 0 + // Single, medium bounce + player->tumbleBounces = TUMBLEBOUNCES; + player->tumbleHeight = 30; +#else + // Two small bounces + player->tumbleBounces = TUMBLEBOUNCES-1; + player->tumbleHeight = 20; +#endif + + player->pflags &= ~PF_TUMBLESOUND; + S_StartSound(player->mo, sfx_s3k9b); + + gravityadjust = P_GetMobjGravity(player->mo)/2; // so we'll halve it for our calculations. + + if (player->mo->eflags & MFE_UNDERWATER) + gravityadjust /= 2; // halve "gravity" underwater + + // and then modulate momz like that... + player->mo->momz = -gravityadjust * player->tumbleHeight; + + P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); + + if (P_IsDisplayPlayer(player)) + P_StartQuake(64<mo->pitch = player->mo->roll = 0; +} + static boolean K_LastTumbleBounceCondition(player_t *player) { return (player->tumbleBounces > TUMBLEBOUNCES && player->tumbleHeight < 60); diff --git a/src/k_kart.h b/src/k_kart.h index 91024488f..605e0f410 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -70,6 +70,7 @@ void K_DoInstashield(player_t *player); void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); +void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll); INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_DebtStingPlayer(player_t *player, mobj_t *source); void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers); diff --git a/src/p_local.h b/src/p_local.h index 4940daf81..1bcc2f6d8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -169,7 +169,7 @@ 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) boolean P_InQuicksand(mobj_t *mo); -boolean P_PlayerHitFloor(player_t *player, boolean fromAir); +boolean P_PlayerHitFloor(player_t *player, boolean fromAir, angle_t oldPitch, angle_t oldRoll); void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative); void P_RestoreMusic(player_t *player); diff --git a/src/p_map.c b/src/p_map.c index 6954d6e11..996d1c2db 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2667,12 +2667,15 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thing->momz <= 0) { + angle_t oldPitch = thing->pitch; + angle_t oldRoll = thing->roll; + thing->standingslope = tmfloorslope; P_SetPitchRollFromSlope(thing, thing->standingslope); - if (thing->momz == 0 && thing->player && !startingonground) + if (thing->momz == 0 && thing->player) { - P_PlayerHitFloor(thing->player, true); + P_PlayerHitFloor(thing->player, !startingonground, oldPitch, oldRoll); } } } @@ -2687,12 +2690,15 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thing->momz >= 0) { + angle_t oldPitch = thing->pitch; + angle_t oldRoll = thing->roll; + thing->standingslope = tmceilingslope; P_SetPitchRollFromSlope(thing, thing->standingslope); - if (thing->momz == 0 && thing->player && !startingonground) + if (thing->momz == 0 && thing->player) { - P_PlayerHitFloor(thing->player, true); + P_PlayerHitFloor(thing->player, !startingonground, oldPitch, oldRoll); } } } @@ -2983,7 +2989,7 @@ static boolean P_ThingHeightClip(mobj_t *thing) } if ((P_MobjFlip(thing)*(thing->z - oldz) > 0 || hitfloor) && thing->player) - P_PlayerHitFloor(thing->player, !onfloor); + P_PlayerHitFloor(thing->player, !onfloor, thing->pitch, thing->roll); // debug: be sure it falls to the floor thing->eflags &= ~MFE_ONGROUND; diff --git a/src/p_mobj.c b/src/p_mobj.c index 3a4cd1751..953d641c0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2685,6 +2685,7 @@ static boolean P_PlayerPolyObjectZMovement(mobj_t *mo) void P_PlayerZMovement(mobj_t *mo) { boolean onground; + angle_t oldPitch, oldRoll; I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); @@ -2692,6 +2693,9 @@ void P_PlayerZMovement(mobj_t *mo) if (!mo->player) return; + oldPitch = mo->pitch; + oldRoll = mo->roll; + // Intercept the stupid 'fall through 3dfloors' bug if (mo->subsector->sector->ffloors) P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0); @@ -2768,7 +2772,7 @@ void P_PlayerZMovement(mobj_t *mo) mo->pmomz = 0; // We're on a new floor, don't keep doing platform movement. mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack - clipmomz = P_PlayerHitFloor(mo->player, true); + clipmomz = P_PlayerHitFloor(mo->player, true, oldPitch, oldRoll); P_PlayerPolyObjectZMovement(mo); if (clipmomz) diff --git a/src/p_user.c b/src/p_user.c index 8cc74c837..af0aff8b1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1316,7 +1316,7 @@ void P_DoPlayerExit(player_t *player) // // Handles player hitting floor surface. // Returns whether to clip momz. -boolean P_PlayerHitFloor(player_t *player, boolean fromAir) +boolean P_PlayerHitFloor(player_t *player, boolean fromAir, angle_t oldPitch, angle_t oldRoll) { boolean clipmomz; @@ -1329,6 +1329,11 @@ boolean P_PlayerHitFloor(player_t *player, boolean fromAir) K_SpawnSplashForMobj(player->mo, abs(player->mo->momz)); } + if (player->mo->health) + { + K_CheckSlopeTumble(player, oldPitch, oldRoll); + } + return clipmomz; } @@ -1639,7 +1644,7 @@ static void P_CheckQuicksand(player_t *player) player->mo->z = ceilingheight - player->mo->height; if (player->mo->momz <= 0) - P_PlayerHitFloor(player, false); + P_PlayerHitFloor(player, false, player->mo->roll, player->mo->pitch); } else { @@ -1651,7 +1656,7 @@ static void P_CheckQuicksand(player_t *player) player->mo->z = floorheight; if (player->mo->momz >= 0) - P_PlayerHitFloor(player, false); + P_PlayerHitFloor(player, false, player->mo->roll, player->mo->pitch); } friction = abs(rover->master->v1->y - rover->master->v2->y)>>6; From c207de5d5d7783c452b0db43728f64fbb17c02a2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Mar 2022 19:04:18 -0400 Subject: [PATCH 02/26] Tilt towards even while falling, make more strict as a result --- src/k_kart.c | 2 +- src/p_mobj.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 7bd45c029..082f4bf90 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3415,7 +3415,7 @@ static angle_t K_TumbleSlope(mobj_t *mobj, angle_t pitch, angle_t roll) return FixedMul(pitch, pitchMul) + FixedMul(roll, rollMul); } -#define STEEP_VAL (ANG60) +#define STEEP_VAL (ANGLE_45 - ANGLE_11hh) // (ANG60) void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 953d641c0..e92a98639 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2808,6 +2808,47 @@ void P_PlayerZMovement(mobj_t *mo) mo->eflags &= ~MFE_JUSTHITFLOOR; P_CheckGravity(mo, true); } + + // Even out pitch & roll slowly over time when falling. + // Helps give OpenGL models a bit of the tumble tell. + if (P_MobjFlip(mo) * mo->momz < 0) + { + const angle_t evenSpeed = (ANG1 << 1) / 3; // 0.66 degrees + INT32 pitchDelta = AngleDeltaSigned(mo->pitch, 0); + INT32 rollDelta = AngleDeltaSigned(mo->roll, 0); + + if (abs(pitchDelta) <= evenSpeed) + { + mo->pitch = 0; + } + else + { + if (pitchDelta > 0) + { + mo->pitch -= evenSpeed; + } + else + { + mo->pitch += evenSpeed; + } + } + + if (abs(rollDelta) <= evenSpeed) + { + mo->roll = 0; + } + else + { + if (rollDelta > 0) + { + mo->roll -= evenSpeed; + } + else + { + mo->roll += evenSpeed; + } + } + } } if (((mo->eflags & MFE_VERTICALFLIP && mo->z < mo->floorz) || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z + mo->height > mo->ceilingz)) From 421d850a5b69054705934e3a3dc623667d986a51 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Mar 2022 19:06:09 -0400 Subject: [PATCH 03/26] Use <= 0 so it happens while respawning. --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e92a98639..d8f8f025b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2811,7 +2811,7 @@ void P_PlayerZMovement(mobj_t *mo) // Even out pitch & roll slowly over time when falling. // Helps give OpenGL models a bit of the tumble tell. - if (P_MobjFlip(mo) * mo->momz < 0) + if (P_MobjFlip(mo) * mo->momz <= 0) { const angle_t evenSpeed = (ANG1 << 1) / 3; // 0.66 degrees INT32 pitchDelta = AngleDeltaSigned(mo->pitch, 0); From 60d72b5c202d37fd3e925a9ff380b765cd0042eb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Mar 2022 22:14:45 -0400 Subject: [PATCH 04/26] Make it flatten out faster & while rising, add a cap to the flattening, flatten out completely while respawning. --- src/k_kart.c | 2 +- src/p_mobj.c | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 082f4bf90..49f199932 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3415,7 +3415,7 @@ static angle_t K_TumbleSlope(mobj_t *mobj, angle_t pitch, angle_t roll) return FixedMul(pitch, pitchMul) + FixedMul(roll, rollMul); } -#define STEEP_VAL (ANGLE_45 - ANGLE_11hh) // (ANG60) +#define STEEP_VAL (ANGLE_45) void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll) { diff --git a/src/p_mobj.c b/src/p_mobj.c index d8f8f025b..ad79f6353 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2811,41 +2811,46 @@ void P_PlayerZMovement(mobj_t *mo) // Even out pitch & roll slowly over time when falling. // Helps give OpenGL models a bit of the tumble tell. - if (P_MobjFlip(mo) * mo->momz <= 0) { - const angle_t evenSpeed = (ANG1 << 1) / 3; // 0.66 degrees + const angle_t speed = ANG1; + angle_t dest = ANGLE_45 + (ANG10 >> 1); INT32 pitchDelta = AngleDeltaSigned(mo->pitch, 0); INT32 rollDelta = AngleDeltaSigned(mo->roll, 0); - if (abs(pitchDelta) <= evenSpeed) + if (mo->player->respawn.state != RESPAWNST_NONE) + { + dest = 0; + } + + if (abs(pitchDelta) <= speed && dest == 0) { mo->pitch = 0; } - else + else if (abs(pitchDelta) > dest) { if (pitchDelta > 0) { - mo->pitch -= evenSpeed; + mo->pitch -= speed; } else { - mo->pitch += evenSpeed; + mo->pitch += speed; } } - if (abs(rollDelta) <= evenSpeed) + if (abs(rollDelta) <= speed && dest == 0) { mo->roll = 0; } - else + else if (abs(rollDelta) > dest) { if (rollDelta > 0) { - mo->roll -= evenSpeed; + mo->roll -= speed; } else { - mo->roll += evenSpeed; + mo->roll += speed; } } } From f06be5ce1d0a62be6c8c1ac6f35fb1b9c282f313 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Mar 2022 22:37:43 -0400 Subject: [PATCH 05/26] Make it the tiniest bit more aggressive again - Do it while falling agaaainnn - Double even-out speed - Fix Mario Kart 64 --- src/k_kart.c | 20 ++++++++++---------- src/p_mobj.c | 5 +++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 49f199932..f019eef50 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3412,17 +3412,23 @@ static angle_t K_TumbleSlope(mobj_t *mobj, angle_t pitch, angle_t roll) fixed_t pitchMul = -FINESINE(mobj->angle >> ANGLETOFINESHIFT); fixed_t rollMul = FINECOSINE(mobj->angle >> ANGLETOFINESHIFT); - return FixedMul(pitch, pitchMul) + FixedMul(roll, rollMul); + angle_t slope = FixedMul(pitch, pitchMul) + FixedMul(roll, rollMul); + + if (slope > ANGLE_180) + { + slope = InvAngle(slope); + } + + return slope; } -#define STEEP_VAL (ANGLE_45) +#define STEEP_VAL (FixedAngle(40*FRACUNIT)) void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll) { fixed_t gravityadjust; angle_t oldSlope, newSlope; angle_t slopeDelta; - angle_t oldSteepness; // If you don't land upright on a slope, then you tumble, // kinda like Kirby Air Ride @@ -3435,13 +3441,7 @@ void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll) oldSlope = K_TumbleSlope(player->mo, oldPitch, oldRoll); - oldSteepness = oldSlope; - if (oldSteepness > ANGLE_180) - { - oldSteepness = InvAngle(oldSteepness); - } - - if (oldSteepness <= STEEP_VAL) + if (oldSlope <= STEEP_VAL) { // Transferring from flat ground to a steep slope // is a free action. (The other way around isn't, though.) diff --git a/src/p_mobj.c b/src/p_mobj.c index ad79f6353..428880478 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2811,9 +2811,10 @@ void P_PlayerZMovement(mobj_t *mo) // Even out pitch & roll slowly over time when falling. // Helps give OpenGL models a bit of the tumble tell. + if (P_MobjFlip(mo) * mo->momz <= 0) { - const angle_t speed = ANG1; - angle_t dest = ANGLE_45 + (ANG10 >> 1); + const angle_t speed = ANG2; + angle_t dest = FixedAngle(50*FRACUNIT); INT32 pitchDelta = AngleDeltaSigned(mo->pitch, 0); INT32 rollDelta = AngleDeltaSigned(mo->roll, 0); From 794090d026c8167dbf405aca17856f6d0b994ec9 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 2 Apr 2022 01:20:23 -0400 Subject: [PATCH 06/26] Make more lenient on the ground --- src/k_kart.c | 35 ++++++++++++++++++++++++++++------- src/k_kart.h | 2 +- src/p_map.c | 6 +++--- src/p_mobj.c | 38 ++++++++++++++++++++++++++++---------- src/p_user.c | 21 +++++++++++++++------ 5 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index f019eef50..26c7c4811 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3422,10 +3422,13 @@ static angle_t K_TumbleSlope(mobj_t *mobj, angle_t pitch, angle_t roll) return slope; } -#define STEEP_VAL (FixedAngle(40*FRACUNIT)) -void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll) +#define STEEP_VAL ANG60 +#define STEEP_VAL_AIR ANG30 + ANG10 + +boolean K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll, boolean fromAir) { + angle_t steepVal = ANGLE_MAX; fixed_t gravityadjust; angle_t oldSlope, newSlope; angle_t slopeDelta; @@ -3436,25 +3439,41 @@ void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll) if (player->tumbleBounces) { // Already tumbling. - return; + return false; + } + + if ((player->mo->pitch == oldPitch) + && (player->mo->roll == oldRoll)) + { + // No change. + return false; + } + + if (fromAir == true) + { + steepVal = STEEP_VAL_AIR; + } + else + { + steepVal = STEEP_VAL; } oldSlope = K_TumbleSlope(player->mo, oldPitch, oldRoll); - if (oldSlope <= STEEP_VAL) + if (oldSlope <= steepVal) { // Transferring from flat ground to a steep slope // is a free action. (The other way around isn't, though.) - return; + return false; } newSlope = K_TumbleSlope(player->mo, player->mo->pitch, player->mo->roll); slopeDelta = AngleDelta(oldSlope, newSlope); - if (slopeDelta <= STEEP_VAL) + if (slopeDelta <= steepVal) { // Needs to be VERY steep before we'll punish this. - return; + return false; } // Oh jeez, you landed on your side. @@ -3488,6 +3507,7 @@ void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll) // Reset slope. player->mo->pitch = player->mo->roll = 0; + return true; } static boolean K_LastTumbleBounceCondition(player_t *player) @@ -3525,6 +3545,7 @@ static void K_HandleTumbleBounce(player_t *player) player->tumbleHeight = 10; player->pflags |= PF_TUMBLELASTBOUNCE; player->mo->rollangle = 0; // p_user.c will stop rotating the player automatically + player->mo->pitch = player->mo->roll = 0; // Prevent Kodachrome Void infinite } } diff --git a/src/k_kart.h b/src/k_kart.h index 605e0f410..8881729ad 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -70,7 +70,7 @@ void K_DoInstashield(player_t *player); void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); -void K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll); +boolean K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll, boolean fromAir); INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_DebtStingPlayer(player_t *player, mobj_t *source); void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers); diff --git a/src/p_map.c b/src/p_map.c index 996d1c2db..67f15102e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2480,7 +2480,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) fixed_t oldy = tryy; fixed_t radius = thing->radius; fixed_t thingtop; - fixed_t startingonground = P_IsObjectOnGround(thing); + boolean startingonground = P_IsObjectOnGround(thing); fixed_t stairjank = 0; pslope_t *oldslope = thing->standingslope; floatok = false; @@ -2673,7 +2673,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->standingslope = tmfloorslope; P_SetPitchRollFromSlope(thing, thing->standingslope); - if (thing->momz == 0 && thing->player) + if (thing->player) { P_PlayerHitFloor(thing->player, !startingonground, oldPitch, oldRoll); } @@ -2696,7 +2696,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->standingslope = tmceilingslope; P_SetPitchRollFromSlope(thing, thing->standingslope); - if (thing->momz == 0 && thing->player) + if (thing->player) { P_PlayerHitFloor(thing->player, !startingonground, oldPitch, oldRoll); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 428880478..42652afdc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1514,12 +1514,18 @@ void P_XYMovement(mobj_t *mo) } // adjust various things based on slope - if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) { - if (!P_IsObjectOnGround(mo)) { // We fell off at some point? Do the twisty thing! + if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) + { + if (!P_IsObjectOnGround(mo)) + { + // We fell off at some point? Do the twisty thing! P_SlopeLaunch(mo); xmove = mo->momx; ymove = mo->momy; - } else { // Still on the ground. + } + else + { + // Still on the ground. slopemom.x = xmove; slopemom.y = ymove; slopemom.z = 0; @@ -1748,9 +1754,13 @@ void P_XYMovement(mobj_t *mo) if (P_MobjWasRemoved(mo)) // MF_SPECIAL touched a player! O_o;; return; - if (moved && oldslope && !(mo->flags & MF_NOCLIPHEIGHT)) { // Check to see if we ran off + if (moved && oldslope && !(mo->flags & MF_NOCLIPHEIGHT)) + { + // Check to see if we ran off - if (oldslope != mo->standingslope) { // First, compare different slopes + if (oldslope != mo->standingslope) + { + // First, compare different slopes angle_t oldangle, newangle; angle_t moveangle = K_MomentumAngle(mo); @@ -1762,7 +1772,9 @@ void P_XYMovement(mobj_t *mo) newangle = 0; // Now compare the Zs of the different quantizations - if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later + if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) + { + // Allow for a bit of sticking - this value can be adjusted later mo->standingslope = oldslope; P_SetPitchRollFromSlope(mo, mo->standingslope); P_SlopeLaunch(mo); @@ -1776,12 +1788,17 @@ void P_XYMovement(mobj_t *mo) FIXED_TO_FLOAT(AngleFixed(oldangle-newangle)) );*/ // Sryder 2018-11-26: Don't launch here if it's a slope without physics, we stick to those like glue anyway - } else if (predictedz-mo->z > abs(slopemom.z/2) - && !(mo->standingslope->flags & SL_NOPHYSICS)) { // Now check if we were supposed to stick to this slope + } + else if (predictedz-mo->z > abs(slopemom.z/2) + && !(mo->standingslope->flags & SL_NOPHYSICS)) + { + // 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); } - } else if (moved && mo->standingslope && predictedz) { + } + else if (moved && mo->standingslope && predictedz) + { angle_t moveangle = K_MomentumAngle(mo); angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); @@ -1789,7 +1806,8 @@ void P_XYMovement(mobj_t *mo) FIXED_TO_FLOAT(AngleFixed(ANGLE_MAX-newangle)), FIXED_TO_FLOAT(predictedz) );*/ - if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180) { + if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180) + { mo->momz = P_MobjFlip(mo)*FRACUNIT/2; mo->z = predictedz + P_MobjFlip(mo); mo->standingslope = NULL; diff --git a/src/p_user.c b/src/p_user.c index af0aff8b1..9eba0531e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1324,14 +1324,23 @@ boolean P_PlayerHitFloor(player_t *player, boolean fromAir, angle_t oldPitch, an clipmomz = !(P_CheckDeathPitCollide(player->mo)); - if (fromAir == true && clipmomz == true) + if (clipmomz == true) { - K_SpawnSplashForMobj(player->mo, abs(player->mo->momz)); - } + if (fromAir == true) + { + K_SpawnSplashForMobj(player->mo, abs(player->mo->momz)); + } - if (player->mo->health) - { - K_CheckSlopeTumble(player, oldPitch, oldRoll); + if (player->mo->health) + { + boolean air = fromAir; + + if (P_IsObjectOnGround(player->mo) && (player->mo->eflags & MFE_JUSTHITFLOOR)) + air = true; + + if (K_CheckSlopeTumble(player, oldPitch, oldRoll, air)) + return false; + } } return clipmomz; From d6efbc143b8b429552a96b2e35045d6fc1073650 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 2 Apr 2022 01:40:40 -0400 Subject: [PATCH 07/26] Some code I didn't end up using but want here anyway --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 42652afdc..6820d7948 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2831,8 +2831,8 @@ void P_PlayerZMovement(mobj_t *mo) // Helps give OpenGL models a bit of the tumble tell. if (P_MobjFlip(mo) * mo->momz <= 0) { - const angle_t speed = ANG2; - angle_t dest = FixedAngle(50*FRACUNIT); + const angle_t speed = ANG2; //FixedMul(ANG2, abs(mo->momz) / 8); + angle_t dest = ANG60 - ANG10; INT32 pitchDelta = AngleDeltaSigned(mo->pitch, 0); INT32 rollDelta = AngleDeltaSigned(mo->roll, 0); From bb510a6a6708399c6ff7de7817399677dab07f4d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 2 Apr 2022 02:01:39 -0400 Subject: [PATCH 08/26] Rename to "stumble" :D --- src/k_kart.c | 16 ++++++---------- src/k_kart.h | 6 +++++- src/p_user.c | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 26c7c4811..d4d9ebcd7 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3407,7 +3407,7 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) P_StartQuake(64<angle >> ANGLETOFINESHIFT); fixed_t rollMul = FINECOSINE(mobj->angle >> ANGLETOFINESHIFT); @@ -3422,11 +3422,7 @@ static angle_t K_TumbleSlope(mobj_t *mobj, angle_t pitch, angle_t roll) return slope; } - -#define STEEP_VAL ANG60 -#define STEEP_VAL_AIR ANG30 + ANG10 - -boolean K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll, boolean fromAir) +boolean K_CheckStumble(player_t *player, angle_t oldPitch, angle_t oldRoll, boolean fromAir) { angle_t steepVal = ANGLE_MAX; fixed_t gravityadjust; @@ -3451,14 +3447,14 @@ boolean K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll, if (fromAir == true) { - steepVal = STEEP_VAL_AIR; + steepVal = STUMBLE_STEEP_VAL_AIR; } else { - steepVal = STEEP_VAL; + steepVal = STUMBLE_STEEP_VAL; } - oldSlope = K_TumbleSlope(player->mo, oldPitch, oldRoll); + oldSlope = K_StumbleSlope(player->mo, oldPitch, oldRoll); if (oldSlope <= steepVal) { @@ -3467,7 +3463,7 @@ boolean K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll, return false; } - newSlope = K_TumbleSlope(player->mo, player->mo->pitch, player->mo->roll); + newSlope = K_StumbleSlope(player->mo, player->mo->pitch, player->mo->roll); slopeDelta = AngleDelta(oldSlope, newSlope); if (slopeDelta <= steepVal) diff --git a/src/k_kart.h b/src/k_kart.h index 8881729ad..796392d85 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -28,6 +28,9 @@ Make sure this matches the actual number of states #define GROW_PHYSICS_SCALE (3*FRACUNIT/2) #define SHRINK_PHYSICS_SCALE (3*FRACUNIT/4) +#define STUMBLE_STEEP_VAL ANG60 +#define STUMBLE_STEEP_VAL_AIR (ANG30 + ANG10) + player_t *K_GetItemBoxPlayer(mobj_t *mobj); angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed); @@ -70,7 +73,8 @@ void K_DoInstashield(player_t *player); void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); -boolean K_CheckSlopeTumble(player_t *player, angle_t oldPitch, angle_t oldRoll, boolean fromAir); +angle_t K_StumbleSlope(mobj_t *mobj, angle_t pitch, angle_t roll); +boolean K_CheckStumble(player_t *player, angle_t oldPitch, angle_t oldRoll, boolean fromAir); INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_DebtStingPlayer(player_t *player, mobj_t *source); void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers); diff --git a/src/p_user.c b/src/p_user.c index 9eba0531e..7e6e1b1f9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1338,7 +1338,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean fromAir, angle_t oldPitch, an if (P_IsObjectOnGround(player->mo) && (player->mo->eflags & MFE_JUSTHITFLOOR)) air = true; - if (K_CheckSlopeTumble(player, oldPitch, oldRoll, air)) + if (K_CheckStumble(player, oldPitch, oldRoll, air)) return false; } } From 5ece4825c0949ce6c12373ffec01f17a3951cfb4 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 2 Apr 2022 02:25:25 -0400 Subject: [PATCH 09/26] Smooth landing support for bots --- src/k_bot.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/k_bot.c b/src/k_bot.c index b3f73b8ac..5d512f54c 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -1062,6 +1062,55 @@ static void K_BotTrick(player_t *player, ticcmd_t *cmd, line_t *botController) } } +/*-------------------------------------------------- + static angle_t K_BotSmoothLanding(player_t *player, angle_t destangle) + + Calculates a new destination angle while in the air, + to be able to successfully smooth land. + + Input Arguments:- + player - Bot player to check. + destangle - Previous destination angle. + + Return:- + New destination angle. +--------------------------------------------------*/ +static angle_t K_BotSmoothLanding(player_t *player, angle_t destangle) +{ + angle_t newAngle = destangle; + boolean air = !P_IsObjectOnGround(player->mo); + angle_t steepVal = air ? STUMBLE_STEEP_VAL_AIR : STUMBLE_STEEP_VAL; + angle_t slopeSteep = max(AngleDelta(player->mo->pitch, 0), AngleDelta(player->mo->roll, 0)); + + if (slopeSteep > steepVal) + { + fixed_t pitchMul = -FINESINE(destangle >> ANGLETOFINESHIFT); + fixed_t rollMul = FINECOSINE(destangle >> ANGLETOFINESHIFT); + angle_t testAngles[2]; + angle_t testDeltas[2]; + UINT8 i; + + testAngles[0] = R_PointToAngle2(0, 0, rollMul, pitchMul); + testAngles[1] = R_PointToAngle2(0, 0, -rollMul, -pitchMul); + + for (i = 0; i < 2; i++) + { + testDeltas[i] = AngleDelta(testAngles[i], destangle); + } + + if (testDeltas[1] < testDeltas[0]) + { + return testAngles[1]; + } + else + { + return testAngles[0]; + } + } + + return newAngle; +} + /*-------------------------------------------------- static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *predict) @@ -1085,6 +1134,8 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * I_Assert(predict != NULL); + destangle = K_BotSmoothLanding(player, destangle); + moveangle = player->mo->angle; angle = (moveangle - destangle); @@ -1227,6 +1278,8 @@ static INT32 K_HandleBotReverse(player_t *player, ticcmd_t *cmd, botprediction_t } } + destangle = K_BotSmoothLanding(player, destangle); + // Calculate turn direction first. moveangle = player->mo->angle; angle = (moveangle - destangle); From cf15c485c8e47b1990b3f57eb4a1d1b36bca781c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 2 Apr 2022 14:43:38 -0400 Subject: [PATCH 10/26] review --- src/k_bot.c | 25 +++++++------ src/k_grandprix.c | 94 +++++++++++++++++++++++++++++------------------ src/k_grandprix.h | 14 ++----- src/y_inter.c | 13 ++----- 4 files changed, 78 insertions(+), 68 deletions(-) diff --git a/src/k_bot.c b/src/k_bot.c index 5d512f54c..c8c2a232b 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -487,7 +487,7 @@ static UINT32 K_BotRubberbandDistance(player_t *player) fixed_t K_BotRubberband(player_t *player) { fixed_t rubberband = FRACUNIT; - fixed_t max, min; + fixed_t rubbermax, rubbermin; player_t *firstplace = NULL; line_t *botController = NULL; UINT8 i; @@ -551,21 +551,21 @@ fixed_t K_BotRubberband(player_t *player) // Lv. 5: x1.4 max // Lv. 9: x1.8 max // Lv. MAX: x2.2 max - max = FRACUNIT + ((FRACUNIT * (player->botvars.difficulty - 1)) / 10); + rubbermax = FRACUNIT + ((FRACUNIT * (player->botvars.difficulty - 1)) / 10); // Lv. 1: x0.75 min // Lv. 5: x0.875 min // Lv. 9: x1.0 min // Lv. MAX: x1.0 min - min = FRACUNIT - (((FRACUNIT/4) * (DIFFICULTBOT - min(DIFFICULTBOT, player->botvars.difficulty))) / (DIFFICULTBOT - 1)); + rubbermin = FRACUNIT - (((FRACUNIT/4) * (DIFFICULTBOT - min(DIFFICULTBOT, player->botvars.difficulty))) / (DIFFICULTBOT - 1)); - if (rubberband > max) + if (rubberband > rubbermax) { - rubberband = max; + rubberband = rubbermax; } - else if (rubberband < min) + else if (rubberband < rubbermin) { - rubberband = min; + rubberband = rubbermin; } return rubberband; @@ -1170,6 +1170,11 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t * predict->x, predict->y ); + if (realrad < player->mo->radius) + { + realrad = player->mo->radius; + } + if (anglediff > 0) { // Become more precise based on how hard you need to turn @@ -1500,11 +1505,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) turnamt = bullyTurn; // If already spindashing, wait until we get a relatively OK charge first. - if (player->spindash > 0 && player->spindash <= TICRATE) - { - trySpindash = true; - } - else + if (player->spindash == 0 || player->spindash > TICRATE) { trySpindash = false; cmd->buttons |= BT_ACCELERATE; diff --git a/src/k_grandprix.c b/src/k_grandprix.c index 332224479..bb14edac6 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -513,18 +513,16 @@ void K_IncreaseBotDifficulty(player_t *bot) } /*-------------------------------------------------- - void K_ReplaceBot(player_t *bot) + void K_RetireBots(void) See header file for description. --------------------------------------------------*/ -void K_ReplaceBot(player_t *bot) +void K_RetireBots(void) { const SINT8 defaultbotskin = K_BotDefaultSkin(); SINT8 newDifficulty; boolean skinusable[MAXSKINS]; - UINT8 skinnum; - UINT8 loops = 0; UINT8 i; @@ -555,32 +553,6 @@ void K_ReplaceBot(player_t *bot) } } - skinnum = P_RandomKey(numskins); - - while (!skinusable[skinnum]) - { - if (loops >= numskins) - { - // no more skins - break; - } - - skinnum++; - - if (skinnum >= numskins) - { - skinnum = 0; - } - - loops++; - } - - if (loops >= numskins) - { - // Use default skin - skinnum = defaultbotskin; - } - if (!grandprixinfo.gp) // Sure, let's let this happen all the time :) { newDifficulty = cv_kartbot.value; @@ -600,14 +572,64 @@ void K_ReplaceBot(player_t *bot) newDifficulty = 1; } - bot->botvars.difficulty = newDifficulty; - bot->botvars.diffincrease = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + player_t *bot = NULL; - SetPlayerSkinByNum(bot - players, skinnum); - bot->skincolor = skins[skinnum].prefcolor; - sprintf(player_names[bot - players], "%s", skins[skinnum].realname); + if (!playeringame[i] || !players[i].bot) + { + continue; + } - bot->score = 0; + bot = players[i]; + + if (bot->spectator) + { + continue; + } + + if (bot->pflags & PF_NOCONTEST) + { + UINT8 skinnum = P_RandomKey(numskins); + UINT8 loops = 0; + + while (!skinusable[skinnum]) + { + if (loops >= numskins) + { + // no more skins + break; + } + + skinnum++; + + if (skinnum >= numskins) + { + skinnum = 0; + } + + loops++; + } + + if (loops >= numskins) + { + // Use default skin + skinnum = defaultbotskin; + } + + skinusable[skinnum] = false; + + bot->botvars.difficulty = newDifficulty; + bot->botvars.diffincrease = 0; + + SetPlayerSkinByNum(bot - players, skinnum); + bot->skincolor = skins[skinnum].prefcolor; + sprintf(player_names[bot - players], "%s", skins[skinnum].realname); + + bot->score = 0; + bot->pflags &= ~PF_NOCONTEST; + } + } } /*-------------------------------------------------- diff --git a/src/k_grandprix.h b/src/k_grandprix.h index f951860d8..552f75450 100644 --- a/src/k_grandprix.h +++ b/src/k_grandprix.h @@ -106,19 +106,13 @@ void K_IncreaseBotDifficulty(player_t *bot); /*-------------------------------------------------- - void K_ReplaceBot(player_t *bot); + void K_RetireBots(player_t *bot); - "Replaces" a bot, by refreshing their difficulty + Replaces PF_NOCONTEST bots, by refreshing their difficulty and changing their skin. - - Input Arguments:- - bot - Player to do this for. - - Return:- - None --------------------------------------------------*/ -void K_ReplaceBot(player_t *bot); +void K_RetireBots(player_t *bot); /*-------------------------------------------------- @@ -162,7 +156,7 @@ void K_PlayerLoseLife(player_t *player); None Return:- - None + true if can change important gameplay rules, otherwise false. --------------------------------------------------*/ boolean K_CanChangeRules(void); diff --git a/src/y_inter.c b/src/y_inter.c index 69cbf2660..7f48f0798 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -584,7 +584,7 @@ void Y_IntermissionDrawer(void) V_DrawScaledPatch(x+16, y-4, 0, W_CachePatchName(va("K_CHILI%d", cursorframe+1), PU_CACHE)); } - if (!data.rankingsmode && (players[data.num[i]].pflags & PF_NOCONTEST) && players[data.num[i]].bot) + if ((players[data.num[i]].pflags & PF_NOCONTEST) && players[data.num[i]].bot) { // RETIRED!! V_DrawScaledPatch(x+12, y-7, 0, W_CachePatchName("K_NOBLNS", PU_CACHE)); @@ -811,15 +811,7 @@ void Y_Ticker(void) { if (!data.rankingsmode && sorttic != -1 && (intertic >= sorttic + 8)) { - UINT8 i; - for (i = 0; i < MAXPLAYERS; i++) - { - if ((players[i].pflags & PF_NOCONTEST) && players[i].bot) - { - K_ReplaceBot(&players[i]); - } - } - + K_RetireBots(); Y_CalculateMatchData(1, Y_CompareRank); } @@ -1170,6 +1162,7 @@ void Y_StartIntermission(void) // void Y_EndIntermission(void) { + K_RetireBots(); Y_UnloadData(); endtic = -1; From 33c79ea746a43206bc2419a9b86de6b946fa58f1 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 2 Apr 2022 14:54:23 -0400 Subject: [PATCH 11/26] Bad function declaration --- src/k_grandprix.c | 2 +- src/k_grandprix.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/k_grandprix.c b/src/k_grandprix.c index bb14edac6..740730c6f 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -581,7 +581,7 @@ void K_RetireBots(void) continue; } - bot = players[i]; + bot = &players[i]; if (bot->spectator) { diff --git a/src/k_grandprix.h b/src/k_grandprix.h index 552f75450..bd20d3894 100644 --- a/src/k_grandprix.h +++ b/src/k_grandprix.h @@ -106,13 +106,13 @@ void K_IncreaseBotDifficulty(player_t *bot); /*-------------------------------------------------- - void K_RetireBots(player_t *bot); + void K_RetireBots(void); Replaces PF_NOCONTEST bots, by refreshing their difficulty and changing their skin. --------------------------------------------------*/ -void K_RetireBots(player_t *bot); +void K_RetireBots(void); /*-------------------------------------------------- From db25599647496d6e79c4b761719ffc6c7f3ec70e Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Tue, 20 Sep 2022 02:34:53 -0700 Subject: [PATCH 12/26] Offline input delay cvar --- src/d_clisrv.c | 4 +++- src/d_clisrv.h | 1 + src/d_netcmd.c | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index ebd58844e..aa4199fce 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -114,6 +114,8 @@ UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. static tic_t lowest_lag; boolean server_lagless; +static CV_PossibleValue_t mindelay_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}}; +consvar_t cv_mindelay = CVAR_INIT ("mindelay", "0", 0, mindelay_cons_t, NULL); SINT8 nodetoplayer[MAXNETNODES]; SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) @@ -5665,7 +5667,7 @@ static void UpdatePingTable(void) if (netgame && !(gametime % 35)) // update once per second. PingUpdate(); - fastest = 0; + fastest = cv_mindelay.value; // update node latency values so we can take an average later. for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 72ce18a5c..ca36ba26c 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -445,6 +445,7 @@ extern UINT32 playerpingtable[MAXPLAYERS]; extern tic_t servermaxping; extern boolean server_lagless; +extern consvar_t cv_mindelay; extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_maxconnections, cv_joindelay; extern consvar_t cv_resynchattempts, cv_blamecfail; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 9dcc990a9..c0057896a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -972,6 +972,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_rollingdemos); CV_RegisterVar(&cv_netstat); CV_RegisterVar(&cv_netticbuffer); + CV_RegisterVar(&cv_mindelay); #ifdef NETGAME_DEVMODE CV_RegisterVar(&cv_fishcake); From f987d1b601b5f6e225c8d6f1190426e16f6c8e7c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 20 Sep 2022 10:33:24 -0400 Subject: [PATCH 13/26] Add smooth landing vfx --- src/d_player.h | 2 + src/deh_tables.c | 4 ++ src/info.c | 30 ++++++++++ src/info.h | 5 ++ src/k_bot.c | 2 +- src/k_kart.c | 140 +++++++++++++++++++++++++++++++++++++++++++++-- src/k_kart.h | 4 +- src/p_mobj.c | 14 ++--- src/p_saveg.c | 17 ++++++ 9 files changed, 202 insertions(+), 16 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 7d0f20058..ad7b75b86 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -590,6 +590,8 @@ typedef struct player_s UINT8 shrinkLaserDelay; + mobj_t *stumbleIndicator; + #ifdef HWRENDER fixed_t fovadd; // adjust FOV for hw rendering #endif diff --git a/src/deh_tables.c b/src/deh_tables.c index 7bb649d2b..9b8774f4c 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3832,6 +3832,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_TRIPWIREBOOST_BLAST_TOP", "S_TRIPWIREBOOST_BLAST_BOTTOM", + "S_SMOOTHLANDING", + // DEZ respawn laser "S_DEZLASER", "S_DEZLASER_TRAIL1", @@ -5376,6 +5378,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_TRIPWIREBOOST", + "MT_SMOOTHLANDING", + "MT_DEZLASER", "MT_WAYPOINT", diff --git a/src/info.c b/src/info.c index e80098499..110c1e906 100644 --- a/src/info.c +++ b/src/info.c @@ -587,6 +587,7 @@ char sprnames[NUMSPRITES + 1][5] = "BEXB", // Battle Bumper Explosion: Blast "TWBS", // Tripwire Boost "TWBT", // Tripwire BLASTER + "SMLD", // Smooth landing "DEZL", // DEZ Laser respawn // Additional Kart Objects @@ -4392,6 +4393,8 @@ state_t states[NUMSTATES] = {SPR_TWBT, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE, -1, {NULL}, 6, 2, S_NULL}, // S_TRIPWIREBOOST_BLAST_TOP {SPR_TWBT, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE|FF_VERTICALFLIP|FF_HORIZONTALFLIP, -1, {NULL}, 6, 2, S_NULL}, // S_TRIPWIREBOOST_BLAST_BOTTOM + {SPR_SMLD, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE, -1, {NULL}, 7, 2, S_NULL}, // S_SMOOTHLANDING + {SPR_DEZL, FF_FULLBRIGHT|FF_PAPERSPRITE, 8, {NULL}, 0, 0, S_NULL}, // S_DEZLASER {SPR_DEZL, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL2}, // S_DEZLASER_TRAIL1 {SPR_DEZL, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_DEZLASER_TRAIL3}, // S_DEZLASER_TRAIL2 @@ -24411,6 +24414,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SMOOTHLANDING + -1, // doomednum + S_SMOOTHLANDING, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + -1, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_DEZLASER -1, // doomednum S_DEZLASER, // spawnstate diff --git a/src/info.h b/src/info.h index 8305e1400..0d07f2775 100644 --- a/src/info.h +++ b/src/info.h @@ -1133,6 +1133,7 @@ typedef enum sprite SPR_BEXB, // Battle Bumper Explosion: Blast SPR_TWBS, // Tripwire Boost SPR_TWBT, // Tripwire BLASTER + SPR_SMLD, // Smooth landing SPR_DEZL, // DEZ Laser respawn // Additional Kart Objects @@ -4826,6 +4827,8 @@ typedef enum state S_TRIPWIREBOOST_BLAST_TOP, S_TRIPWIREBOOST_BLAST_BOTTOM, + S_SMOOTHLANDING, + // DEZ Laser respawn S_DEZLASER, S_DEZLASER_TRAIL1, @@ -6407,6 +6410,8 @@ typedef enum mobj_type MT_TRIPWIREBOOST, + MT_SMOOTHLANDING, + MT_DEZLASER, MT_WAYPOINT, diff --git a/src/k_bot.c b/src/k_bot.c index f77cbe882..1b5a183b0 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -987,7 +987,7 @@ static angle_t K_BotSmoothLanding(player_t *player, angle_t destangle) { testDeltas[i] = AngleDelta(testAngles[i], destangle); } -' + if (testDeltas[1] < testDeltas[0]) { return testAngles[1]; diff --git a/src/k_kart.c b/src/k_kart.c index bad2c1da0..9d888cfbd 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3797,10 +3797,10 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) P_StartQuake(64<angle >> ANGLETOFINESHIFT); - fixed_t rollMul = FINECOSINE(mobj->angle >> ANGLETOFINESHIFT); + fixed_t pitchMul = -FINESINE(angle >> ANGLETOFINESHIFT); + fixed_t rollMul = FINECOSINE(angle >> ANGLETOFINESHIFT); angle_t slope = FixedMul(pitch, pitchMul) + FixedMul(roll, rollMul); @@ -3844,7 +3844,7 @@ boolean K_CheckStumble(player_t *player, angle_t oldPitch, angle_t oldRoll, bool steepVal = STUMBLE_STEEP_VAL; } - oldSlope = K_StumbleSlope(player->mo, oldPitch, oldRoll); + oldSlope = K_StumbleSlope(player->mo->angle, oldPitch, oldRoll); if (oldSlope <= steepVal) { @@ -3853,7 +3853,7 @@ boolean K_CheckStumble(player_t *player, angle_t oldPitch, angle_t oldRoll, bool return false; } - newSlope = K_StumbleSlope(player->mo, player->mo->pitch, player->mo->roll); + newSlope = K_StumbleSlope(player->mo->angle, player->mo->pitch, player->mo->roll); slopeDelta = AngleDelta(oldSlope, newSlope); if (slopeDelta <= steepVal) @@ -3896,6 +3896,134 @@ boolean K_CheckStumble(player_t *player, angle_t oldPitch, angle_t oldRoll, bool return true; } +void K_InitStumbleIndicator(player_t *player) +{ + mobj_t *new = NULL; + + if (player == NULL) + { + return; + } + + if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true) + { + return; + } + + if (player->stumbleIndicator != NULL && P_MobjWasRemoved(player->stumbleIndicator) == false) + { + P_RemoveMobj(player->stumbleIndicator); + } + + new = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SMOOTHLANDING); + + P_SetTarget(&player->stumbleIndicator, new); + P_SetTarget(&new->target, player->mo); +} + +void K_UpdateStumbleIndicator(player_t *player) +{ + mobj_t *mobj = NULL; + + boolean air = false; + angle_t steepVal = STUMBLE_STEEP_VAL; + angle_t slopeSteep = 0; + angle_t steepRange = ANGLE_90; + + INT32 delta = 0; + INT32 trans = 0; + + if (player == NULL) + { + return; + } + + if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true) + { + return; + } + + if (player->stumbleIndicator == NULL || P_MobjWasRemoved(player->stumbleIndicator) == true) + { + K_InitStumbleIndicator(player); + return; + } + + mobj = player->stumbleIndicator; + + P_MoveOrigin(mobj, player->mo->x, player->mo->y, player->mo->z + (player->mo->height / 2)); + + air = !P_IsObjectOnGround(player->mo); + steepVal = air ? STUMBLE_STEEP_VAL_AIR : STUMBLE_STEEP_VAL; + slopeSteep = max(AngleDelta(player->mo->pitch, 0), AngleDelta(player->mo->roll, 0)); + + delta = 0; + + if (slopeSteep > steepVal) + { + angle_t testAngles[2]; + INT32 testDeltas[2]; + UINT8 i; + + testAngles[0] = R_PointToAngle2(0, 0, player->mo->pitch, player->mo->roll); + testAngles[1] = R_PointToAngle2(0, 0, -player->mo->pitch, -player->mo->roll); + + for (i = 0; i < 2; i++) + { + testDeltas[i] = AngleDeltaSigned(player->mo->angle, testAngles[i]); + } + + if (abs(testDeltas[1]) < abs(testDeltas[0])) + { + delta = testDeltas[1]; + } + else + { + delta = testDeltas[0]; + } + } + + if (delta < 0) + { + mobj->renderflags |= RF_HORIZONTALFLIP; + } + else + { + mobj->renderflags &= ~RF_HORIZONTALFLIP; + } + + steepRange = ANGLE_90 - steepVal; + delta = max(0, abs(delta) - ((signed)steepVal)); + trans = ((FixedDiv(AngleFixed(delta), AngleFixed(steepRange)) * (NUMTRANSMAPS+1)) + (FRACUNIT/2)) / FRACUNIT; + + if (trans < 0) + { + trans = 0; + } + + if (trans > NUMTRANSMAPS) + { + trans = NUMTRANSMAPS; + } + + // invert + trans = NUMTRANSMAPS - trans; + + if (trans >= NUMTRANSMAPS) + { + mobj->renderflags |= RF_DONTDRAW; + } + else + { + mobj->renderflags &= ~(RF_TRANSMASK|RF_DONTDRAW); + + if (trans != 0) + { + mobj->renderflags |= (trans << RF_TRANSSHIFT); + } + } +} + static boolean K_LastTumbleBounceCondition(player_t *player) { return (player->tumbleBounces > TUMBLEBOUNCES && player->tumbleHeight < 60); @@ -7999,6 +8127,8 @@ void K_KartPlayerAfterThink(player_t *player) { K_KartResetPlayerColor(player); + K_UpdateStumbleIndicator(player); + // Move held objects (Bananas, Orbinaut, etc) K_MoveHeldObjects(player); diff --git a/src/k_kart.h b/src/k_kart.h index 9d91ef240..b44258a9a 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -78,8 +78,10 @@ void K_RemoveGrowShrink(player_t *player); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_TumbleInterrupt(player_t *player); -angle_t K_StumbleSlope(mobj_t *mobj, angle_t pitch, angle_t roll); +angle_t K_StumbleSlope(angle_t angle, angle_t pitch, angle_t roll); boolean K_CheckStumble(player_t *player, angle_t oldPitch, angle_t oldRoll, boolean fromAir); +void K_InitStumbleIndicator(player_t *player); +void K_UpdateStumbleIndicator(player_t *player); INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_DebtStingPlayer(player_t *player, mobj_t *source); void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers); diff --git a/src/p_mobj.c b/src/p_mobj.c index c71238928..3f0521b12 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2847,20 +2847,14 @@ void P_PlayerZMovement(mobj_t *mo) P_CheckGravity(mo, true); } - // Even out pitch & roll slowly over time when falling. - // Helps give OpenGL models a bit of the tumble tell. - if (P_MobjFlip(mo) * mo->momz <= 0) + // Even out pitch & roll slowly over time when respawning. + if (mo->player->respawn.state != RESPAWNST_NONE) { const angle_t speed = ANG2; //FixedMul(ANG2, abs(mo->momz) / 8); - angle_t dest = ANG60 - ANG10; + angle_t dest = 0; INT32 pitchDelta = AngleDeltaSigned(mo->pitch, 0); INT32 rollDelta = AngleDeltaSigned(mo->roll, 0); - if (mo->player->respawn.state != RESPAWNST_NONE) - { - dest = 0; - } - if (abs(pitchDelta) <= speed && dest == 0) { mo->pitch = 0; @@ -11389,6 +11383,8 @@ void P_SpawnPlayer(INT32 playernum) P_SetScale(mobj, mobj->destscale); P_FlashPal(p, 0, 0); // Resets + K_InitStumbleIndicator(p); + if (gametyperules & GTR_BUMPERS) { mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height + 16*FRACUNIT, MT_PLAYERARROW); diff --git a/src/p_saveg.c b/src/p_saveg.c index da85dac77..f1e51d3fb 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -64,6 +64,7 @@ typedef enum SKYBOXVIEW = 0x08, SKYBOXCENTER = 0x10, HOVERHYUDORO = 0x20, + STUMBLE = 0x40, } player_saveflags; static inline void P_ArchivePlayer(void) @@ -202,6 +203,9 @@ static void P_NetArchivePlayers(void) if (players[i].hoverhyudoro) flags |= HOVERHYUDORO; + if (players[i].stumbleIndicator) + flags |= STUMBLE; + WRITEUINT16(save_p, flags); if (flags & SKYBOXVIEW) @@ -219,6 +223,9 @@ static void P_NetArchivePlayers(void) if (flags & HOVERHYUDORO) WRITEUINT32(save_p, players[i].hoverhyudoro->mobjnum); + if (flags & STUMBLE) + WRITEUINT32(save_p, players[i].stumbleIndicator->mobjnum); + WRITEUINT32(save_p, (UINT32)players[i].followitem); WRITEUINT32(save_p, players[i].charflags); @@ -509,6 +516,9 @@ static void P_NetUnArchivePlayers(void) if (flags & HOVERHYUDORO) players[i].hoverhyudoro = (mobj_t *)(size_t)READUINT32(save_p); + if (flags & STUMBLE) + players[i].stumbleIndicator = (mobj_t *)(size_t)READUINT32(save_p); + players[i].followitem = (mobjtype_t)READUINT32(save_p); //SetPlayerSkinByNum(i, players[i].skin); @@ -4289,6 +4299,13 @@ static void P_RelinkPointers(void) if (!P_SetTarget(&mobj->player->hoverhyudoro, P_FindNewPosition(temp))) CONS_Debug(DBG_GAMELOGIC, "hoverhyudoro not found on %d\n", mobj->type); } + if (mobj->player->stumbleIndicator) + { + temp = (UINT32)(size_t)mobj->player->stumbleIndicator; + mobj->player->stumbleIndicator = NULL; + if (!P_SetTarget(&mobj->player->stumbleIndicator, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "stumbleIndicator not found on %d\n", mobj->type); + } } } } From 12475dc4340f86fa997da1b102feb012cdb74902 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 20 Sep 2022 10:35:13 -0400 Subject: [PATCH 14/26] Make smoothland client-sided --- src/k_kart.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 9d888cfbd..8b0f472a9 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4009,13 +4009,11 @@ void K_UpdateStumbleIndicator(player_t *player) // invert trans = NUMTRANSMAPS - trans; - if (trans >= NUMTRANSMAPS) + mobj->renderflags |= RF_DONTDRAW; + + if (trans < NUMTRANSMAPS) { - mobj->renderflags |= RF_DONTDRAW; - } - else - { - mobj->renderflags &= ~(RF_TRANSMASK|RF_DONTDRAW); + mobj->renderflags &= ~(RF_TRANSMASK | K_GetPlayerDontDrawFlag(player)); if (trans != 0) { From e242207d10c5edf7d12e7364eab0b2998861ebdd Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Tue, 20 Sep 2022 19:01:54 -0700 Subject: [PATCH 15/26] Mindelay: Oni suggestions rollup --- src/d_clisrv.c | 10 +++++++--- src/hu_stuff.c | 37 +++++++++++++++++++++++++++++++++---- src/hu_stuff.h | 2 +- src/k_hud.c | 4 ++-- src/k_menudef.c | 6 ++++++ src/screen.c | 5 ++++- src/sdl/i_video.c | 2 ++ 7 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index aa4199fce..2f38f0aef 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -115,7 +115,7 @@ UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. static tic_t lowest_lag; boolean server_lagless; static CV_PossibleValue_t mindelay_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}}; -consvar_t cv_mindelay = CVAR_INIT ("mindelay", "0", 0, mindelay_cons_t, NULL); +consvar_t cv_mindelay = CVAR_INIT ("mindelay", "0", CV_SAVE, mindelay_cons_t, NULL); SINT8 nodetoplayer[MAXNETNODES]; SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) @@ -5650,7 +5650,7 @@ static inline void PingUpdate(void) if (nodeingame[i]) HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1)); - pingmeasurecount = 1; //Reset count + pingmeasurecount = 0; //Reset count } static tic_t gametime = 0; @@ -5667,7 +5667,7 @@ static void UpdatePingTable(void) if (netgame && !(gametime % 35)) // update once per second. PingUpdate(); - fastest = cv_mindelay.value; + fastest = 0; // update node latency values so we can take an average later. for (i = 0; i < MAXPLAYERS; i++) @@ -5690,6 +5690,10 @@ static void UpdatePingTable(void) } } + // Don't gentleman below your mindelay + if (fastest < (tic_t)cv_mindelay.value) + fastest = (tic_t)cv_mindelay.value; + pingmeasurecount++; if (server_lagless) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index fd57f4a36..2ffc80bc7 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -79,6 +79,7 @@ typedef enum patch_t *pinggfx[5]; // small ping graphic patch_t *mping[5]; // smaller ping graphic patch_t *pingmeasure[2]; // ping measurement graphic +patch_t *pinglocal[2]; // mindelay indecator patch_t *framecounter; patch_t *frameslash; // framerate stuff. Used in screen.c @@ -197,6 +198,9 @@ void HU_LoadGraphics(void) HU_UpdatePatch(&pingmeasure[0], "PINGD"); HU_UpdatePatch(&pingmeasure[1], "PINGMS"); + HU_UpdatePatch(&pinglocal[0], "PINGGFXL"); + HU_UpdatePatch(&pinglocal[1], "MPINGL"); + // fps stuff HU_UpdatePatch(&framecounter, "FRAMER"); HU_UpdatePatch(&frameslash, "FRAMESL"); @@ -2346,25 +2350,47 @@ Ping_gfx_num (int lag) return 4; } +static int +Ping_gfx_color (int lag) +{ + if (lag < 2) + return SKINCOLOR_JAWZ; + else if (lag < 4) + return SKINCOLOR_MINT; + else if (lag < 7) + return SKINCOLOR_GOLD; + else if (lag < 10) + return SKINCOLOR_RASPBERRY; + else + return SKINCOLOR_MAGENTA; +} + // // HU_drawPing // -void HU_drawPing(INT32 x, INT32 y, UINT32 lag, INT32 flags) +void HU_drawPing(INT32 x, INT32 y, UINT32 lag, INT32 flags, boolean offline) { UINT8 *colormap = NULL; INT32 measureid = cv_pingmeasurement.value ? 1 : 0; INT32 gfxnum; // gfx to draw + boolean drawlocal = (offline && cv_mindelay.value && lag <= (tic_t)cv_mindelay.value); gfxnum = Ping_gfx_num(lag); if (measureid == 1) V_DrawScaledPatch(x+11 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]); - V_DrawScaledPatch(x+2, y, flags, pinggfx[gfxnum]); + + if (drawlocal) + V_DrawScaledPatch(x+2, y, flags, pinglocal[0]); + else + V_DrawScaledPatch(x+2, y, flags, pinggfx[gfxnum]); + + colormap = R_GetTranslationColormap(TC_RAINBOW, Ping_gfx_color(lag), GTC_CACHE); if (servermaxping && lag > servermaxping && hu_tick < 4) { // flash ping red if too high - colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_RASPBERRY, GTC_CACHE); + colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_WHITE, GTC_CACHE); } if (cv_pingmeasurement.value) @@ -2389,7 +2415,10 @@ HU_drawMiniPing (INT32 x, INT32 y, UINT32 lag, INT32 flags) w /= 2; } - patch = mping[Ping_gfx_num(lag)]; + if (cv_mindelay.value && (tic_t)cv_mindelay.value <= lag) + patch = pinglocal[1]; + else + patch = mping[Ping_gfx_num(lag)]; if (( flags & V_SNAPTORIGHT )) x += ( w - SHORT (patch->width) ); diff --git a/src/hu_stuff.h b/src/hu_stuff.h index cc9959467..9bcf45e09 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -138,7 +138,7 @@ void HU_Drawer(void); char HU_dequeueChatChar(void); void HU_Erase(void); void HU_clearChatChars(void); -void HU_drawPing(INT32 x, INT32 y, UINT32 ping, INT32 flags); // Lat': Ping drawer for scoreboard. +void HU_drawPing(INT32 x, INT32 y, UINT32 ping, INT32 flags, boolean offline); // Lat': Ping drawer for scoreboard. void HU_drawMiniPing(INT32 x, INT32 y, UINT32 ping, INT32 flags); INT32 HU_CreateTeamScoresTbl(playersort_t *tab, UINT32 dmtotals[]); diff --git a/src/k_hud.c b/src/k_hud.c index 96635584e..2496e5393 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2177,7 +2177,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN } else if (tab[i].num != serverplayer || !server_lagless) { - HU_drawPing(x + ((i < 8) ? -17 : rightoffset + 11), y-4, playerpingtable[tab[i].num], 0); + HU_drawPing(x + ((i < 8) ? -17 : rightoffset + 11), y-4, playerpingtable[tab[i].num], 0, false); } } @@ -4878,7 +4878,7 @@ void K_drawKartHUD(void) V_DrawCenteredString(BASEVIDWIDTH>>1, 176, V_REDMAP|V_SNAPTOBOTTOM, "WRONG WAY"); } - if (netgame && r_splitscreen) + if ((netgame || cv_mindelay.value) && r_splitscreen) { K_drawMiniPing(); } diff --git a/src/k_menudef.c b/src/k_menudef.c index d97083509..fe243c38c 100644 --- a/src/k_menudef.c +++ b/src/k_menudef.c @@ -1035,6 +1035,12 @@ menuitem_t OPTIONS_Gameplay[] = {IT_STRING | IT_CVAR, "Karma Comeback", "Enable Karma Comeback in Battle mode.", NULL, {.cvar = &cv_kartcomeback}, 0, 0}, + {IT_SPACE | IT_NOTHING, NULL, NULL, + NULL, {NULL}, 0, 0}, + + {IT_STRING | IT_CVAR, "Offline Input Delay", "Practice for online play in offline modes. Higher = more delay.", + NULL, {.cvar = &cv_mindelay}, 0, 0}, + {IT_SPACE | IT_NOTHING, NULL, NULL, NULL, {NULL}, 0, 0}, diff --git a/src/screen.c b/src/screen.c index 5d6b59ee8..f1b53a7f2 100644 --- a/src/screen.c +++ b/src/screen.c @@ -628,11 +628,14 @@ void SCR_DisplayTicRate(void) void SCR_DisplayLocalPing(void) { + boolean offline; + UINT32 ping = playerpingtable[consoleplayer]; // consoleplayer's ping is everyone's ping in a splitnetgame :P if (! r_splitscreen && ( cv_showping.value == 1 || (cv_showping.value == 2 && ping > servermaxping) )) // only show 2 (warning) if our ping is at a bad level { INT32 dispy = cv_ticrate.value ? 160 : 181; - HU_drawPing(307, dispy, ping, V_SNAPTORIGHT | V_SNAPTOBOTTOM | V_HUDTRANS); + offline = (consoleplayer == serverplayer); + HU_drawPing(307, dispy, ping, V_SNAPTORIGHT | V_SNAPTOBOTTOM | V_HUDTRANS, offline); } } diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 2361a5349..09b2f6bbf 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1219,6 +1219,8 @@ void I_FinishUpdate(void) } } } + if (cv_mindelay.value && consoleplayer == serverplayer) + SCR_DisplayLocalPing(); } if (marathonmode) From 87b92a7127137bc78739c492543f4646d305900f Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Tue, 20 Sep 2022 20:05:00 -0700 Subject: [PATCH 16/26] Bump ping tiers by 1 tic --- src/hu_stuff.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 2ffc80bc7..2fe1fb883 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2338,13 +2338,13 @@ void HU_Erase(void) static int Ping_gfx_num (int lag) { - if (lag < 2) + if (lag <= 2) return 0; - else if (lag < 4) + else if (lag <= 4) return 1; - else if (lag < 7) + else if (lag <= 7) return 2; - else if (lag < 10) + else if (lag <= 10) return 3; else return 4; @@ -2353,13 +2353,13 @@ Ping_gfx_num (int lag) static int Ping_gfx_color (int lag) { - if (lag < 2) + if (lag <= 2) return SKINCOLOR_JAWZ; - else if (lag < 4) + else if (lag <= 4) return SKINCOLOR_MINT; - else if (lag < 7) + else if (lag <= 7) return SKINCOLOR_GOLD; - else if (lag < 10) + else if (lag <= 10) return SKINCOLOR_RASPBERRY; else return SKINCOLOR_MAGENTA; From e1f72898f5543d2f0e66ff72baebafeddb8773d1 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Tue, 20 Sep 2022 20:15:02 -0700 Subject: [PATCH 17/26] Mindelay: Update ping display even in local play --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 2f38f0aef..69eebe595 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5664,7 +5664,7 @@ static void UpdatePingTable(void) if (server) { - if (netgame && !(gametime % 35)) // update once per second. + if (!(gametime % 35)) // update once per second. PingUpdate(); fastest = 0; From ada40b421c1757025ff1a9369932813245a52b4c Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Tue, 20 Sep 2022 20:29:34 -0700 Subject: [PATCH 18/26] Mindelay: Never draw ping outside of games --- src/k_hud.c | 2 +- src/sdl/i_video.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 2496e5393..fd4493a93 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4878,7 +4878,7 @@ void K_drawKartHUD(void) V_DrawCenteredString(BASEVIDWIDTH>>1, 176, V_REDMAP|V_SNAPTOBOTTOM, "WRONG WAY"); } - if ((netgame || cv_mindelay.value) && r_splitscreen) + if ((netgame || cv_mindelay.value) && r_splitscreen && Playing()) { K_drawMiniPing(); } diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 09b2f6bbf..a1948f2f1 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1219,7 +1219,7 @@ void I_FinishUpdate(void) } } } - if (cv_mindelay.value && consoleplayer == serverplayer) + if (cv_mindelay.value && consoleplayer == serverplayer && Playing()) SCR_DisplayLocalPing(); } From bd83a9f3b198082b1aecfb2d02c41cbafb6ef447 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Tue, 20 Sep 2022 20:33:30 -0700 Subject: [PATCH 19/26] Mindelay: Probably don't calculate ping outside of games period --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 69eebe595..1c3708b12 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5664,7 +5664,7 @@ static void UpdatePingTable(void) if (server) { - if (!(gametime % 35)) // update once per second. + if (Playing() && !(gametime % 35)) // update once per second. PingUpdate(); fastest = 0; From 8525dfb50273e4265bd470948f8298e25b9da630 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Tue, 20 Sep 2022 21:21:51 -0700 Subject: [PATCH 20/26] Allow netgame clients to display and be affected by mindelay --- src/d_clisrv.c | 5 +++++ src/hu_stuff.c | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1c3708b12..f11215b60 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5725,6 +5725,11 @@ static void UpdatePingTable(void) } } } + else // We're a client, handle mindelay on the way out. + { + if ((neededtic - gametic) < (tic_t)cv_mindelay.value) + lowest_lag = cv_mindelay.value - (neededtic - gametic); + } } static void RenewHolePunch(void) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 2fe1fb883..bdcc158d4 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2375,6 +2375,12 @@ void HU_drawPing(INT32 x, INT32 y, UINT32 lag, INT32 flags, boolean offline) INT32 gfxnum; // gfx to draw boolean drawlocal = (offline && cv_mindelay.value && lag <= (tic_t)cv_mindelay.value); + if (!server && lag <= (tic_t)cv_mindelay.value) + { + lag = cv_mindelay.value; + drawlocal = true; + } + gfxnum = Ping_gfx_num(lag); if (measureid == 1) @@ -2415,7 +2421,15 @@ HU_drawMiniPing (INT32 x, INT32 y, UINT32 lag, INT32 flags) w /= 2; } - if (cv_mindelay.value && (tic_t)cv_mindelay.value <= lag) + CONS_Printf("mindelay %d / lag %d\n", cv_mindelay.value, lag); + + // This looks kinda dumb, but basically: + // Servers with mindelay set modify the ping table. + // Clients with mindelay unset don't, because they can't. + // Both are affected by mindelay, but a client's lag value is pre-adjustment. + if (server && cv_mindelay.value && (tic_t)cv_mindelay.value <= lag) + patch = pinglocal[1]; + else if (!server && cv_mindelay.value && (tic_t)cv_mindelay.value >= lag) patch = pinglocal[1]; else patch = mping[Ping_gfx_num(lag)]; From aaf18fb1cf7f000526fa22f51999edecd370c30d Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Tue, 20 Sep 2022 21:29:17 -0700 Subject: [PATCH 21/26] Offline Input Delay -> Minimum Input Delay, default 0 -> 2 --- src/d_clisrv.c | 2 +- src/k_menudef.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index f11215b60..1e5787583 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -115,7 +115,7 @@ UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. static tic_t lowest_lag; boolean server_lagless; static CV_PossibleValue_t mindelay_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}}; -consvar_t cv_mindelay = CVAR_INIT ("mindelay", "0", CV_SAVE, mindelay_cons_t, NULL); +consvar_t cv_mindelay = CVAR_INIT ("mindelay", "2", CV_SAVE, mindelay_cons_t, NULL); SINT8 nodetoplayer[MAXNETNODES]; SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) diff --git a/src/k_menudef.c b/src/k_menudef.c index fe243c38c..97f77abd2 100644 --- a/src/k_menudef.c +++ b/src/k_menudef.c @@ -1038,7 +1038,7 @@ menuitem_t OPTIONS_Gameplay[] = {IT_SPACE | IT_NOTHING, NULL, NULL, NULL, {NULL}, 0, 0}, - {IT_STRING | IT_CVAR, "Offline Input Delay", "Practice for online play in offline modes. Higher = more delay.", + {IT_STRING | IT_CVAR, "Minimum Input Delay", "Practice for online play! Higher = more delay.", NULL, {.cvar = &cv_mindelay}, 0, 0}, {IT_SPACE | IT_NOTHING, NULL, NULL, From 51d46a2a8abd88a5a46ab6e6e5491abc5d90190f Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Tue, 20 Sep 2022 21:32:45 -0700 Subject: [PATCH 22/26] Remove debug print --- src/hu_stuff.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index bdcc158d4..1d7f23ac9 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2421,8 +2421,6 @@ HU_drawMiniPing (INT32 x, INT32 y, UINT32 lag, INT32 flags) w /= 2; } - CONS_Printf("mindelay %d / lag %d\n", cv_mindelay.value, lag); - // This looks kinda dumb, but basically: // Servers with mindelay set modify the ping table. // Clients with mindelay unset don't, because they can't. From 3f66a8e72f351f1008189cc450257c734cc41a23 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 21 Sep 2022 01:38:21 -0400 Subject: [PATCH 23/26] Fix fast fall preventing stumble --- src/k_kart.c | 63 +++++++++++++++++++++++++++++++--------------------- src/k_kart.h | 1 + src/p_user.c | 13 +++++++++-- 3 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 8b0f472a9..00c99c8e1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3865,6 +3865,8 @@ boolean K_CheckStumble(player_t *player, angle_t oldPitch, angle_t oldRoll, bool // Oh jeez, you landed on your side. // You get to tumble. + P_ResetPlayer(player); + #if 0 // Single, medium bounce player->tumbleBounces = TUMBLEBOUNCES; @@ -9568,31 +9570,7 @@ static void K_KartSpindash(player_t *player) } else if (player->fastfall != 0) { - // Handle fastfall bounce. - const fixed_t maxBounce = player->mo->scale * 10; - const fixed_t minBounce = player->mo->scale; - fixed_t bounce = 2 * abs(player->fastfall) / 3; - - if (bounce > maxBounce) - { - bounce = maxBounce; - } - else - { - // Lose speed on bad bounce. - player->mo->momx /= 2; - player->mo->momy /= 2; - - if (bounce < minBounce) - { - bounce = minBounce; - } - } - - S_StartSound(player->mo, sfx_ffbonc); - player->mo->momz = bounce * P_MobjFlip(player->mo); - - player->fastfall = 0; + // Still handling fast-fall bounce. return; } @@ -9659,6 +9637,41 @@ static void K_KartSpindash(player_t *player) #undef SPINDASHTHRUSTTIME +boolean K_FastFallBounce(player_t *player) +{ + // Handle fastfall bounce. + if (player->fastfall != 0) + { + const fixed_t maxBounce = player->mo->scale * 10; + const fixed_t minBounce = player->mo->scale; + fixed_t bounce = 2 * abs(player->fastfall) / 3; + + if (bounce > maxBounce) + { + bounce = maxBounce; + } + else + { + // Lose speed on bad bounce. + player->mo->momx /= 2; + player->mo->momy /= 2; + + if (bounce < minBounce) + { + bounce = minBounce; + } + } + + S_StartSound(player->mo, sfx_ffbonc); + player->mo->momz = bounce * P_MobjFlip(player->mo); + + player->fastfall = 0; + return true; + } + + return false; +} + static void K_AirFailsafe(player_t *player) { const fixed_t maxSpeed = 6*player->mo->scale; diff --git a/src/k_kart.h b/src/k_kart.h index b44258a9a..46f97a3f5 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -149,6 +149,7 @@ fixed_t K_GetNewSpeed(player_t *player); fixed_t K_3dKartMovement(player_t *player); boolean K_PlayerEBrake(player_t *player); SINT8 K_Sliptiding(player_t *player); +boolean K_FastFallBounce(player_t *player); void K_AdjustPlayerFriction(player_t *player); void K_MoveKartPlayer(player_t *player, boolean onground); void K_CheckSpectateStatus(void); diff --git a/src/p_user.c b/src/p_user.c index e7cc525cc..f733bad28 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1354,15 +1354,24 @@ boolean P_PlayerHitFloor(player_t *player, boolean fromAir, angle_t oldPitch, an K_SpawnSplashForMobj(player->mo, abs(player->mo->momz)); } - if (player->mo->health) + if (player->mo->health > 0) { boolean air = fromAir; if (P_IsObjectOnGround(player->mo) && (player->mo->eflags & MFE_JUSTHITFLOOR)) + { air = true; + } - if (K_CheckStumble(player, oldPitch, oldRoll, air)) + if (K_CheckStumble(player, oldPitch, oldRoll, air) == true) + { return false; + } + + if (air == false && K_FastFallBounce(player) == true) + { + return false; + } } } From 1530c15db74ba11395e5feb4c564fed58e9f935c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 21 Sep 2022 02:01:38 -0400 Subject: [PATCH 24/26] Fix visual not matching exact steep range --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 00c99c8e1..513fe6c7f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3996,7 +3996,7 @@ void K_UpdateStumbleIndicator(player_t *player) steepRange = ANGLE_90 - steepVal; delta = max(0, abs(delta) - ((signed)steepVal)); - trans = ((FixedDiv(AngleFixed(delta), AngleFixed(steepRange)) * (NUMTRANSMAPS+1)) + (FRACUNIT/2)) / FRACUNIT; + trans = ((FixedDiv(AngleFixed(delta), AngleFixed(steepRange)) * NUMTRANSMAPS) + (FRACUNIT/2)) / FRACUNIT; if (trans < 0) { From e347fadf0219c17c963f752c4d1470a21d5a8db9 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 21 Sep 2022 07:49:33 -0400 Subject: [PATCH 25/26] Add a fudge constant to the stumble indicator --- src/k_kart.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 513fe6c7f..39366c64d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3925,6 +3925,7 @@ void K_InitStumbleIndicator(player_t *player) void K_UpdateStumbleIndicator(player_t *player) { + const angle_t fudge = ANG10; mobj_t *mobj = NULL; boolean air = false; @@ -3956,7 +3957,7 @@ void K_UpdateStumbleIndicator(player_t *player) P_MoveOrigin(mobj, player->mo->x, player->mo->y, player->mo->z + (player->mo->height / 2)); air = !P_IsObjectOnGround(player->mo); - steepVal = air ? STUMBLE_STEEP_VAL_AIR : STUMBLE_STEEP_VAL; + steepVal = (air ? STUMBLE_STEEP_VAL_AIR : STUMBLE_STEEP_VAL) - fudge; slopeSteep = max(AngleDelta(player->mo->pitch, 0), AngleDelta(player->mo->roll, 0)); delta = 0; From 329aecd5e52c8e5da1dc8d0d70cafc9216b80cc0 Mon Sep 17 00:00:00 2001 From: VelocitOni Date: Wed, 21 Sep 2022 10:12:10 -0400 Subject: [PATCH 26/26] Made the circle solid for longer Edited NUMTRANSMAPS to make it solid for 2 maps longer, adjusted fudge ANG to 15 from 10 (more visually lenient) --- src/k_kart.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 39366c64d..2b1eb3aa1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -19,6 +19,7 @@ #include "p_setup.h" #include "r_draw.h" #include "r_local.h" +#include "r_things.c" #include "s_sound.h" #include "st_stuff.h" #include "v_video.h" @@ -3925,7 +3926,7 @@ void K_InitStumbleIndicator(player_t *player) void K_UpdateStumbleIndicator(player_t *player) { - const angle_t fudge = ANG10; + const angle_t fudge = ANG15; mobj_t *mobj = NULL; boolean air = false; @@ -3997,24 +3998,24 @@ void K_UpdateStumbleIndicator(player_t *player) steepRange = ANGLE_90 - steepVal; delta = max(0, abs(delta) - ((signed)steepVal)); - trans = ((FixedDiv(AngleFixed(delta), AngleFixed(steepRange)) * NUMTRANSMAPS) + (FRACUNIT/2)) / FRACUNIT; + trans = ((FixedDiv(AngleFixed(delta), AngleFixed(steepRange)) * (NUMTRANSMAPS - 2)) + (FRACUNIT/2)) / FRACUNIT; if (trans < 0) { trans = 0; } - if (trans > NUMTRANSMAPS) + if (trans > (NUMTRANSMAPS - 2)) { - trans = NUMTRANSMAPS; + trans = (NUMTRANSMAPS - 2); } // invert - trans = NUMTRANSMAPS - trans; + trans = (NUMTRANSMAPS - 2) - trans; mobj->renderflags |= RF_DONTDRAW; - if (trans < NUMTRANSMAPS) + if (trans < (NUMTRANSMAPS - 2)) { mobj->renderflags &= ~(RF_TRANSMASK | K_GetPlayerDontDrawFlag(player));