- 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.
int bouncecount; // Strife's grenades only bounce twice before exploding
double Gravity; // [GRB] Gravity factor
fixed_t Friction;
double Friction;
int FastChaseStrafeCount;
double pushfactor;
int lastpush;

View File

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

View File

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

View File

@ -453,9 +453,9 @@ bool P_Move (AActor *actor)
fixed_t tryx, tryy, deltax, deltay, origx, origy;
bool try_ok;
int speed = actor->_f_speed();
int movefactor = ORIG_FRICTION_FACTOR;
int friction = ORIG_FRICTION;
fixed_t speed = actor->_f_speed();
double movefactor = ORIG_FRICTION_FACTOR;
double friction = ORIG_FRICTION;
int dropoff = 0;
if (actor->flags2 & MF2_BLASTED)
@ -503,8 +503,7 @@ bool P_Move (AActor *actor)
if (friction < ORIG_FRICTION)
{ // sludge
speed = ((ORIG_FRICTION_FACTOR - (ORIG_FRICTION_FACTOR-movefactor)/2)
* speed) / ORIG_FRICTION_FACTOR;
speed = fixed_t(speed * ((ORIG_FRICTION_FACTOR - (ORIG_FRICTION_FACTOR-movefactor)/2)) / ORIG_FRICTION_FACTOR);
if (speed == 0)
{ // always give the monster a little bit of speed
speed = ksgn(actor->_f_speed());
@ -564,9 +563,9 @@ bool P_Move (AActor *actor)
if (try_ok && friction > ORIG_FRICTION)
{
actor->SetOrigin(origx, origy, actor->_f_Z(), false);
movefactor *= FRACUNIT / ORIG_FRICTION_FACTOR / 4;
actor->Vel.X += FIXED2DBL(FixedMul (deltax, movefactor));
actor->Vel.Y += FIXED2DBL(FixedMul (deltay, movefactor));
movefactor *= 1.f / ORIG_FRICTION_FACTOR / 4;
actor->Vel.X += FIXED2DBL(deltax * movefactor);
actor->Vel.Y += FIXED2DBL(deltay * movefactor);
}
// [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
msecnode_t* P_DelSecnode(msecnode_t *);
void P_CreateSecNodeList(AActor*,fixed_t,fixed_t); // phares 3/14/98
int P_GetMoveFactor(const AActor *mo, int *frictionp); // phares 3/6/98
inline double P_GetMoveFactor(const AActor *mo, double *frictionp)
{
int rv, fp;
rv = P_GetMoveFactor(mo, &fp);
*frictionp = FIXED2DBL(fp);
return FIXED2DBL(rv);
}
int P_GetFriction(const AActor *mo, int *frictionfactor);
double P_GetMoveFactor(const AActor *mo, double *frictionp); // phares 3/6/98
double P_GetFriction(const AActor *mo, double *frictionfactor);
bool Check_Sides(AActor *, int, int); // phares
// [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;
int movefactor = ORIG_FRICTION_FACTOR;
fixed_t newfriction;
double friction = ORIG_FRICTION;
double movefactor = ORIG_FRICTION_FACTOR;
double newfriction;
double newmf;
const msecnode_t *m;
sector_t *sec;
fixed_t newmf;
if (mo->IsNoClip2())
{
@ -608,7 +609,7 @@ int P_GetFriction(const AActor *mo, int *frictionfactor)
(mo->waterlevel == 1 && mo->Z() > mo->floorz+ 6))
{
friction = mo->Sector->GetFriction(sector_t::floor, &movefactor);
movefactor >>= 1;
movefactor *= 0.5;
// Check 3D floors -- might be the source of the waterlevel
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)
{
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)
{
// 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)
{
// Or on or inside a swimmable floor (e.g. in shallow water)
if (mo->_f_Z() > rover->top.plane->ZatPoint(pos) ||
(mo->_f_Top()) < rover->bottom.plane->ZatPoint(pos))
if (mo->Z() > rover->top.plane->ZatPointF(pos) ||
(mo->Top()) < rover->bottom.plane->ZatPointF(pos))
continue;
}
else
@ -664,7 +665,7 @@ int P_GetFriction(const AActor *mo, int *frictionfactor)
if (newfriction < friction || friction == ORIG_FRICTION)
{
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);
if ((newfriction < friction || friction == ORIG_FRICTION) &&
(mo->_f_Z() <= sec->floorplane.ZatPoint(pos) ||
(mo->Z() <= sec->floorplane.ZatPointF(pos) ||
(sec->GetHeightSec() != NULL &&
mo->_f_Z() <= sec->heightsec->floorplane.ZatPoint(pos))))
mo->Z() <= sec->heightsec->floorplane.ZatPointF(pos))))
{
friction = newfriction;
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);
}
@ -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
// 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();
if (velocity > MORE_FRICTION_VELOCITY * 4)
movefactor <<= 3;
movefactor *= 8;
else if (velocity > MORE_FRICTION_VELOCITY * 2)
movefactor <<= 2;
movefactor *= 4;
else if (velocity > MORE_FRICTION_VELOCITY)
movefactor <<= 1;
movefactor *= 2;
}
if (frictionp)

