- floatified friction.

This commit is contained in:
Christoph Oelckers 2016-03-24 22:50:03 +01:00
parent 6c9e5b03c8
commit 7a26318bf0
15 changed files with 84 additions and 94 deletions

View file

@ -1244,7 +1244,7 @@ public:
double wallbouncefactor; // The bounce factor for walls can be different. double wallbouncefactor; // The bounce factor for walls can be different.
int bouncecount; // Strife's grenades only bounce twice before exploding int bouncecount; // Strife's grenades only bounce twice before exploding
double Gravity; // [GRB] Gravity factor double Gravity; // [GRB] Gravity factor
fixed_t Friction; double Friction;
int FastChaseStrafeCount; int FastChaseStrafeCount;
double pushfactor; double pushfactor;
int lastpush; int lastpush;

View file

@ -366,13 +366,10 @@ enum
// magnetized floors, etc. Less friction can create ice. // magnetized floors, etc. Less friction can create ice.
#define MORE_FRICTION_VELOCITY (15000/65536.) // mud factor based on velocity #define MORE_FRICTION_VELOCITY (15000/65536.) // mud factor based on velocity
#define ORIG_FRICTION 0xE800 // original value #define ORIG_FRICTION (0xE800/65536.) // original value
#define fORIG_FRICTION (ORIG_FRICTION/65536.) #define ORIG_FRICTION_FACTOR (2048/65536.) // original value
#define ORIG_FRICTION_FACTOR 2048 // original value #define FRICTION_LOW (0xf900/65536.)
#define fORIG_FRICTION_FACTOR (2048/65536.) // original value #define FRICTION_FLY (0xeb00/65536.)
#define FRICTION_LOW 0xf900
#define FRICTION_FLY 0xeb00
#define fFRICTION_FLY (0xeb00/65536.)
#define BLINKTHRESHOLD (4*32) #define BLINKTHRESHOLD (4*32)

View file

@ -4022,7 +4022,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
break; break;
case APROP_Friction: case APROP_Friction:
actor->Friction = value; actor->Friction = ACSToDouble(value);
default: default:
// do nothing. // do nothing.
@ -4123,7 +4123,7 @@ int DLevelScript::GetActorProperty (int tid, int property)
case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies()); case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies());
case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag()); case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag());
case APROP_StencilColor:return actor->fillcolor; case APROP_StencilColor:return actor->fillcolor;
case APROP_Friction: return actor->Friction; case APROP_Friction: return DoubleToACS(actor->Friction);
default: return 0; default: return 0;
} }

View file

