[Done] Checking speed + in floor

Archive of the old editing forum
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
Locked
User avatar
DBThanatos
Posts: 3101
Joined: Fri Apr 14, 2006 3:17 pm
Location: in "the darkness that lurks in our mind"

[Done] Checking speed + in floor

Post by DBThanatos »

Im usually OK when trying to figure out things for decorate, but for ACS, is a completely different story for me.

Im just trying to find a workaround for foot steps on player. What I need is an script that would check the player speed, and if he is on the floor. But I dont seem to be able to understand how to combine [wiki]GetActorVelX[/wiki] and [wiki]GetActorVelY[/wiki], nor how to apply this in a script.

The idea is basically check the player speed constantly; if is too slow, footstep sound will be played with more time between each other, and when is at full speed, play it more frequently, and since it'd be an script that would be running all the time, I need to make sure player is actually on the floor (to avoid playing footstep sounds while jumping or falling) wich I think would be with [wiki]GetActorZ[/wiki]. I simply cant get my head around this.

So, is this possible? and if so, can someone help me to construct it? Is just that the old footstep method simply works horrible with earphones and certain issues completely prevents it from working.
Last edited by DBThanatos on Thu Oct 21, 2010 10:20 pm, edited 1 time in total.
User avatar
David Ferstat
Posts: 1113
Joined: Wed Jul 16, 2003 8:53 am
Location: Perth, Western Australia
Contact:

Re: Checking speed + in floor

Post by David Ferstat »

OK, as I understand it, there's a couple of things you want to do here.

You want to play footstep sounds for the player at a frequency that depends upon the player's speed.
You want to only play these sounds while the player is on the floor.

Now, if you're NOT going to have any sectors that modify the player's max speed, you could assume that the player is either stationary, walking, or running. You should be able to detect which through [wiki]GetPlayerInput[/wiki]. Note that this is a crude method; as the wiki notes, there are circumstances where this wouldn't be reliable.

Alternatively, if you want something that's more accurate, then you want to determine the players speed through GetActorVelX and its sibling GetActorVelY.

So, remember your geometry? No? Well, Zippy's gone and done a lot of my job for me, because he's created [wiki]Trigonometry[/wiki]. Using this page you can see how to use GetActorVelX and GetActorVelY to find the player's speed.

Ok, so we've got player speed sorted.

You need a script to calculate the interval between each footstep, probably something like this:

Code: Select all

If PlayerSpeed is not 0 // You want to make sure that you never divide by zero
   Interval = constant/PlayerSpeed // The faster you travel, the less time between footsteps
So how do we know when to play footsteps? According to [wiki]GetActorZ[/wiki],
Usage This returns the Z coordinate of the actor. It will return the absolute height of the actor, not the height relative to the floor. To calculate the height of the floor, subtract the result of [wiki]GetActorFloorZ[/wiki] from this value.
So how do we put this together? Well, I expect that it would look something this:

Code: Select all

while PlayerSpeed is not equal to zero // We only want to use this code while the player is moving
   while GetActorZ is equal to GetActorFloorZ // That is, if the player is standing on the floor
   Timer = 0 // This is the timer that will tell us when to play the next step
      while Timer is not equal to Interval
         Play footstep
         Timer = Timer + 1
Note that the timer here is counts up, rather than down, as Interval may change while the script is running.

Yes, I do realize that this is not, by any means, ACS. Rather, it's an example of what I was taught, many many moons ago, to call pseudo-script. However, it should be enough for you to see the logic, so that you can convert it to ACS.
User avatar
DBThanatos
Posts: 3101
Joined: Fri Apr 14, 2006 3:17 pm
Location: in "the darkness that lurks in our mind"

Re: Checking speed + in floor

Post by DBThanatos »

BUT I WANTZ THE CODEZ!! PLZ?

Nah, seriously, thanks, i needed some direction here :P
However, I thought I did get it, but apparently Im messing something here. First, of course, Im trying to get the player speed right.

This is how my script looks

Code: Select all

#library "speed"
#include "zcommon.acs"

function int sqrt (int x)  //found on the wiki by searching SQRT
{
	int r;
	x = x + 1 >> 1;
	while (x > r)
		x -= r++;
	return r;
}

