While I was investigating this viewtopic.php?t=80247 I realised that a few lines of code might be causing the problems that I was experiencing. As reported in that thread, they were. However, in order to test it, I couldn't figure out how to remove the lines of code by making an add-on, and so had to edit the code in GZDoom.pk3 during my testing (which is obviously not the way to go about things if I had been making an actual mod).
So, I have persevered, and got something that works as an add on, but I wanted to check how legitimate what I have done is, and if it could be any more efficiently. I'm not doing this as a fix for the code or anything, merely to try and learn how to do something that had me stumped while investigating the problem.
OK, so, here is the original code from the player definition in GZDoom.pk3.
Code: Select all
//---------------------------------------------------------------------------
//
// Handle player footstep sounds.
// Default footstep handling.
//
//---------------------------------------------------------------------------
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 * snd_footstepvolume);
}
//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()
{
if(pos.z > floorz) return;
let Ground = GetFloorTerrain();
if(Ground && (player.cmd.forwardMove != 0 || player.cmd.sideMove != 0))
{
int Delay = (player.cmd.buttons & BT_RUN) ? Ground.RunStepTics : Ground.WalkStepTics;
if((player.cmd.buttons ^ player.oldbuttons) & BT_RUN)
{ // zero out counters when starting/stopping a run
footstepCounter = 0;
footstepLength = Ground.StepDistance;
}
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;
}
}
//Steps make splashes regardless.
and I just couldn't figure it out using an add-on PK3.
However, I have now got something that seems to do the trick. So, I'll step (ahem) through what my thinking was.
Firstly, every time I tried to create an alternative of the void DoFootstep(TerrainDef Ground) section, I got errors, or my changes simply got ignored. I tried overrides and a whole bunch of things (mostly wild stabs in the dark, because I didn't really know what I was doing), but - not too surprisingly - nothing worked. Is it possible to override that section with a new one of the same name but with fewer lines? If so, how?
Eventually I realised that I could manage to override the second virtual void MakeFootsteps() section, and it calls the DoFootstep section. So, perhaps if I wrote a new DoFootstep section with a new name, I could override the MakeFoosteps section to call my new/alternative DoFootstep section instead of the original. I did that, and it worked.
However, this seems clumsy. To remove two lines of code, I have to re-write the section that I actually want to prune, and provide a whole section of code for the section that I don't really even want to touch, but which, in a couple of very short lines, calls the code that I do want to alter.
So, here's what I have:
My DoFootstep section, cunningly renamed DoFootstepNJ.

Note, I removed the two lines that I originally wanted to remove, but I also removed other things - i.e. the left/right footsteps and I commented out the variable declarations at the start too (again, just to see if it was doable, and what would happen really).
Code: Select all
//Comment these out because they should still be set in the parent code
//int footstepCounter;
//double footstepLength;
//bool footstepFoot;
void DoFootstepNJ(TerrainDef Ground)
{
Sound Step = Ground.StepSound;
//left/right stuff removed from here
if(Step)
{
A_StartSound(Step, flags: CHANF_OVERLAP, volume: Ground.StepVolume * snd_footstepvolume);
}
//forcing splashes stuff removed from here
}
Then we have my MakeFootsteps section. It's basically almost the same, except that I am overriding the original (I think) and calling DoFootstepNJ instead of DoFootstep.
Code: Select all
Override void MakeFootsteps()
{
if(pos.z > floorz) return;
let Ground = GetFloorTerrain();
if(Ground && (player.cmd.forwardMove != 0 || player.cmd.sideMove != 0))
{
int Delay = (player.cmd.buttons & BT_RUN) ? Ground.RunStepTics : Ground.WalkStepTics;
if((player.cmd.buttons ^ player.oldbuttons) & BT_RUN)
{ // zero out counters when starting/stopping a run
footstepCounter = 0;
footstepLength = Ground.StepDistance;
}
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;
DoFootstepNJ(Ground);
}
}
else
{
footstepLength = Ground.StepDistance;
}
}
else if(Delay > 0)
{ // delay-based terrain
footstepLength = 0;
if(footstepCounter % Delay == 0)
{
DoFootstepNJ(Ground);
}
footstepCounter = (footstepCounter + 1) % Delay;
}
}
else
{
footstepCounter = 0;
footstepLength = Ground.StepDistance;
footstepFoot = false;
}
}
And, again, just to be clear, this is merely me messing around trying to learn stuff. I saw what I thought should be a simple thing to replace with a cut-down patch and I couldn't figure out a way to do it. I now have something that has the correct end result, but I'm sure that there must be a better/more efficient way to do it.
So, is anyone able to suggest what I should have done (and explain it, if it isn't obvious)?
Thank you kindly.