@ -453,9 +453,9 @@ bool P_Move (AActor *actor)
fixed_t tryx, tryy, deltax, deltay, origx, origy; fixed_t tryx, tryy, deltax, deltay, origx, origy;
bool try_ok; bool try_ok;
int speed = actor->_f_speed(); fixed_t speed = actor->_f_speed();
int movefactor = ORIG_FRICTION_FACTOR; double movefactor = ORIG_FRICTION_FACTOR;
int friction = ORIG_FRICTION; double friction = ORIG_FRICTION;
int dropoff = 0; int dropoff = 0;
if (actor->flags2 & MF2_BLASTED) if (actor->flags2 & MF2_BLASTED)
@ -503,8 +503,7 @@ bool P_Move (AActor *actor)
if (friction < ORIG_FRICTION) if (friction < ORIG_FRICTION)
{ // sludge { // sludge
speed = ((ORIG_FRICTION_FACTOR - (ORIG_FRICTION_FACTOR-movefactor)/2) speed = fixed_t(speed * ((ORIG_FRICTION_FACTOR - (ORIG_FRICTION_FACTOR-movefactor)/2)) / ORIG_FRICTION_FACTOR);
* speed) / ORIG_FRICTION_FACTOR;
if (speed == 0) if (speed == 0)
{ // always give the monster a little bit of speed { // always give the monster a little bit of speed
speed = ksgn(actor->_f_speed()); speed = ksgn(actor->_f_speed());
@ -564,9 +563,9 @@ bool P_Move (AActor *actor)
if (try_ok && friction > ORIG_FRICTION) if (try_ok && friction > ORIG_FRICTION)
{ {
actor->SetOrigin(origx, origy, actor->_f_Z(), false); actor->SetOrigin(origx, origy, actor->_f_Z(), false);
movefactor *= FRACUNIT / ORIG_FRICTION_FACTOR / 4; movefactor *= 1.f / ORIG_FRICTION_FACTOR / 4;
actor->Vel.X += FIXED2DBL(FixedMul (deltax, movefactor)); actor->Vel.X += FIXED2DBL(deltax * movefactor);
actor->Vel.Y += FIXED2DBL(FixedMul (deltay, movefactor)); actor->Vel.Y += FIXED2DBL(deltay * movefactor);
} }
// [RH] If a walking monster is no longer on the floor, move it down // [RH] If a walking monster is no longer on the floor, move it down

View file

@ -428,16 +428,8 @@ void P_DelSector_List();
void P_DelSeclist(msecnode_t *); // phares 3/16/98 void P_DelSeclist(msecnode_t *); // phares 3/16/98
msecnode_t* P_DelSecnode(msecnode_t *); msecnode_t* P_DelSecnode(msecnode_t *);
void P_CreateSecNodeList(AActor*,fixed_t,fixed_t); // phares 3/14/98 void P_CreateSecNodeList(AActor*,fixed_t,fixed_t); // phares 3/14/98
int P_GetMoveFactor(const AActor *mo, int *frictionp); // phares 3/6/98 double P_GetMoveFactor(const AActor *mo, double *frictionp); // phares 3/6/98
inline double P_GetMoveFactor(const AActor *mo, double *frictionp) double P_GetFriction(const AActor *mo, double *frictionfactor);
{
int rv, fp;
rv = P_GetMoveFactor(mo, &fp);
*frictionp = FIXED2DBL(fp);
return FIXED2DBL(rv);
}
int P_GetFriction(const AActor *mo, int *frictionfactor);
bool Check_Sides(AActor *, int, int); // phares bool Check_Sides(AActor *, int, int); // phares
// [RH] // [RH]

View file

@ -587,14 +587,15 @@ void P_PlayerStartStomp(AActor *actor, bool mononly)
// //
//========================================================================== //==========================================================================
int P_GetFriction(const AActor *mo, int *frictionfactor) double P_GetFriction(const AActor *mo, double *frictionfactor)
{ {
int friction = ORIG_FRICTION; double friction = ORIG_FRICTION;
int movefactor = ORIG_FRICTION_FACTOR; double movefactor = ORIG_FRICTION_FACTOR;
fixed_t newfriction; double newfriction;
double newmf;
const msecnode_t *m; const msecnode_t *m;
sector_t *sec; sector_t *sec;
fixed_t newmf;
if (mo->IsNoClip2()) if (mo->IsNoClip2())
{ {
@ -608,7 +609,7 @@ int P_GetFriction(const AActor *mo, int *frictionfactor)
(mo->waterlevel == 1 && mo->Z() > mo->floorz+ 6)) (mo->waterlevel == 1 && mo->Z() > mo->floorz+ 6))
{ {
friction = mo->Sector->GetFriction(sector_t::floor, &movefactor); friction = mo->Sector->GetFriction(sector_t::floor, &movefactor);
movefactor >>= 1; movefactor *= 0.5;
// Check 3D floors -- might be the source of the waterlevel // Check 3D floors -- might be the source of the waterlevel
for (unsigned i = 0; i < mo->Sector->e->XFloor.ffloors.Size(); i++) for (unsigned i = 0; i < mo->Sector->e->XFloor.ffloors.Size(); i++)
@ -625,7 +626,7 @@ int P_GetFriction(const AActor *mo, int *frictionfactor)
if (newfriction < friction || friction == ORIG_FRICTION) if (newfriction < friction || friction == ORIG_FRICTION)
{ {
friction = newfriction; friction = newfriction;
movefactor = newmf >> 1; movefactor = newmf * 0.5;
} }
} }
} }
@ -648,13 +649,13 @@ int P_GetFriction(const AActor *mo, int *frictionfactor)
if (rover->flags & FF_SOLID) if (rover->flags & FF_SOLID)
{ {
// Must be standing on a solid floor // Must be standing on a solid floor
if (mo->_f_Z() != rover->top.plane->ZatPoint(pos)) continue; if (mo->Z() != rover->top.plane->ZatPointF(pos)) continue;
} }
else if (rover->flags & FF_SWIMMABLE) else if (rover->flags & FF_SWIMMABLE)
{ {
// Or on or inside a swimmable floor (e.g. in shallow water) // Or on or inside a swimmable floor (e.g. in shallow water)
if (mo->_f_Z() > rover->top.plane->ZatPoint(pos) || if (mo->Z() > rover->top.plane->ZatPointF(pos) ||
(mo->_f_Top()) < rover->bottom.plane->ZatPoint(pos)) (mo->Top()) < rover->bottom.plane->ZatPointF(pos))
continue; continue;
} }
else else
@ -664,7 +665,7 @@ int P_GetFriction(const AActor *mo, int *frictionfactor)
if (newfriction < friction || friction == ORIG_FRICTION) if (newfriction < friction || friction == ORIG_FRICTION)
{ {
friction = newfriction; friction = newfriction;
movefactor = newmf >> 1; movefactor = newmf * 0.5;
} }
} }
@ -675,9 +676,9 @@ int P_GetFriction(const AActor *mo, int *frictionfactor)
} }
newfriction = sec->GetFriction(sector_t::floor, &newmf); newfriction = sec->GetFriction(sector_t::floor, &newmf);
if ((newfriction < friction || friction == ORIG_FRICTION) && if ((newfriction < friction || friction == ORIG_FRICTION) &&
(mo->_f_Z() <= sec->floorplane.ZatPoint(pos) || (mo->Z() <= sec->floorplane.ZatPointF(pos) ||
(sec->GetHeightSec() != NULL && (sec->GetHeightSec() != NULL &&
mo->_f_Z() <= sec->heightsec->floorplane.ZatPoint(pos)))) mo->Z() <= sec->heightsec->floorplane.ZatPointF(pos))))
{ {
friction = newfriction; friction = newfriction;
movefactor = newmf; movefactor = newmf;
@ -685,9 +686,9 @@ int P_GetFriction(const AActor *mo, int *frictionfactor)
} }
} }
if (mo->Friction != FRACUNIT) if (mo->Friction != 1)
{ {
friction = clamp(FixedMul(friction, mo->Friction), 0, FRACUNIT); friction = clamp((friction * mo->Friction), 0., 1.);
movefactor = FrictionToMoveFactor(friction); movefactor = FrictionToMoveFactor(friction);
} }
@ -707,9 +708,9 @@ int P_GetFriction(const AActor *mo, int *frictionfactor)
// //
//========================================================================== //==========================================================================
int P_GetMoveFactor(const AActor *mo, int *frictionp) double P_GetMoveFactor(const AActor *mo, double *frictionp)
{ {
int movefactor, friction; double movefactor, friction;
// If the floor is icy or muddy, it's harder to get moving. This is where // If the floor is icy or muddy, it's harder to get moving. This is where
// the different friction factors are applied to 'trying to move'. In // the different friction factors are applied to 'trying to move'. In
@ -723,11 +724,11 @@ int P_GetMoveFactor(const AActor *mo, int *frictionp)
double velocity = mo->VelXYToSpeed(); double velocity = mo->VelXYToSpeed();
if (velocity > MORE_FRICTION_VELOCITY * 4) if (velocity > MORE_FRICTION_VELOCITY * 4)
movefactor <<= 3; movefactor *= 8;
else if (velocity > MORE_FRICTION_VELOCITY * 2) else if (velocity > MORE_FRICTION_VELOCITY * 2)
movefactor <<= 2; movefactor *= 4;
else if (velocity > MORE_FRICTION_VELOCITY) else if (velocity > MORE_FRICTION_VELOCITY)
movefactor <<= 1; movefactor *= 2;
} }
if (frictionp) if (frictionp)

