while loop trouble ?
Moderator: InsideQC Admins
6 posts
• Page 1 of 1
while loop trouble ?
hey i've been having a lot of trouble with while loops in qc. for some reason everytime i make a while loop and run it crashes in game? here's some of my code that crashes when i call the function in game.
- Code: Select all
/*
=====================================
=============Sprint Function=========
=====================================
*/
void() sprinting =
{
local .float sprint_time; // float to keep track of sprint time
stuffcmd(self,"cl_forwardspeed 650"); // sprint speed
while ("cl_forwardspeed 650") // while the player is sprinting
{
self.sprint_time = time + 1; // keep going up by one second
}
if ("cl_forwardspeed 200")// if player is not sprinting and in normal speed
{
self.sprint_time = 0; // sprint_time is reset to 0 so that when it is called again it is not set to the previous sprint_time
}
while (self.sprint_time < 0) // while sprint time is greater than 0 aka player is sprinting
{
self.energy = self.energy - 5; // take 5 out of self.energy
}
if (self.energy == 0) // if theres no energy
{
centerprint(self,"You Have No More Energy left to sprint");
}
}
- sniperz227
- Posts: 112
- Joined: Sat Apr 09, 2011 3:19 am
Re: while loop trouble ?
Comments:
1. if ("cl_forwardspeed 200") <----- you can't do that. That is a string like "my name is bob" and you cannot evaluate it. Even worse, the QuakeC compiler might try too.
2. cl_forwardspeed is a client cvar, the server has no idea of the value
3. cl_forwardspeed is the speed the player wants to move if moving. That does not mean they are moving.
What you probably want is self.velocity, the speed component broken down into self.velocity_x, self.velocity_y, self.velocity_z
In QuakeC, I'm not 100% sure how you convert that to a true speed. For QuakeC I think it might be the vlen function.
And that player speed would then be the speed they are moving. By the way, that does not mean they want to move that speed. They could be falling.
Look at client.qc for more infos ...
http://inside3d.com/browse.php?show=client.qc
There is a lot more wrong with your example. Like the speed the player is moving is NEVER going to change in that loop. QuakeC thinks about a player's speed once per frame, it does not change during the course of a single function in QuakeC.
1. if ("cl_forwardspeed 200") <----- you can't do that. That is a string like "my name is bob" and you cannot evaluate it. Even worse, the QuakeC compiler might try too.
2. cl_forwardspeed is a client cvar, the server has no idea of the value
3. cl_forwardspeed is the speed the player wants to move if moving. That does not mean they are moving.
What you probably want is self.velocity, the speed component broken down into self.velocity_x, self.velocity_y, self.velocity_z
In QuakeC, I'm not 100% sure how you convert that to a true speed. For QuakeC I think it might be the vlen function.
- Code: Select all
local float playerspeed;
playerspeed = vlen(self.velocity);
And that player speed would then be the speed they are moving. By the way, that does not mean they want to move that speed. They could be falling.
Look at client.qc for more infos ...
http://inside3d.com/browse.php?show=client.qc
There is a lot more wrong with your example. Like the speed the player is moving is NEVER going to change in that loop. QuakeC thinks about a player's speed once per frame, it does not change during the course of a single function in QuakeC.
The night is young. How else can I annoy the world before sunsrise?
Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
-

