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 6e88dc3da..ac2663e2c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -12573,12 +12573,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; }