View file

@ -2269,7 +2269,7 @@ explode:
// Reducing player velocity is no longer needed to reduce // Reducing player velocity is no longer needed to reduce
// bobbing, so ice works much better now. // bobbing, so ice works much better now.
double friction = FIXED2DBL(P_GetFriction (mo, NULL)); double friction = P_GetFriction (mo, NULL);
mo->Vel.X *= friction; mo->Vel.X *= friction;
mo->Vel.Y *= friction; mo->Vel.Y *= friction;
@ -2280,8 +2280,8 @@ explode:
if (player && player->mo == mo) // Not voodoo dolls if (player && player->mo == mo) // Not voodoo dolls
{ {
player->Vel.X *= fORIG_FRICTION; player->Vel.X *= ORIG_FRICTION;
player->Vel.Y *= fORIG_FRICTION; player->Vel.Y *= ORIG_FRICTION;
} }
// Don't let the velocity become less than the smallest representable fixed point value. // Don't let the velocity become less than the smallest representable fixed point value.
@ -2452,11 +2452,11 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
{ {
mo->_f_AddZ(finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8); mo->_f_AddZ(finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8);
} }
mo->Vel.Z *= fFRICTION_FLY; mo->Vel.Z *= FRICTION_FLY;
} }
if (mo->waterlevel && !(mo->flags & MF_NOGRAVITY)) if (mo->waterlevel && !(mo->flags & MF_NOGRAVITY))
{ {
fixed_t friction = FIXED_MIN; double friction = -1;
// Check 3D floors -- might be the source of the waterlevel // Check 3D floors -- might be the source of the waterlevel
for (auto rover : mo->Sector->e->XFloor.ffloors) for (auto rover : mo->Sector->e->XFloor.ffloors)
@ -2464,17 +2464,17 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
if (!(rover->flags & FF_EXISTS)) continue; if (!(rover->flags & FF_EXISTS)) continue;
if (!(rover->flags & FF_SWIMMABLE)) continue; if (!(rover->flags & FF_SWIMMABLE)) continue;
if (mo->_f_Z() >= rover->top.plane->ZatPoint(mo) || if (mo->Z() >= rover->top.plane->ZatPointF(mo) ||
mo->_f_Z() + mo->_f_height()/2 < rover->bottom.plane->ZatPoint(mo)) mo->Center() < rover->bottom.plane->ZatPointF(mo))
continue; continue;
friction = rover->model->GetFriction(rover->top.isceiling); friction = rover->model->GetFriction(rover->top.isceiling);
break; break;
} }
if (friction == FIXED_MIN) if (friction < 0)
friction = mo->Sector->GetFriction(); // get real friction, even if from a terrain definition friction = mo->Sector->GetFriction(); // get real friction, even if from a terrain definition
mo->Vel.Z *= FIXED2DBL(friction); mo->Vel.Z *= friction;
} }
// //

