mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- floatified friction.
This commit is contained in:
parent
6c9e5b03c8
commit
7a26318bf0
15 changed files with 84 additions and 94 deletions
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
21
src/p_spec.h
21
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);
|
||||
|
||||
//
|
||||
|
|
|
@ -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.;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue