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.
This commit is contained in:
Sally Coolatta 2024-05-11 22:38:25 -04:00
parent 5f7d08fd3c
commit 87a223d5e2
8 changed files with 69 additions and 41 deletions

View file

@ -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.

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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 *);

View file

@ -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)
//

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
}