View file

@ -1027,7 +1027,7 @@ fixed_t sector_t::NextLowestFloorAt(fixed_t x, fixed_t y, fixed_t z, int flags,
// //
//=========================================================================== //===========================================================================
fixed_t sector_t::GetFriction(int plane, fixed_t *pMoveFac) const double sector_t::GetFriction(int plane, double *pMoveFac) const
{ {
if (Flags & SECF_FRICTION) if (Flags & SECF_FRICTION)
{ {

View file

@ -1212,7 +1212,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers)
case dFriction_Low: case dFriction_Low:
sector->friction = FRICTION_LOW; sector->friction = FRICTION_LOW;
sector->movefactor = 0x269; sector->movefactor = 0x269/65536.;
sector->Flags |= SECF_FRICTION; sector->Flags |= SECF_FRICTION;
break; break;
@ -2049,7 +2049,7 @@ static void P_SpawnFriction(void)
} }
else else
{ {
length = P_AproxDistance(l->dx,l->dy)>>FRACBITS; length = int(l->Delta().Length());
} }
P_SetSectorFriction (l->args[0], length, false); P_SetSectorFriction (l->args[0], length, false);
@ -2061,14 +2061,14 @@ static void P_SpawnFriction(void)
void P_SetSectorFriction (int tag, int amount, bool alterFlag) void P_SetSectorFriction (int tag, int amount, bool alterFlag)
{ {
int s; int s;
fixed_t friction, movefactor; double friction, movefactor;
// An amount of 100 should result in a friction of // An amount of 100 should result in a friction of
// ORIG_FRICTION (0xE800) // ORIG_FRICTION (0xE800)
friction = (0x1EB8*amount)/0x80 + 0xD001; friction = ((0x1EB8 * amount) / 0x80 + 0xD001) / 65536.;
// killough 8/28/98: prevent odd situations // killough 8/28/98: prevent odd situations
friction = clamp(friction, 0, FRACUNIT); friction = clamp(friction, 0., 1.);
// The following check might seem odd. At the time of movement, // The following check might seem odd. At the time of movement,
// the move distance is multiplied by 'friction/0x10000', so a // the move distance is multiplied by 'friction/0x10000', so a
@ -2106,6 +2106,26 @@ void P_SetSectorFriction (int tag, int amount, bool alterFlag)
} }
} }
double FrictionToMoveFactor(double friction)
{
double movefactor;
// [RH] Twiddled these values so that velocity on ice (with
// friction 0xf900) is the same as in Heretic/Hexen.
if (friction >= ORIG_FRICTION) // ice
//movefactor = ((0x10092 - friction)*(0x70))/0x158;
movefactor = (((0x10092 - friction * 65536) * 1024) / 4352 + 568) / 65536.;
else
movefactor = (((friction*65536. - 0xDB34)*(0xA)) / 0x80) / 65536.;
// killough 8/28/98: prevent odd situations
if (movefactor < 1 / 2048.)
movefactor = 1 / 2048.;
return movefactor;
}
// //
// phares 3/12/98: End of friction effects // phares 3/12/98: End of friction effects
// //

