From 7a26318bf0245bf44e8261a400d64533b18c07eb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 24 Mar 2016 22:50:03 +0100 Subject: [PATCH] - floatified friction. --- src/actor.h | 2 +- src/doomdef.h | 11 +++----- src/p_acs.cpp | 4 +-- src/p_enemy.cpp | 15 +++++----- src/p_local.h | 12 ++------ src/p_map.cpp | 41 ++++++++++++++-------------- src/p_mobj.cpp | 18 ++++++------ src/p_sectors.cpp | 2 +- src/p_spec.cpp | 30 ++++++++++++++++---- src/p_spec.h | 21 +------------- src/p_terrain.cpp | 10 +++---- src/p_terrain.h | 4 +-- src/p_user.cpp | 2 +- src/r_defs.h | 4 +-- src/thingdef/thingdef_properties.cpp | 2 +- 15 files changed, 84 insertions(+), 94 deletions(-) diff --git a/src/actor.h b/src/actor.h index c74714e94..5bd462a0b 100644 --- a/src/actor.h +++ b/src/actor.h @@ -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; diff --git a/src/doomdef.h b/src/doomdef.h index 346a73f0f..67c43787c 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -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) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 4885389ed..2ca9378aa 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -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; } diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index e63185638..5742aa49a 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -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 diff --git a/src/p_local.h b/src/p_local.h index bea8d9d20..63e3e2c94 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -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] diff --git a/src/p_map.cpp b/src/p_map.cpp index c2eefcda2..c0bfd4cd7 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -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) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 197575aaa..9118abce3 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -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; } // diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 6a91d7072..10a8aedd7 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -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) { diff --git a/src/p_spec.cpp b/src/p_spec.cpp index bd7eabdeb..0c4380cd4 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -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 // diff --git a/src/p_spec.h b/src/p_spec.h index 5407ed9b6..cfdbd5241 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -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); // diff --git a/src/p_terrain.cpp b/src/p_terrain.cpp index a91d7fe92..f99652758 100644 --- a/src/p_terrain.cpp +++ b/src/p_terrain.cpp @@ -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 (friction, 0, FRACUNIT); + friction = (0x1EB8*(sc.Float*100))/0x80 + 0xD001; + friction = clamp (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.; } //========================================================================== diff --git a/src/p_terrain.h b/src/p_terrain.h index b9217b45e..e8e6544d0 100644 --- a/src/p_terrain.h +++ b/src/p_terrain.h @@ -115,8 +115,8 @@ struct FTerrainDef FSoundID RightStepSound; bool IsLiquid; bool AllowProtection; - fixed_t Friction; - fixed_t MoveFactor; + double Friction; + double MoveFactor; }; extern TArray Splashes; diff --git a/src/p_user.cpp b/src/p_user.cpp index 1eee21935..a8e8755bc 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -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. diff --git a/src/r_defs.h b/src/r_defs.h index fac1379c3..57fdba270 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -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]; diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 5ab622dce..71818a7ae 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -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;