Baker - Posts: 3666
- Joined: Tue Mar 14, 2006 5:15 am
Re: while loop trouble ?
oh well what i have an impulse to set the speed back to normal and one to sprint thats why i wanted to check if the player is sprinting or not cuz i cant let the player sprint forever 
- sniperz227
- Posts: 112
- Joined: Sat Apr 09, 2011 3:19 am
Re: while loop trouble ?
Ya even if you could do "while ("cl_forwardspeed 650")" that would be an infinite loop which would kill the game. Idk how that even got through compilation without error. All I can guess is it thinks you want to compare if the value of the string is non-zero. Which would also be an infinite loop. The design of this code is very flawed, to be honest. This function wouldn't return until the player stopped sprinting(if at all), meaning nothing else would get done during that time.
I think what you should do is add an entity field (but preferably a flag) that is set to true once the sprint button is pressed and then just change the cvar for cl_forwardspeed once that happens. Set up another entity field that indicates the player's energy. When the sprint button isn't pressed anymore or the energy of the player is depleted, set the field to false and return the cl_fowardspeed cvar to it's normal value.
Maybe something like this:
EDIT: This code doesn't account for if you hold the button down but don't actually try to move. lol
You should also add "&& (velocity_x > 0 || velocity_y > 0)" to "if (isSprinting)" in the function "sprint_update". This makes sure the player is moving forward/backwards or is strafing, and isn't in mid-air.
Also I wanted to point out that you shouldn't do things like:
This just instantly depletes the player's energy and also puts it far into the negatives depending on how fast the condition "self.sprint_time < 0" is met. It's not subtract by 5 per second or even subtract by 5 per frame. It's subtract by 5 per loop. Btw, that would be another infinite loop.
I think what you should do is add an entity field (but preferably a flag) that is set to true once the sprint button is pressed and then just change the cvar for cl_forwardspeed once that happens. Set up another entity field that indicates the player's energy. When the sprint button isn't pressed anymore or the energy of the player is depleted, set the field to false and return the cl_fowardspeed cvar to it's normal value.
Maybe something like this:
- Code: Select all
.float isSprinting;
.float sprintTime;
.float oldTime;
// call this when the sprint button is pressed down
void() sprint_start =
{
if (sprintTime > 0) // check if energy isn't already depleted
{
isSprinting = true;
sprintTime = sprintTime + time;
stuffcmd(self,"cl_forwardspeed 650");
}
}
// call this when the sprint button is released or energy is depleted
void() sprint_stop =
{
isSprinting = false;
sprintTime = sprintTime - time;
stuffcmd(self, "cl_fowardspeed 200");
}
// call this function every frame
void() sprint_update =
{
if (isSprinting)
{
if (time >= sprintTime)
sprint_stop();
}
else if (sprintTime < 5) // recharge sprint energy
{
sprintTime += time - oldTime; // increment by time between last frame and current frame.
// 1 second of sprinting per 1 second of recharging
if (sprintTime > 5) // force maximum of 5 seconds
sprintTime = 5;
}
oldTime = time;
}
EDIT: This code doesn't account for if you hold the button down but don't actually try to move. lol
You should also add "&& (velocity_x > 0 || velocity_y > 0)" to "if (isSprinting)" in the function "sprint_update". This makes sure the player is moving forward/backwards or is strafing, and isn't in mid-air.
Also I wanted to point out that you shouldn't do things like:
- Code: Select all
while (self.sprint_time < 0) // while sprint time is greater than 0 aka player is sprinting
{
self.energy = self.energy - 5; // take 5 out of self.energy
}
This just instantly depletes the player's energy and also puts it far into the negatives depending on how fast the condition "self.sprint_time < 0" is met. It's not subtract by 5 per second or even subtract by 5 per frame. It's subtract by 5 per loop. Btw, that would be another infinite loop.

-