View file

@ -170,26 +170,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector=NULL);
void P_PlayerOnSpecialFlat (player_t *player, int floorType); void P_PlayerOnSpecialFlat (player_t *player, int floorType);
void P_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass, int flags); void P_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass, int flags);
void P_SetSectorFriction (int tag, int amount, bool alterFlag); void P_SetSectorFriction (int tag, int amount, bool alterFlag);
double FrictionToMoveFactor(double friction);
inline fixed_t FrictionToMoveFactor(fixed_t friction)
{
fixed_t movefactor;
// [RH] Twiddled these values so that velocity on ice (with
// friction 0xf900) is the same as in Heretic/Hexen.
if (friction >= ORIG_FRICTION) // ice
// movefactor = ((0x10092 - friction)*(0x70))/0x158;
movefactor = ((0x10092 - friction) * 1024) / 4352 + 568;
else
movefactor = ((friction - 0xDB34)*(0xA))/0x80;
// killough 8/28/98: prevent odd situations
if (movefactor < 32)
movefactor = 32;
return movefactor;
}
void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornum); void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornum);
// //

View file

@ -488,15 +488,15 @@ static void ParseDamage (FScanner &sc, int keyword, void *fields)
static void ParseFriction (FScanner &sc, int keyword, void *fields) static void ParseFriction (FScanner &sc, int keyword, void *fields)
{ {
FTerrainDef *def = (FTerrainDef *)fields; FTerrainDef *def = (FTerrainDef *)fields;
fixed_t friction, movefactor; double friction, movefactor;
sc.MustGetFloat (); sc.MustGetFloat ();
// These calculations should match those in P_SetSectorFriction(). // These calculations should match those in P_SetSectorFriction().
// A friction of 1.0 is equivalent to ORIG_FRICTION. // A friction of 1.0 is equivalent to ORIG_FRICTION.
friction = (fixed_t)(0x1EB8*(sc.Float*100))/0x80 + 0xD001; friction = (0x1EB8*(sc.Float*100))/0x80 + 0xD001;
friction = clamp<fixed_t> (friction, 0, FRACUNIT); friction = clamp<double> (friction, 0, 65536.);
if (friction > ORIG_FRICTION) // ice if (friction > ORIG_FRICTION) // ice
movefactor = ((0x10092 - friction) * 1024) / 4352 + 568; movefactor = ((0x10092 - friction) * 1024) / 4352 + 568;
@ -506,8 +506,8 @@ static void ParseFriction (FScanner &sc, int keyword, void *fields)
if (movefactor < 32) if (movefactor < 32)
movefactor = 32; movefactor = 32;
def->Friction = friction; def->Friction = friction / 65536.;
def->MoveFactor = movefactor; def->MoveFactor = movefactor / 65536.;
} }
//========================================================================== //==========================================================================