script 685 (void)
{
	while(1)
	{
		int PlayerSpeedX,PlayerSpeedY,temp,PlayerSpeedTotal;  //I just wanted to store everything to understand :P
		PlayerSpeedX=GetActorVelX(0);
		PlayerSpeedY=GetActorVelY(0);
		temp=((PlayerSpeedX*PlayerSpeedX)+(PlayerSpeedY*PlayerSpeedY));     //In theory this should be the part "a^2 + b^2"
		PlayerSpeedTotal=(sqrt(temp));     //and this, " = c^2"
		HudMessage(s:"X speed: ",d:(PlayerSpeedX);HUDMSG_PLAIN, 1, CR_RED, 0.1, 0.8, 1.0);
		HudMessage(s:"Y speed: ",d:(PlayerSpeedY);HUDMSG_PLAIN, 2, CR_RED, 0.1, 0.9, 1.0);
		HudMessage(s:"Total speed: ",d:(PlayerSpeedTotal);HUDMSG_PLAIN, 3, CR_RED, 0.1, 0.1, 1.0);
		delay(3);
	}
}
But on the "total speed" Im getting lots of zeros (as in "none") even when moving diagonally. And sometimes I get pretty big numbers on the total speed like 10,000,000.
User avatar
DBThanatos
Posts: 3101
Joined: Fri Apr 14, 2006 3:17 pm
Location: in "the darkness that lurks in our mind"

Re: Checking speed + in floor

Post by DBThanatos »

And somehow I missed completely this example in the wiki:

Code: Select all

script 1 enter
{
  int x, y, z, speed;
  while (TRUE)
  {
    x = GetActorVelX(0);
    y = GetActorVelY(0);
    z = GetActorVelZ(0);
    speed = FixedMul(x, x) + FixedMul(y, y) + FixedMul(z, z);
    print(f:sqrt(speed));
  }
}
With a delay of 3 tics, it seems to work as desired; even though I dont quite get it, it works :P

However, is it taking also in account the z speed? can I remove that part safely? since that one doesnt matter for what Im trying to achieve. If so, is it as simple as:

Code: Select all

    speed = FixedMul(x, x) + FixedMul(y, y);
?
User avatar
DBThanatos
Posts: 3101
Joined: Fri Apr 14, 2006 3:17 pm
Location: in "the darkness that lurks in our mind"

Re: Checking speed + in floor

Post by DBThanatos »

Triple posting! YAY!

So, after toying with what I had for a while, I think I finally nailed it. I tested it, and seems to work just like I needed. Here's my (perhaps ugly) code:
Spoiler:
Basically, if too slow, no sound will be played. If medium speed, medium delay. If player is going from fast to pretty fast, short delay. I think I covered all the possibilities, but Im posting this just in case someone finds it useful (yay for "convoluted" footstep system), or if someone can find any major horrible flaw.

Thanks again David! I really needed someone to point me in the right direction :D
User avatar
David Ferstat
Posts: 1113
Joined: Wed Jul 16, 2003 8:53 am
Location: Perth, Western Australia
Contact:

Re: [Done] Checking speed + in floor

Post by David Ferstat »

DBT, you're very welcome.

I think that, when you're trying to code something, the most important trick to learn is to how to break up your task into lots of small tasks.

For example, say you need to find an actor's speed (just to pull an example of of thin air :) .) Now, speed is defined as distance travelled divided by the time taken to do so. Therefore, you need to be able to measure distance and time. Distance you can get from the actor's x, y and z coordinates at time a, and from the equivalent coordinates at time b. Once you have these numbers, Pythagoras will give you the distance. Time, of course, is the gap between a and b.

So, you make a function that records where the actor is at time a, and stores these numbers. Then, at some predefined time later (b) it stores the player's location again. You then calculate the distance, and divide by time.

If you start to list your tasks, you get:

Record player position a
Record time a
Record player position b
Record time b
Calculate distance between a and b
Calculate time between a and b
Divide distance by time

Once you see your list like this, you can see that your tasks don't look anywhere near as daunting, as each task becomes smaller.
Locked

Return to “Editing (Archive)”