DukeInstinct - Posts: 20
- Joined: Sat Jul 10, 2010 11:20 pm
- Location: DukeLand
Re: while loop trouble ?
I messed a long time with sprinting for my mod using the stuffcommands for the speed like that, but since darkplaces has a new physics QC file you can optionally activate, you can manage this alot easier in some ways.....so thats what I am doing now, but I was ' moderately' successful trying it with the stuff commands llike that. There is a tut here for footsteps sounds that I used as the main foundation, after all, it all ought to synchronize with the sounds in the end.
So in the playerpostthink() I had:
stuffspeed ();
playerfootstep ();
Things like making sure the player is on ground, in or out of water and I decided to give him some extra speed if he has the biosuit and in water, but that got trickier. There was other code that defined the .sprint_time but that was where the problem lied, as I was going to make that change depending on the type of character shosen and if he or she had a rune for example. vlen (self.velocity) is your most key float here
in that its a direct measurement you can look at and see those cl_speed values in realtime.
So in the playerpostthink() I had:
stuffspeed ();
playerfootstep ();
- Code: Select all
void () stuffspeed =
{
if (((self.watertype == CONTENT_WATER) || (self.watertype == CONTENT_SLIME)))
{
if ((self.velocity != puff_org))
{
if (((self.waterlevel > FIND_NEAREST) && !(self.items & IT_SUIT)))
{
stuffcmd (self, "-speed\n");
}
else
{
if (((self.waterlevel == FIND_NEAREST) && !(self.items & IT_SUIT)))
{
stuffcmd (self, "cl_forwardspeed 175\n");
stuffcmd (self, "cl_backspeed 175\n");
stuffcmd (self, "cl_sidespeed 150\n");
self.walkvalue = CONTENT_EMPTY;
}
else
{
if ((self.items & IT_SUIT))
{
stuffcmd (self, "cl_forwardspeed 295\n");
stuffcmd (self, "cl_backspeed 295\n");
stuffcmd (self, "cl_sidespeed 270\n");
self.runvalue = CONTENT_EMPTY;
}
}
}
}
}
if (((self.runvalue == CONTENT_EMPTY) || (self.walkvalue == CONTENT_EMPTY)))
{
if (((!self.waterlevel && checkbottom (self)) && (self.velocity != puff_org)))
{
stuffcmd (self, "cl_forwardspeed 200\n");
stuffcmd (self, "cl_backspeed 200\n");
stuffcmd (self, "cl_sidespeed 175\n");
}
}
};
void () playerfootstep =
{
local float amp;
local float s;
if ((self.deadflag || (self.classname != "player")))
{
return;
}
if (!(self.flags & FL_ONGROUND))
{
return;
}
if (((time < self.nextfootstep) || (time < self.attack_finished)))
{
return;
}
if (((!self.waterlevel && checkbottom (self)) && (self.velocity != puff_org)))
{
if ((vlen (self.velocity) < 300))
{
amp = CAM_IDLE;
self.nextfootstep = (time + 0.3);
if (((self.runtime > self.sprint_finished) && (self.walktime == CONTENT_EMPTY)))
{
self.sprint_finished = ((time + (self.runtime - self.sprint_finished)) - FIND_NEAREST);
if (((self.runtime - self.sprint_finished) >= fAutoBotNextThink))
{
self.sprint_finished = fAutoBotNextThink;
stuffcmd (self, "bind shift \"+speed\"\n");
}
}
self.walkvalue = vlen (self.velocity);
if (((vlen (self.velocity) < MSG_UPDATENAME) && (self.velocity != puff_org)))
{
if ((vlen (self.velocity) < CAM_FOLLOW))
{
self.nextfootstep = (time + 0.6);
}
else
{
self.nextfootstep = (time + (vlen (self.velocity) / 9.5));
}
s = CONTENT_EMPTY;
}
}
if ((vlen (self.velocity) > 300))
{
amp = DO_ADD;
if (((self.runvalue == action) && (self.walktime != CONTENT_EMPTY)))
{
self.sprint_finished = (time + fAutoBotNextThink);
self.runtime = (self.sprint_finished + fAutoBotNextThink);
}
self.nextfootstep = (time + 0.15);
self.runvalue = vlen (self.velocity);
updatebreath ();
}
if ((s != CONTENT_EMPTY))
{
s = (random () * DO_ADD);
if ((s < FIND_NEAREST))
{
sound (self, CHAN_BODY, "boot1.wav", LMQUOTA_ARMOR, amp);
}
else
{
if ((s < FIND_FURTHEST))
{
sound (self, CHAN_DEV, "boot2.wav", LMQUOTA_ARMOR, amp);
}
else
{
if ((s < CAM_IDLE))
{
sound (self, CHAN_DEV, "boot3.wav", LMQUOTA_ARMOR, amp);
}
else
{
sound (self, CHAN_DEV, "boot4.wav", LMQUOTA_ARMOR, amp);
}
}
}
}
else
{
sound (self, CHAN_AUTO, "slip.wav", LMQUOTA_ARMOR, amp);
}
}
else
{
if (((!self.waterlevel && checkbottom (self)) && (self.velocity == puff_org)))
{
if ((self.runvalue || self.walkvalue))
{
sound (self, CHAN_AUTO, "breath2f.wav", FIND_NEAREST, ATTN_IDLE);
}
self.walkvalue = action;
self.runvalue = action;
}
}
};
Things like making sure the player is on ground, in or out of water and I decided to give him some extra speed if he has the biosuit and in water, but that got trickier. There was other code that defined the .sprint_time but that was where the problem lied, as I was going to make that change depending on the type of character shosen and if he or she had a rune for example. vlen (self.velocity) is your most key float here
in that its a direct measurement you can look at and see those cl_speed values in realtime.
-

Cobalt - Posts: 445
- Joined: Wed Jun 10, 2009 2:58 am
- Location: New England, USA
Re: while loop trouble ?
Also of note, I happen to be experimenting with my bots angles, setting their v_angle ....and I happen to notice if you change it incrementally slowly as they move, but not exceeding 45 degrees up or down, it adds a more real looking effect to the model, as if its really taking steps walking and running. I bet if you set it to lean forward a little while running / sprinting it would be a sweet tweak....I'll have to try it someday. But heres the code I messed with:
This is for when its moving to a goal, I was trying to have it keep looking in the direction of the goal as much as possible, but on one of the larger maps that are pretty much flat, and all the goal entities are on the same Z, it did a nice job of making the player look like its running.
- Code: Select all
if ((self.goalentity != self && self.goalentity != world))
{
if (!EntityInFieldOfView (self.goalentity) && self.bot_action != BOT_FIGHTING)
{
if (self.goalentity.origin_z + self.view_ofs_z > self.origin_z + self.view_ofs_z )
self.v_angle_x = (self.v_angle_x + (random () * 0.07));
if (self.goalentity.origin_z + self.view_ofs_z < self.origin_z + self.view_ofs_z )
self.v_angle_x = (self.v_angle_x - (random () * 0.07));
if (self.v_angle_x > 45 )
self.v_angle_x = 45;
if (self.v_angle_x < -45 )
self.v_angle_x = -45;
This is for when its moving to a goal, I was trying to have it keep looking in the direction of the goal as much as possible, but on one of the larger maps that are pretty much flat, and all the goal entities are on the same Z, it did a nice job of making the player look like its running.
-

Cobalt - Posts: 445
- Joined: Wed Jun 10, 2009 2:58 am
- Location: New England, USA
6 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 1 guest