View file

@ -115,8 +115,8 @@ struct FTerrainDef
FSoundID RightStepSound; FSoundID RightStepSound;
bool IsLiquid; bool IsLiquid;
bool AllowProtection; bool AllowProtection;
fixed_t Friction; double Friction;
fixed_t MoveFactor; double MoveFactor;
}; };
extern TArray<FSplashDef> Splashes; extern TArray<FSplashDef> Splashes;

View file

@ -1967,7 +1967,7 @@ void P_MovePlayer (player_t *player)
double fm, sm; double fm, sm;
movefactor = P_GetMoveFactor (mo, &friction); movefactor = P_GetMoveFactor (mo, &friction);
bobfactor = friction < ORIG_FRICTION ? movefactor : fORIG_FRICTION_FACTOR; bobfactor = friction < ORIG_FRICTION ? movefactor : ORIG_FRICTION_FACTOR;
if (!player->onground && !(player->mo->flags & MF_NOGRAVITY) && !player->mo->waterlevel) if (!player->onground && !(player->mo->flags & MF_NOGRAVITY) && !player->mo->waterlevel)
{ {
// [RH] allow very limited movement if not on ground. // [RH] allow very limited movement if not on ground.

View file

@ -585,7 +585,7 @@ struct sector_t
int GetFloorLight () const; int GetFloorLight () const;
int GetCeilingLight () const; int GetCeilingLight () const;
sector_t *GetHeightSec() const; sector_t *GetHeightSec() const;
fixed_t GetFriction(int plane = sector_t::floor, fixed_t *movefac = NULL) const; double GetFriction(int plane = sector_t::floor, double *movefac = NULL) const;
DInterpolation *SetInterpolation(int position, bool attach); DInterpolation *SetInterpolation(int position, bool attach);
@ -907,7 +907,7 @@ struct sector_t
// killough 8/28/98: friction is a sector property, not an mobj property. // killough 8/28/98: friction is a sector property, not an mobj property.
// these fields used to be in AActor, but presented performance problems // these fields used to be in AActor, but presented performance problems
// when processed as mobj properties. Fix is to make them sector properties. // when processed as mobj properties. Fix is to make them sector properties.
fixed_t friction, movefactor; double friction, movefactor;
int terrainnum[2]; int terrainnum[2];

View file

@ -1350,7 +1350,7 @@ DEFINE_PROPERTY(gravity, F, Actor)
//========================================================================== //==========================================================================
DEFINE_PROPERTY(friction, F, Actor) DEFINE_PROPERTY(friction, F, Actor)
{ {
PROP_FIXED_PARM(i, 0); PROP_DOUBLE_PARM(i, 0);
if (i < 0) I_Error ("Friction must not be negative."); if (i < 0) I_Error ("Friction must not be negative.");
defaults->Friction = i; defaults->Friction = i;