Skip to content

Commit

Permalink
libcommon|Refactor: Unified the mobj thrust multiplier calculation
Browse files Browse the repository at this point in the history
Since the thrust multiplier is directly related to friction, it should
be placed next to the friction calculations.
  • Loading branch information
skyjake committed Dec 14, 2014
1 parent e61fb81 commit d483aca
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 56 deletions.
32 changes: 31 additions & 1 deletion doomsday/plugins/common/include/mobj.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,31 @@ extern "C" {
*
* @param mo Object.
*
* @return Friction multiplier to apply to the momentum.
* @return Friction factor to apply to the momentum.
*/
coord_t Mobj_Friction(mobj_t const *mo);

/**
* Calculates the thrust multiplier for the mobj, to be applied when the mobj momentum
* changes under thrust. The multiplier adjusts thrust behavior to account for slippery
* or sticky surfaces.
*
* @param mo Object.
*
* @return Thrust multiplier.
*/
coord_t Mobj_ThrustMul(mobj_t const *mo);

/**
* Calculates the mobj thrust multiplier given a certain friction. The thrust multiplier
* counters the effect of increased friction to retain normal thrust behavior.
*
* @param friction Friction factor.
*
* @return Thrust factor to account for amount of friction.
*/
coord_t Mobj_ThrustMulForFriction(coord_t friction);

/**
* Handles the stopping of mobj movement. Also stops player walking animation.
*
Expand Down Expand Up @@ -70,6 +91,15 @@ dd_bool Mobj_IsPlayer(mobj_t const *mobj);
*/
dd_bool Mobj_IsVoodooDoll(mobj_t const *mobj);

/**
* Determines if the mobj is currently touching the floor or on an object.
*
* @param mo Object.
*
* @return @c true, if the object is considered to be airborne/flying.
*/
dd_bool Mobj_IsAirborne(mobj_t const *mo);

/**
* @param mobj Mobj instance.
* @param allAround @c false= only look 180 degrees in front.
Expand Down
3 changes: 1 addition & 2 deletions doomsday/plugins/common/include/p_xgsec.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,7 @@ void XS_Update(void);
void XS_Thinker(void *xsThinker);

coord_t XS_Gravity(Sector *sector);
coord_t XS_Friction(Sector *sector);
coord_t XS_ThrustMul(Sector *sector);
coord_t XS_Friction(Sector const *sector);

void XS_InitMovePlane(Line *line);

Expand Down
60 changes: 53 additions & 7 deletions doomsday/plugins/common/src/mobj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,34 +47,80 @@
/// Threshold for stopping walk animation.
#define STANDSPEED (1.0 / 2) // FIX2FLT(0x8000)

coord_t Mobj_ThrustMulForFriction(coord_t friction)
{
if(friction <= FRICTION_NORMAL)
return 1; // Normal friction.

if(friction > 1)
return 0; // There's nothing to thrust from!

// Decrease thrust exponentially when nearing friction == 1.0.
// {c = -93.31092643, b = 208.0448223, a = -114.7338958}
return (-114.7338958 * friction * friction + 208.0448223 * friction - 93.31092643);
}

coord_t Mobj_ThrustMul(mobj_t const *mo)
{
coord_t mul = 1.0;

#if __JHEXEN__
if(P_MobjFloorTerrain(mo)->flags & TTF_FRICTION_LOW)
{
mul /= 2;
}
#else // !__JHEXEN__
Sector *sec = Mobj_Sector(mo);

#if __JHERETIC__
if(P_ToXSector(sec)->special == 15) // Friction_Low
{
mul /= 4;
return mul; // XG friction ignored.
}
#endif

// Use a thrust multiplier based on the sector's friction.
mul = Mobj_ThrustMulForFriction(XS_Friction(sec));

#endif

return mul;
}

dd_bool Mobj_IsAirborne(mobj_t const *mo)
{
return ((mo->flags2 & MF2_FLY) && !(mo->origin[VZ] <= mo->floorZ) && !mo->onMobj) != 0;
}

coord_t Mobj_Friction(mobj_t const *mo)
{
if((mo->flags2 & MF2_FLY) && !(mo->origin[VZ] <= mo->floorZ) && !mo->onMobj)
if(Mobj_IsAirborne(mo))
{
// Airborne "friction".
return FRICTION_FLY;
}

#ifdef __JHERETIC__
if(P_ToXSector(Mobj_Sector(mo))->special == 15)
#if __JHERETIC__
if(P_ToXSector(Mobj_Sector(mo))->special == 15) // Low friction.
{
// Low friction.
return FRICTION_LOW;
}
#endif

#ifdef __JHEXEN__
#if __JHEXEN__
terraintype_t const *tt = P_MobjFloorTerrain(mo);
if(tt->flags & TTF_FRICTION_LOW)
{
return FRICTION_LOW;
}
return FRICTION_NORMAL; // Hexen doesn't have XG sectors.
#endif

#ifndef __JHEXEN__
#if LIBCOMMON_HAVE_XG
// Use the current sector's friction.
return XS_Friction(Mobj_Sector(mo));
#else
return FRICTION_NORMAL;
#endif
}

Expand Down
25 changes: 1 addition & 24 deletions doomsday/plugins/common/src/p_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,30 +230,7 @@ void P_Thrust(player_t *player, angle_t angle, coord_t move)

if(!(player->powers[PT_FLIGHT] && !(mo->origin[VZ] <= mo->floorZ)))
{
#if __JDOOM__ || __JDOOM64__ || __JHERETIC__
Sector *sec = Mobj_Sector(mo);
#endif
#if __JHEXEN__
terraintype_t const *tt = P_MobjFloorTerrain(mo);
#endif

#if __JHEXEN__
if(tt->flags & TTF_FRICTION_LOW)
{
move /= 2;
}
#elif __JHERETIC__
if(P_ToXSector(sec)->special == 15) // Friction_Low
{
move /= 4;
}
else
#endif
#if __JDOOM__ || __JDOOM64__ || __JHERETIC__
{
move *= XS_ThrustMul(sec);
}
#endif
move *= Mobj_ThrustMul(mo);
}

mo->mom[MX] += move * FIX2FLT(finecosine[an]);
Expand Down
29 changes: 7 additions & 22 deletions doomsday/plugins/common/src/p_xgsec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3010,36 +3010,21 @@ coord_t XS_Gravity(Sector* sec)
coord_t gravity = xsec->xg->info.gravity;

// Apply gravity modifier.
if(cfg.netGravity != -1)
gravity *= (coord_t) cfg.netGravity / 100;
if(cfg.common.netGravity != -1)
gravity *= (coord_t) cfg.common.netGravity / 100;

return gravity;
}
}

coord_t XS_Friction(Sector* sector)
coord_t XS_Friction(Sector const *sector)
{
if(!P_ToXSector(sector)->xg || !(P_ToXSector(sector)->xg->info.flags & STF_FRICTION))
return FRICTION_NORMAL; // Normal friction.

return P_ToXSector(sector)->xg->info.friction;
}
auto const *xsec = P_ToXSector_const(sector);

/**
* @return The thrust multiplier to emulate by friction.
*/
coord_t XS_ThrustMul(Sector *sector)
{
coord_t x = XS_Friction(sector);

if(x <= FRICTION_NORMAL)
return 1; // Normal friction.

if(x > 1)
return 0; // There's nothing to thrust from!
if(!xsec->xg || !(xsec->xg->info.flags & STF_FRICTION))
return FRICTION_NORMAL; // Normal friction.

// {c = -93.31092643, b = 208.0448223, a = -114.7338958}
return (-114.7338958 * x * x + 208.0448223 * x - 93.31092643);
return xsec->xg->info.friction;
}

/**
Expand Down

0 comments on commit d483aca

Please sign in to comment.