diff --git a/src/actor.h b/src/actor.h index 4c2952639..783eb5408 100644 --- a/src/actor.h +++ b/src/actor.h @@ -906,6 +906,7 @@ public: fixed_t wallbouncefactor; // The bounce factor for walls can be different. int bouncecount; // Strife's grenades only bounce twice before exploding fixed_t gravity; // [GRB] Gravity factor + fixed_t Friction; int FastChaseStrafeCount; fixed_t pushfactor; int lastpush; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index baf573b99..16e511b23 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3605,7 +3605,8 @@ enum APROP_MeleeRange = 38, APROP_ViewHeight = 39, APROP_AttackZOffset = 40, - APROP_StencilColor = 41 + APROP_StencilColor = 41, + APROP_Friction = 42, }; // These are needed for ACS's APROP_RenderStyle @@ -3839,6 +3840,9 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) actor->SetShade(value); break; + case APROP_Friction: + actor->Friction = value; + default: // do nothing. break; @@ -3937,6 +3941,7 @@ int DLevelScript::GetActorProperty (int tid, int property, const SDWORD *stack, case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies(), stack, stackdepth); case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag(), stack, stackdepth); case APROP_StencilColor:return actor->fillcolor; + case APROP_Friction: return actor->Friction; default: return 0; } diff --git a/src/p_map.cpp b/src/p_map.cpp index 45eb0d95c..db0c09202 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -554,7 +554,13 @@ int P_GetFriction (const AActor *mo, int *frictionfactor) } } } - + + if (mo->Friction != FRACUNIT) + { + friction = clamp(FixedMul(friction, mo->Friction), 0, FRACUNIT); + movefactor = FrictionToMoveFactor(friction); + } + if (frictionfactor) *frictionfactor = movefactor; diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 5068cd575..00ed322c0 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1990,26 +1990,12 @@ void P_SetSectorFriction (int tag, int amount, bool alterFlag) friction = (0x1EB8*amount)/0x80 + 0xD001; // killough 8/28/98: prevent odd situations - if (friction > FRACUNIT) - friction = FRACUNIT; - if (friction < 0) - friction = 0; + friction = clamp(friction, 0, FRACUNIT); // The following check might seem odd. At the time of movement, // the move distance is multiplied by 'friction/0x10000', so a // higher friction value actually means 'less friction'. - - // [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; + movefactor = FrictionToMoveFactor(friction); for (s = -1; (s = P_FindSectorFromTag (tag,s)) >= 0; ) { diff --git a/src/p_spec.h b/src/p_spec.h index 245c699d7..dc0eb3646 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -172,6 +172,25 @@ void P_PlayerOnSpecialFlat (player_t *player, int floorType); void P_SectorDamage(int tag, int amount, FName type, const PClass *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; +} + void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornum); // diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 81452c7b0..b5fdc8e42 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1297,6 +1297,17 @@ DEFINE_PROPERTY(gravity, F, Actor) defaults->gravity = i; } +//========================================================================== +// +//========================================================================== +DEFINE_PROPERTY(friction, F, Actor) +{ + PROP_FIXED_PARM(i, 0); + + if (i < 0) I_Error ("Friction must not be negative."); + defaults->Friction = i; +} + //========================================================================== // //========================================================================== diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 1eb00440c..501933f04 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -18,6 +18,7 @@ ACTOR Actor native //: Thinker FloatSpeed 4 FloatBobPhase -1 // randomly initialize by default Gravity 1 + Friction 1 DamageFactor 1.0 PushFactor 0.25 WeaveIndexXY 0