View File

@ -2269,7 +2269,7 @@ explode:
// Reducing player velocity is no longer needed to reduce
// 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.Y *= friction;
@ -2280,8 +2280,8 @@ explode:
if (player && player->mo == mo) // Not voodoo dolls
{
player->Vel.X *= fORIG_FRICTION;
player->Vel.Y *= fORIG_FRICTION;
player->Vel.X *= ORIG_FRICTION;
player->Vel.Y *= ORIG_FRICTION;
}
// 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->Vel.Z *= fFRICTION_FLY;
mo->Vel.Z *= FRICTION_FLY;
}
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
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_SWIMMABLE)) continue;
if (mo->_f_Z() >= rover->top.plane->ZatPoint(mo) ||
mo->_f_Z() + mo->_f_height()/2 < rover->bottom.plane->ZatPoint(mo))
if (mo->Z() >= rover->top.plane->ZatPointF(mo) ||
mo->Center() < rover->bottom.plane->ZatPointF(mo))
continue;
friction = rover->model->GetFriction(rover->top.isceiling);
break;
}
if (friction == FIXED_MIN)
if (friction < 0)
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)
{

View File

@ -1212,7 +1212,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers)
case dFriction_Low:
sector->friction = FRICTION_LOW;
sector->movefactor = 0x269;
sector->movefactor = 0x269/65536.;
sector->Flags |= SECF_FRICTION;
break;
@ -2049,7 +2049,7 @@ static void P_SpawnFriction(void)
}
else
{
length = P_AproxDistance(l->dx,l->dy)>>FRACBITS;
length = int(l->Delta().Length());
}
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)
{
int s;
fixed_t friction, movefactor;
double friction, movefactor;
// An amount of 100 should result in a friction of
// ORIG_FRICTION (0xE800)
friction = (0x1EB8*amount)/0x80 + 0xD001;
friction = ((0x1EB8 * amount) / 0x80 + 0xD001) / 65536.;
// 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 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
//

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_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass, int flags);
void P_SetSectorFriction (int tag, int amount, bool alterFlag);
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;
}
double FrictionToMoveFactor(double friction);
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)
{
FTerrainDef *def = (FTerrainDef *)fields;
fixed_t friction, movefactor;
double friction, movefactor;
sc.MustGetFloat ();
// These calculations should match those in P_SetSectorFriction().
// A friction of 1.0 is equivalent to ORIG_FRICTION.
friction = (fixed_t)(0x1EB8*(sc.Float*100))/0x80 + 0xD001;
friction = clamp<fixed_t> (friction, 0, FRACUNIT);
friction = (0x1EB8*(sc.Float*100))/0x80 + 0xD001;
friction = clamp<double> (friction, 0, 65536.);
if (friction > ORIG_FRICTION) // ice
movefactor = ((0x10092 - friction) * 1024) / 4352 + 568;
@ -506,8 +506,8 @@ static void ParseFriction (FScanner &sc, int keyword, void *fields)
if (movefactor < 32)
movefactor = 32;
def->Friction = friction;
def->MoveFactor = movefactor;
def->Friction = friction / 65536.;
def->MoveFactor = movefactor / 65536.;
}
//==========================================================================

View File

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

View File

@ -1967,7 +1967,7 @@ void P_MovePlayer (player_t *player)
double fm, sm;
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)
{
// [RH] allow very limited movement if not on ground.

View File

@ -585,7 +585,7 @@ struct sector_t
int GetFloorLight () const;
int GetCeilingLight () 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);
@ -907,7 +907,7 @@ struct sector_t
// killough 8/28/98: friction is a sector property, not an mobj property.
// these fields used to be in AActor, but presented performance problems
// when processed as mobj properties. Fix is to make them sector properties.
fixed_t friction, movefactor;
double friction, movefactor;
int terrainnum[2];

View File

@ -1350,7 +1350,7 @@ DEFINE_PROPERTY(gravity, 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.");
defaults->Friction = i;