From 87a223d5e23ee0922374cca077b733d1bd11a325 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 11 May 2024 22:38:25 -0400 Subject: [PATCH] New ice slope physics Make them stronger by the same factor as acceleration is weakened. This feels a lot more natural, since your top speed tends to be higher on ice, which was making them feel strangely easier to climb ... even though driving on ice is hard mode (even in real life) Also fixes an oversight where P_SpawnFriction was using the outdated movefactor constants from SRB2 instead of the ones from SRB2Kart that the rest of the codebase was using, by unifying it into one function. --- src/doomdef.h | 3 +++ src/k_kart.c | 7 +------ src/k_terrain.c | 15 +-------------- src/p_local.h | 1 + src/p_mobj.c | 19 +++++++++++++++++++ src/p_slopes.c | 31 +++++++++++++++++++++++++++++-- src/p_spec.c | 6 +----- src/r_data.c | 28 ++++++++++++++-------------- 8 files changed, 69 insertions(+), 41 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 69faba1a0..844be1261 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -607,6 +607,9 @@ typedef enum { #ifndef max // Double-Check with WATTCP-32's cdefs.h #define max(x, y) (((x) > (y)) ? (x) : (y)) #endif +#ifndef clamp +#define clamp(x, y, z) (((x) < (y)) ? (y) : (((x) > (z)) ? (z) : (x))) +#endif #endif // Max gamepad/joysticks that can be detected/used. diff --git a/src/k_kart.c b/src/k_kart.c index 5df38627e..46b0a339f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -12552,12 +12552,7 @@ void K_AdjustPlayerFriction(player_t *player) // Friction was changed, so we must recalculate movefactor if (player->mo->friction != prevfriction) { - player->mo->movefactor = FixedDiv(ORIG_FRICTION, player->mo->friction); - - if (player->mo->movefactor < FRACUNIT) - player->mo->movefactor = 19*player->mo->movefactor - 18*FRACUNIT; - else - player->mo->movefactor = FRACUNIT; + player->mo->movefactor = P_MoveFactorFromFriction(player->mo->friction); } } diff --git a/src/k_terrain.c b/src/k_terrain.c index 261ffb9d5..872d94067 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -703,9 +703,7 @@ void K_SetDefaultFriction(mobj_t *mo) if (mo->terrain != NULL) { fixed_t strength = mo->terrain->friction; - fixed_t newFriction = INT32_MAX; - fixed_t newMovefactor = INT32_MAX; if (strength > 0) // sludge { @@ -731,18 +729,7 @@ void K_SetDefaultFriction(mobj_t *mo) if (isPlayer == true) { - newMovefactor = FixedDiv(ORIG_FRICTION, newFriction); - - if (newMovefactor < FRACUNIT) - { - newMovefactor = 19*newMovefactor - 18*FRACUNIT; - } - else - { - newMovefactor = FRACUNIT; - } - - mo->movefactor = newMovefactor; + mo->movefactor = P_MoveFactorFromFriction(newFriction); } } } diff --git a/src/p_local.h b/src/p_local.h index 11bfa5aed..4d2bbdb07 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -589,6 +589,7 @@ void P_CheckGravity(mobj_t *mo, boolean affect); void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope); void P_SetPitchRoll(mobj_t *mo, angle_t pitch, angle_t yaw); void P_ResetPitchRoll(mobj_t *mo); +fixed_t P_MoveFactorFromFriction(fixed_t friction); fixed_t P_ScaleFromMap(fixed_t n, fixed_t scale); fixed_t P_GetMobjHead(const mobj_t *); fixed_t P_GetMobjFeet(const mobj_t *); diff --git a/src/p_mobj.c b/src/p_mobj.c index 0a6d5c9fa..fd3628d4e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1371,6 +1371,25 @@ void P_ResetPitchRoll(mobj_t *mo) mo->roll = 0; } +// +// P_MoveFactorFromFriction +// +fixed_t P_MoveFactorFromFriction(fixed_t friction) +{ + fixed_t ret = FixedDiv(ORIG_FRICTION, friction); + + if (ret < FRACUNIT) + { + ret = 19*ret - 18*FRACUNIT; + } + else + { + ret = FRACUNIT; + } + + return ret; +} + #define STOPSPEED (FRACUNIT) // diff --git a/src/p_slopes.c b/src/p_slopes.c index f5e4bd3ef..f13c60d7b 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -25,6 +25,7 @@ #include "w_wad.h" #include "r_fps.h" #include "k_kart.h" // K_PlayerEBrake +#include "m_easing.h" pslope_t *slopelist = NULL; UINT16 slopecount = 0; @@ -1202,8 +1203,34 @@ void P_ButteredSlope(mobj_t *mo) // Let's get the gravity strength for the object... thrust = FixedMul(thrust, abs(P_GetMobjGravity(mo))); - // ... and its friction against the ground for good measure (divided by original friction to keep behaviour for normal slopes the same). - thrust = FixedMul(thrust, FixedDiv(mo->friction, ORIG_FRICTION)); + if (mo->friction != ORIG_FRICTION) + { + // ... and its friction against the ground for good measure. + // (divided by original friction to keep behaviour for normal slopes the same) + thrust = FixedMul(thrust, FixedDiv(mo->friction, ORIG_FRICTION)); + + // Sal: Also consider movefactor of players. + // We want ice to make slopes *really* funnel you in a specific direction. + fixed_t move_factor = P_MoveFactorFromFriction(mo->friction); + + if (mo->player != NULL) + { + if (mo->player->icecube.frozen == true) + { + // Undo this change with ice cubes, because it is insanity. + move_factor = FRACUNIT; + } + else if (mo->player->tiregrease > 0) + { + // Undo this change with tire grease, so that + // springs and spindash can still overpower slopes. + fixed_t grease_frac = clamp((FRACUNIT * mo->player->tiregrease) / greasetics, 0, FRACUNIT); + move_factor = Easing_Linear(grease_frac, move_factor, FRACUNIT); + } + } + + thrust = FixedMul(thrust, FixedDiv(FRACUNIT, move_factor)); + } P_Thrust(mo, mo->standingslope->xydirection, thrust); } diff --git a/src/p_spec.c b/src/p_spec.c index 6303b84ae..dbddeead1 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -9164,11 +9164,7 @@ static void P_SpawnFriction(void) if (friction < 0) friction = 0; - movefactor = FixedDiv(ORIG_FRICTION, friction); - if (movefactor < FRACUNIT) - movefactor = 8*movefactor - 7*FRACUNIT; - else - movefactor = FRACUNIT; + movefactor = P_MoveFactorFromFriction(friction); Add_Friction(friction, movefactor, (INT32)(s-sectors), -1); diff --git a/src/r_data.c b/src/r_data.c index ff38f888f..e4993ffad 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -95,7 +95,7 @@ UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph } return output.rgba; } -#define clamp(c) max(min(c, 0xFF), 0x00); +#define clamp_rgb(c) max(min(c, 0xFF), 0x00); else { float falpha = ((float)alpha / 255.0f); @@ -104,30 +104,30 @@ UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph float fb = ((float)foreground.s.blue * falpha); if (style == AST_ADD) { - output.s.red = clamp((int)(background.s.red + fr)); - output.s.green = clamp((int)(background.s.green + fg)); - output.s.blue = clamp((int)(background.s.blue + fb)); + output.s.red = clamp_rgb((int)(background.s.red + fr)); + output.s.green = clamp_rgb((int)(background.s.green + fg)); + output.s.blue = clamp_rgb((int)(background.s.blue + fb)); } else if (style == AST_SUBTRACT) { - output.s.red = clamp((int)(background.s.red - fr)); - output.s.green = clamp((int)(background.s.green - fg)); - output.s.blue = clamp((int)(background.s.blue - fb)); + output.s.red = clamp_rgb((int)(background.s.red - fr)); + output.s.green = clamp_rgb((int)(background.s.green - fg)); + output.s.blue = clamp_rgb((int)(background.s.blue - fb)); } else if (style == AST_REVERSESUBTRACT) { - output.s.red = clamp((int)((-background.s.red) + fr)); - output.s.green = clamp((int)((-background.s.green) + fg)); - output.s.blue = clamp((int)((-background.s.blue) + fb)); + output.s.red = clamp_rgb((int)((-background.s.red) + fr)); + output.s.green = clamp_rgb((int)((-background.s.green) + fg)); + output.s.blue = clamp_rgb((int)((-background.s.blue) + fb)); } else if (style == AST_MODULATE) { fr = ((float)foreground.s.red / 256.0f); fg = ((float)foreground.s.green / 256.0f); fb = ((float)foreground.s.blue / 256.0f); - output.s.red = clamp((int)(background.s.red * fr)); - output.s.green = clamp((int)(background.s.green * fg)); - output.s.blue = clamp((int)(background.s.blue * fb)); + output.s.red = clamp_rgb((int)(background.s.red * fr)); + output.s.green = clamp_rgb((int)(background.s.green * fg)); + output.s.blue = clamp_rgb((int)(background.s.blue * fb)); } // just copy the pixel else if (style == AST_COPY) @@ -136,7 +136,7 @@ UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph output.s.alpha = 0xFF; return output.rgba; } -#undef clamp +#undef clamp_rgb return 0; }