Fix terrain friction and rework closer to sector friction

This commit is contained in:
NepDisk 2024-09-14 09:19:22 -04:00
parent a26f971980
commit 7a1be2aeac
3 changed files with 92 additions and 20 deletions

View file

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

View file

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

View file

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