[Trying to Learn] Help with changing an inbuilt bit of ZScript from GZDoom.pk3

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
User avatar
Enjay
 
 
Posts: 26855
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland

[Trying to Learn] Help with changing an inbuilt bit of ZScript from GZDoom.pk3

Post by Enjay »

Please be gentle, I'm just a complete amateur puddling around in the shallow end of the coding pool, but I'm trying to understand ZScript a bit better. Some help/guidance would be much appreciated.

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;
		}

	}
The only bit I wanted to remove was the two lines that follow the comment:
//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. :roll:
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
	}
So, firstly, have I done anything drastically wrong there? It seems to work, so I'm hoping not.

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;
		}

	}
It works (or at least seems to), but it just seems like I've had to include an awful lot of stuff in that section that is just a duplicate of the original code, all so that I can call a different section of code in order to remove a couple of lines.


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. :)
Blue Shadow
Posts: 5039
Joined: Sun Nov 14, 2010 12:59 am

Re: [Trying to Learn] Help with changing an inbuilt bit of ZScript from GZDoom.pk3

Post by Blue Shadow »

What you did there, couldn't have been done any other way.

DoFootstep isn't virtual so you can't override it, which means you have to create a copy of it with a different name and modify away. While MakeFootsteps is virtual, you're trying to modify its code rather than add to it, so you have to copy all of it in the override. If you were to add to it, you could do this:

Code: Select all

override void MakeFootsteps ()
{
	// Prepend code here...

	// Calls the direct parent class's own version of the function.
	Super.MakeFootsteps();

	// Append code here...
}
But you're not in this case.

(I hope I was gentle, there. :lol: )
User avatar
Enjay
 
 
Posts: 26855
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland

Re: [Trying to Learn] Help with changing an inbuilt bit of ZScript from GZDoom.pk3

Post by Enjay »

Not harsh at all. :)

I'm both glad I got it right (with much frantic Wiki searching and general frustration when various other attempts didn't work), and a little disappointed that there isn't a shorter way, but I very much appreciate the explanation. Thank you.

Return to “Scripting”