View previous topic :: View next topic |
Author |
Message |
catalyst
Joined: 17 Feb 2009 Posts: 26
|
Posted: Tue Feb 17, 2009 12:17 pm Post subject: Quake-C question - make player slower |
|
|
Hai,
I haven't found a tutorial nor a forums thread on this so I'm posting...
I'm working on my Quake 1 mod. I've been working on it for a long time and always encountered problems with Quake-C and can never get enough info online (there's so little support for this language these days).
What I'm trying to do right now is to make a player who has the super nail gun in his inventory, run slower than he would without the gun. Any ideas where and what exactly I should write in the qc files?
Thanks in advance for any efforts. |
|
Back to top |
|
 |
Spike
Joined: 05 Nov 2004 Posts: 944 Location: UK
|
Posted: Tue Feb 17, 2009 2:03 pm Post subject: |
|
|
Make it a quakeworld mod.
.float maxspeed;
void(float mul) setmaxspeedmultiplier =
{
if (!mul)
mul = 1;
self.maxspeed = mul*cvar("sv_maxspeed");
};
Prediction etc will be fine as soon as the client receives the update the server will generate. So please don't smooth it out it in the QC or you'll prolong the prediction misses.
Alternatively in non-qw engines, stick the following in PlayerPreThink:
if (vlen(self.velocity) > MAXSPEED)
self.velocity = normalize(self.velocity)*MAXSPEED;
This will cap their speed. But it'll also break rocket jumps/bunnyhops so might not be what you want.
Or that might be meant for PlayerPostThink.. I don't remember now.
Alternatively you can stuffcmd new cl_forwardspeed values (and friends) periodically. Or if strictly singleplayer only, change the sv_maxspeed cvar via localcmds. _________________ What's a signature? |
|
Back to top |
|
 |
catalyst
Joined: 17 Feb 2009 Posts: 26
|
Posted: Tue Feb 17, 2009 5:43 pm Post subject: |
|
|
I want my mod to be compatible with as many engines as possible so I'll stick to the standard one (and it will be single and multiplayer). I'd rather give up doing this thing if I knew it would work only on one engine :)
OK, so what is MAXSPEED? I don't see it defined anywhere in client.qc. Should I define it myself in defs.qc? |
|
Back to top |
|
 |
Wazat
Joined: 15 Oct 2004 Posts: 732 Location: Middle 'o the desert, USA
|
Posted: Tue Feb 17, 2009 6:58 pm Post subject: |
|
|
Here's a more complex but perhaps more effective method that doesn't necessarily hose rocket jumpers:
In PlayerPreThink before this code:
Code: |
if (self.button2)
{
PlayerJump ();
}
|
Add this:
Code: |
float oldZ;
oldZ = self.velocity_z;
self.velocity_z = 0;
if(vlen(self.velocity) > MAXSPEED) {
self.velocity = normalize(self.velocity)*MAXSPEED;
}
self.velocity_z = oldZ;
|
I haven't tested this so it may require tweaking and adjustment. The basic idea is you only restrict the player's horizontal movement so that rocket jumps still give proper lift. MAXSPEED can be replaced with anything including custom values you set for the player like self.speed etc.
Note that reducing the player speed in QC like this will probably create some headaches in terms of client-side prediction. It's a very good idea to combine this method with stuffcmds to set cl_forwardspeed and friends so that the client prediction speed matches your QC cap.
To allow horizontal rocket jump speed, wind tunnels, etc to work properly, you've got to get more creative. You should only cap their speed on the ground, but then how do you prevent crazy bunnyhopping abuse? *groan*
I believe Darkplaces and other engines provide a callback function you can write to intercept player movement input and provide your own velocity. This would presumably give you absolute control, but it's not as global among engines as you appear to want.
A second option is to allow unrestricted speeds in air, but to cut them off as soon as they hit the ground. The code above might then look like this:
Code: |
float oldZ;
oldZ = self.velocity_z;
self.velocity_z = 0;
if(self.flags & FL_ONGROUND && vlen(self.velocity) > MAXSPEED) {
self.velocity = normalize(self.velocity)*MAXSPEED;
}
if(self.flags & FL_ONGROUND && !self.wasOnGround) {
// anything special you want to do when they land goes here
self.wasOnGround = TRUE;
self.velocity = self.velocity * 0.3; // slow them down when they land
}
else if(!self.flags & FL_ONGROUND && self.wasOnGround) {
// anything special you want do do when they
// leave the ground for any reason goes here
self.wasOnGround = FALSE;
}
self.velocity_z = oldZ;
|
(you will create .wasOnGround in defs.qc of course)
This is a method I've seen used in a number of other games to prohibit bunnyhopping. Whenever the player lands, he loses some velocity and has to ration jumps and landings, etc. Since slowing the player only on the ground will allow insane bunnyhopping abuse it may be a very good idea to use this method. It can be annoying for the player, however, and some terrain may prove prohibitive. Depends.
I suspect that periodic stuffcmds combined with one of the QC caps above will cover most of the issues. _________________ When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work. |
|
Back to top |
|
 |
