Forum

Quake-C question - make player slower

Discuss anything not covered by any of the other categories.

Moderator: InsideQC Admins

Quake-C question - make player slower

Postby catalyst » Tue Feb 17, 2009 12:17 pm

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.
catalyst
 
Posts: 26
Joined: Tue Feb 17, 2009 12:06 pm

Postby Spike » Tue Feb 17, 2009 2:03 pm

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.
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby catalyst » Tue Feb 17, 2009 5:43 pm

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?
catalyst
 
Posts: 26
Joined: Tue Feb 17, 2009 12:06 pm

Postby Wazat » Tue Feb 17, 2009 6:58 pm

Here's a more complex but perhaps more effective method that doesn't necessarily hose rocket jumpers:

In PlayerPreThink before this code:
Code: Select all
   if (self.button2)
   {
      PlayerJump ();
   }


Add this:

Code: Select all
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: Select all
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.
Wazat
 
Posts: 771
Joined: Fri Oct 15, 2004 9:50 pm
Location: Middle 'o the desert, USA

Postby catalyst » Tue Feb 17, 2009 10:06 pm

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?
catalyst
 
Posts: 26
Joined: Tue Feb 17, 2009 12:06 pm

Postby Wazat » Tue Feb 17, 2009 10:38 pm

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.
Wazat
 
Posts: 771
Joined: Fri Oct 15, 2004 9:50 pm
Location: Middle 'o the desert, USA

Postby catalyst » Wed Feb 18, 2009 8:07 am

kshh, kshh, got it. it's working! :D now, how do i check if the player has super nailgun?

Code: Select all
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 :))
catalyst
 
Posts: 26
Joined: Tue Feb 17, 2009 12:06 pm

Postby r00k » Wed Feb 18, 2009 11:14 am

Try this in PlayerPreThink before the call the makevectors...

Code: Select all
      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);
      }
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Postby catalyst » Wed Feb 18, 2009 1:03 pm

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?
catalyst
 
Posts: 26
Joined: Tue Feb 17, 2009 12:06 pm

Postby MeTcHsteekle » Wed Feb 18, 2009 1:16 pm

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
MeTcHsteekle
 
Posts: 399
Joined: Thu May 15, 2008 10:46 pm
Location: its a secret

Postby catalyst » Wed Feb 18, 2009 1:18 pm

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?
catalyst
 
Posts: 26
Joined: Tue Feb 17, 2009 12:06 pm

Postby MeTcHsteekle » Wed Feb 18, 2009 1:40 pm

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
MeTcHsteekle
 
Posts: 399
Joined: Thu May 15, 2008 10:46 pm
Location: its a secret

Postby catalyst » Wed Feb 18, 2009 2:24 pm

THX!!! good tutorial, indeed :D

this is the code i made to make the player jump lower:

Code: Select all
   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
catalyst
 
Posts: 26
Joined: Tue Feb 17, 2009 12:06 pm

Postby catalyst » Wed Feb 18, 2009 10:08 pm

hi, i have some more concernes but since they are not related to slow running anymore i started a new thread

viewtopic.php?p=15284#15284

big thanks for any help :)
catalyst
 
Posts: 26
Joined: Tue Feb 17, 2009 12:06 pm

Postby xaGe » Thu Feb 19, 2009 3:34 am

This and at least one other thread I see really should be in the QuakeC Programming forum no?
User avatar
xaGe
 
Posts: 461
Joined: Wed Mar 01, 2006 8:29 am
Location: Upstate, New York

Next

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest