From 7a1be2aeacf75d68a980b81c88e7929611b26e27 Mon Sep 17 00:00:00 2001 From: NepDisk <16447892+NepDisk@users.noreply.github.com> Date: Sat, 14 Sep 2024 09:19:22 -0400 Subject: [PATCH] Fix terrain friction and rework closer to sector friction --- src/k_terrain.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++- src/k_terrain.h | 20 ++--------- src/p_map.c | 2 +- 3 files changed, 92 insertions(+), 20 deletions(-) diff --git a/src/k_terrain.c b/src/k_terrain.c index 62ca483ca..a5e0f7f2a 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -464,6 +464,87 @@ void K_UpdateMobjTerrain(mobj_t *mo, INT32 flatID) mo->terrain = K_GetTerrainForFlatNum(flatID); } +/*-------------------------------------------------- + void K_SetTerrainFriction(mobj_t *mo) + + Applies friction from Terrain definition. + + Input Arguments:- + mo - The object to apply friction to. + +--------------------------------------------------*/ +static void K_SetTerrainFriction(mobj_t *mo) +{ + boolean isPlayer = false; + fixed_t strength = mo->terrain->friction; + terrain_t *terrain = NULL; + fixed_t newFriction = INT32_MAX; + fixed_t newMovefactor = INT32_MAX; + + if (mo == NULL || P_MobjWasRemoved(mo) == true) + { + // Invalid object. + return; + } + + isPlayer = (mo->player != NULL); + terrain = mo->terrain; + + if (isPlayer && !((terrain->flags & TRF_BYPASSBOOST) + || (mo->player->invincibilitytimer == 0 && mo->player->hyudorotimer == 0 + && mo->player->sneakertimer == 0 && mo->player->growshrinktimer <= 0))) + { + // I want this to be consistent with sector friction + // so boosts bypass friction unless specficied otherwise + return; + } + + mo->friction = ORIG_FRICTION; + + if (isPlayer == true) + { + mo->movefactor = FRACUNIT; + } + + if (strength > 0) // sludge + { + strength = strength * 2; // otherwise, the maximum sludginess value is +967... + } + + // The following might seem odd. At the time of movement, + // the move distance is multiplied by 'friction/0x10000', so a + // higher friction value actually means 'less friction'. + newFriction = ORIG_FRICTION - FixedMul(0x1EB8, strength) / 0x80; // ORIG_FRICTION is 0xE800 + + if (newFriction > FRACUNIT) + { + newFriction = FRACUNIT; + } + + if (newFriction < 0) + { + newFriction = 0; + } + + mo->friction = newFriction; + + if (isPlayer == true) + { + newMovefactor = FixedDiv(ORIG_FRICTION, newFriction); + + if (newMovefactor < FRACUNIT) + { + newMovefactor = 19*newMovefactor - 18*FRACUNIT; + } + else + { + newMovefactor = FRACUNIT; + } + + mo->movefactor = newMovefactor; + } +} + /*-------------------------------------------------- void K_ProcessTerrainEffect(mobj_t *mo) @@ -488,6 +569,9 @@ void K_ProcessTerrainEffect(mobj_t *mo) terrain = mo->terrain; player = mo->player; + + if (terrain->friction) // Handle Friction set here so mobjs are affected as well. + K_SetTerrainFriction(mo); if (player == NULL) { @@ -676,7 +760,7 @@ void K_ProcessTerrainEffect(mobj_t *mo) if (!terrain->springStrength) K_DoPogoSpring(player->mo, 0, 1); else - S_StartSound(mo, sfx_kc2f); + S_StartSound(player->mo, sfx_kc2f); } // (Offroad is handled elsewhere!) @@ -1673,6 +1757,10 @@ static void K_ParseTerrainParameter(size_t i, char *param, char *val) { K_FlagBoolean(&terrain->flags, TRF_REMAP, val); } + else if (stricmp(param, "fricfix") == 0 || stricmp(param, "frictionfix") == 0 || stricmp(param, "boostbypass") == 0) + { + K_FlagBoolean(&terrain->flags, TRF_BYPASSBOOST, val); + } } /*-------------------------------------------------- diff --git a/src/k_terrain.h b/src/k_terrain.h index f22db4a94..faae4df18 100644 --- a/src/k_terrain.h +++ b/src/k_terrain.h @@ -96,7 +96,8 @@ typedef enum TRF_SNEAKERPANEL = 1<<1, // Texture is a booster TRF_WATERRUNPANEL = 1<<2, // Texture is a waterrun panel TRF_TRIPWIRE = 1<<3, // Texture is a tripwire when used as a midtexture - TRF_REMAP = 1<<4 // Texture colors may be remapped with ENCOREMAP or TWEAKMAP + TRF_REMAP = 1<<4, // Texture colors may be remapped with ENCOREMAP or TWEAKMAP + TRF_BYPASSBOOST = 1<<5 // Texture bypasses boost friction resistence } terrain_flags_t; typedef struct terrain_s @@ -517,23 +518,6 @@ void K_UpdateMobjTerrain(mobj_t *mo, INT32 flatID); void K_ProcessTerrainEffect(mobj_t *mo); -/*-------------------------------------------------- - void K_SetDefaultFriction(mobj_t *mo); - - Resets an object to their default friction values. - If they are on terrain with different friction, - they will update to that value. - - Input Arguments:- - mo - The object to reset the friction values of. - - Return:- - None ---------------------------------------------------*/ - -void K_SetDefaultFriction(mobj_t *mo); - - /*-------------------------------------------------- void K_SpawnSplashForMobj(mobj_t *mo, fixed_t impact); diff --git a/src/p_map.c b/src/p_map.c index bc977db93..63d28f86c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -614,7 +614,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) return BMIT_CONTINUE; // underneath if (thing->player && thing->flags & MF_SHOOTABLE && tm.thing->health > 0) { - UINT32 damagetype = (tm.thing->info->mass & 0xFF); + UINT32 damagetype = (tm.thing->info->mass & DMG_TYPEMASK); P_DamageMobj(thing, tm.thing, tm.thing, 1, damagetype); } return BMIT_CONTINUE;