catalyst
Joined: 17 Feb 2009 Posts: 26
|
Posted: Tue Feb 17, 2009 10:06 pm Post subject: |
|
|
woh! now that was confusing! :P no, i dont want any rocket jumps. this is gonna be realistic so any explosion is an instant death to anyone around. although you made me concerned about ordinary jumps and free falls. the player might have a different speed when jumping/falling than when on ground. hmmmm...
so, what's the easiest way to make it work? the first piece of code you posted? |
|
Back to top |
|
 |
Wazat
Joined: 15 Oct 2004 Posts: 732 Location: Middle 'o the desert, USA
|
Posted: Tue Feb 17, 2009 10:38 pm Post subject: |
|
|
My second chunk of code will probably be the most accurate and give you want you want: players are able to move fast in air if propelled by a wind tunnel etc, but they cannot reach incredible speeds by hopping constantly so they're always in the air.
If air movement is not a big deal to you, then my first chunk (or Spike's) will do fine. _________________ When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work. |
|
Back to top |
|
 |
catalyst
Joined: 17 Feb 2009 Posts: 26
|
Posted: Wed Feb 18, 2009 8:07 am Post subject: |
|
|
kshh, kshh, got it. it's working! :D now, how do i check if the player has super nailgun?
Code: |
if (self.flags == IT_SUPER_NAILGUN) {
//do all the "slowering"
}
|
??
it's not gonna work, is it?
...and i also want to change their speed when they are firing the super nailgun (make them run even sloooooweeeeer :)) |
|
Back to top |
|
 |
r00k
Joined: 13 Nov 2004 Posts: 483
|
Posted: Wed Feb 18, 2009 11:14 am Post subject: |
|
|
Try this in PlayerPreThink before the call the makevectors...
Code: |
if (((self.flags) & FL_ONGROUND) && (self.items & IT_SUPER_NAILGUN))
{
self.velocity_x = (1 - 2.7 * frametime) * (self.velocity_x);
self.velocity_y = (1 - 2.7 * frametime) * (self.velocity_y);
}
|
|
|
Back to top |
|
 |
catalyst
Joined: 17 Feb 2009 Posts: 26
|
Posted: Wed Feb 18, 2009 1:03 pm Post subject: |
|
|
r00k wrote: | Try this in PlayerPreThink before the call the makevectors...
|
I only used the (self.items & IT_SUPER_NAILGUN) for now. I'm not sure what the rest of the code does. What is frametime? |
|
Back to top |
|
 |
MeTcHsteekle
Joined: 15 May 2008 Posts: 397 Location: its a secret
|
Posted: Wed Feb 18, 2009 1:16 pm Post subject: |
|
|
well, the (((self.flags) & FL_ONGROUND) is a on ground check to see id fthe player is on the ground before the slowerizing happens _________________ bah |
|
Back to top |
|
 |
catalyst
Joined: 17 Feb 2009 Posts: 26
|
Posted: Wed Feb 18, 2009 1:18 pm Post subject: |
|
|
ok, I copied wazat's code again and used the condition
if ( (self.weapon == IT_SUPER_NAILGUN) && self.button0)
to make the player run even slower when they fire the super nailgun. how can I now make them not jump as high? |
|
Back to top |
|
 |
MeTcHsteekle
Joined: 15 May 2008 Posts: 397 Location: its a secret
|
Posted: Wed Feb 18, 2009 1:40 pm Post subject: |
|
|
this might be of slight use to you: http://www.angelfire.com/ult/td/tuts.html#jump
just like instead of adding the health, just make the call like
if (self.items = self.items & IT_SUPER_NAILGUN)
{
......
or something, don't use my code as example i think i messed up [tutorial s not mine, i think it belongs to a guy who calls himself Root?] _________________ bah |
|
Back to top |
|
 |
catalyst
Joined: 17 Feb 2009 Posts: 26
|
Posted: Wed Feb 18, 2009 2:24 pm Post subject: |
|
|
THX!!! good tutorial, indeed :D
this is the code i made to make the player jump lower:
Code: |
if(self.items & IT_SUPER_NAILGUN) { //if has super nailgun
self.velocity_z = self.velocity_z + 150; //low jump
}
else self.velocity_z = self.velocity_z + 270; //normal jump
|
|
|
Back to top |
|
 |
catalyst
Joined: 17 Feb 2009 Posts: 26
|
|
Back to top |
|
 |
xaGe

Joined: 01 Mar 2006 Posts: 329 Location: Upstate, New York
|
Posted: Thu Feb 19, 2009 3:34 am Post subject: |
|
|
This and at least one other thread I see really should be in the QuakeC Programming forum no? |
|
Back to top |
|
 |
|