diff --git a/src/gamedata/p_terrain.cpp b/src/gamedata/p_terrain.cpp index dfdb6e8014..0bb11237fb 100644 --- a/src/gamedata/p_terrain.cpp +++ b/src/gamedata/p_terrain.cpp @@ -188,6 +188,8 @@ static const char *TerrainKeywords[] = "allowprotection", "damageonland", "stepsounds", + "stepdistance", + "stepdistanceminvel", NULL }; @@ -225,6 +227,8 @@ static FGenericParse TerrainParser[] = { GEN_Bool, {myoffsetof(FTerrainDef, AllowProtection)} }, { GEN_Bool, {myoffsetof(FTerrainDef, DamageOnLand)} }, { GEN_Sound, {myoffsetof(FTerrainDef, StepSound)} }, + { GEN_Double, {myoffsetof(FTerrainDef, StepDistance)} }, + { GEN_Double, {myoffsetof(FTerrainDef, StepDistanceMinVel)} }, }; @@ -744,4 +748,6 @@ DEFINE_FIELD(FTerrainDef, AllowProtection) DEFINE_FIELD(FTerrainDef, DamageOnLand) DEFINE_FIELD(FTerrainDef, Friction) DEFINE_FIELD(FTerrainDef, MoveFactor) -DEFINE_FIELD(FTerrainDef, StepSound) \ No newline at end of file +DEFINE_FIELD(FTerrainDef, StepSound) +DEFINE_FIELD(FTerrainDef, StepDistance) +DEFINE_FIELD(FTerrainDef, StepDistanceMinVel) \ No newline at end of file diff --git a/src/gamedata/p_terrain.h b/src/gamedata/p_terrain.h index c581ca3fd4..6890a38cf9 100644 --- a/src/gamedata/p_terrain.h +++ b/src/gamedata/p_terrain.h @@ -119,6 +119,8 @@ struct FTerrainDef double Friction; double MoveFactor; FSoundID StepSound; + double StepDistance; + double StepDistanceMinVel; }; extern TArray Splashes; diff --git a/wadsrc/static/zscript/actors/player/player.zs b/wadsrc/static/zscript/actors/player/player.zs index c7da5e634c..746ad806a5 100644 --- a/wadsrc/static/zscript/actors/player/player.zs +++ b/wadsrc/static/zscript/actors/player/player.zs @@ -1729,6 +1729,38 @@ class PlayerPawn : Actor //--------------------------------------------------------------------------- int footstepCounter; + double footstepLength; + bool footstepFoot; + + void DoFootstep(TerrainDef Ground) + { + Sound Step = Ground.StepSound; + + //Generic foot-agnostic sound takes precedence. + if(!Step) + { + //Apparently most people walk with their right foot first, so assume that here. + if (!footstepFoot) + { + Step = Ground.LeftStepSound; + } + else + { + Step = Ground.RightStepSound; + } + + footstepFoot = !footstepFoot; + } + + if(Step) + { + A_StartSound(Step, flags: CHANF_OVERLAP, volume: Ground.StepVolume); + } + + //Steps make splashes regardless. + bool Heavy = (Mass >= 200) ? 0 : THW_SMALL; //Big player makes big splash. + HitWater(CurSector, (Pos.XY, CurSector.FloorPlane.ZatPoint(Pos.XY)), true, false, flags: Heavy | THW_NOVEL); + } virtual void MakeFootsteps() { @@ -1740,41 +1772,51 @@ class PlayerPawn : Actor { int Delay = (player.cmd.buttons & BT_RUN) ? Ground.RunStepTics : Ground.WalkStepTics; - if((player.cmd.buttons ^ player.oldbuttons) & BT_RUN) footstepCounter = 0; // zero out counter when starting/stopping a run - - if(Delay > 0 && (footstepCounter % Delay == 0)) - { - Sound Step = Ground.StepSound; - - //Generic foot-agnostic sound takes precedence. - if(!Step) - { - //Apparently most people walk with their right foot first, so assume that here. - if (footstepCounter == 0) - { - Step = Ground.LeftStepSound; - } - else - { - Step = Ground.RightStepSound; - } - } - - if(Step) - { - A_StartSound(Step, flags: CHANF_OVERLAP, volume: Ground.StepVolume); - } - - //Steps make splashes regardless. - bool Heavy = (Mass >= 200) ? 0 : THW_SMALL; //Big player makes big splash. - HitWater(CurSector, (Pos.XY, CurSector.FloorPlane.ZatPoint(Pos.XY)), true, false, flags: Heavy | THW_NOVEL); + if((player.cmd.buttons ^ player.oldbuttons) & BT_RUN) + { // zero out counters when starting/stopping a run + footstepCounter = 0; + footstepLength = Ground.StepDistance; } - footstepCounter = (footstepCounter + 1) % (Delay * 2); + if(Ground.StepDistance > 0) + { // distance-based terrain + footstepCounter = 0; + + double moveVel = vel.xy.length(); + + if(moveVel > Ground.StepDistanceMinVel) + { + footstepLength += moveVel; + + while(footstepLength > Ground.StepDistance) + { + footstepLength -= Ground.StepDistance; + DoFootstep(Ground); + } + } + else + { + footstepLength = Ground.StepDistance; + } + + } + else if(Delay > 0) + { // delay-based terrain + footstepLength = 0; + + if(footstepCounter % Delay == 0) + { + DoFootstep(Ground); + } + + footstepCounter = (footstepCounter + 1) % Delay; + } } else { footstepCounter = 0; + footstepLength = Ground.StepDistance; + footstepFoot = false; } } diff --git a/wadsrc/static/zscript/doombase.zs b/wadsrc/static/zscript/doombase.zs index 2d88d01d0e..7751e76cf6 100644 --- a/wadsrc/static/zscript/doombase.zs +++ b/wadsrc/static/zscript/doombase.zs @@ -614,6 +614,8 @@ struct TerrainDef native native double Friction; native double MoveFactor; native Sound StepSound; + native double StepDistance; + native double StepDistanceMinVel; }; enum EPickStart