Jump pad Tutorial
Created By: coffee
eMail: coffee@planetquake.com
Homepage: AI Cafe
Difficulty Scale: Easy

My name is coffee, and I suffer from Quake 3 envy.

Hello, and welcome to another meeting of QA (Quakeaholics Anonymous), the support group for all your first-person fetishes. It's true that I'd love to play Q3A, but my PC just can't run it. My computer still uses punch cards as its storage medium.

Until I can afford one built after 1980, I'm left with my jealous thoughts and fantasies of id's bot arena game. And so, many of the ideas I have to improve Quake 1 are influenced by this mentality.

For instance, we have this tutorial. The concept of jump pads was obviously shaped by Q3A's bounce pads. Despite this, I find them a fun and fresh feature for our beloved classic Quake.

You may or may not find a use for these things. It may sound as though jump pads should be designed into a map itself. However, we will able to spawn them anywhere in any level. This will certainly put a twist in your favorite maps.

Jump pads could be created in a few different ways. We will spawn them as entities. These entities will have a touch function, but they will not possess any special physics, as a bounce pad does. In a nutshell, when its touch function is triggered, the entity will tell the game that the player is able to jump high.

For this to work, we will require one new float variable and three new routines. First step open up defs.qc, and insert this at the very bottom:

.float jump_time;

That is our new variable. If a player's jump time is enable, he will be able to leap twice as high as normal. Close that file. Open items.qc and go to the bottom. There we will add our new creation routine:

// ---------------------------
void() create_jumppad =
// ---------------------------
local entity pad;

	pad = spawn();
	pad.classname = "item_jumppad";
	pad.think = item_jumppad;
	pad.nextthink = time + 0.1;


We've all seen entity spawning routines. But this one looks different, doesn't it? It's kind of, um, incomplete. That's for a reason. It will be explained in due time. For now, just note that we didn't give this new entity a model, a size, or anything; we merely gave it a subroutine to think. Let us write that routine now. Add the following above the previous:

// ---------------------------
void() item_jumppad =
// ---------------------------

	setmodel(self, "progs/h_player.mdl");
	setorigin(self, self.origin);
	self.solid = SOLID_TRIGGER;
	self.touch = jumppad_touch;


Okay, that is a little more specific. Our entity takes shape. We set a touch function. On the last line, we call one of id's routines; this merely puts an item into the map and drops it onto the floor. No need for us to write that code again, right?

You will note that our jump pad will look like, um, a severed head. This of course is rather unfortunate. But I am not a modeler, and there is no other model in the Quake packs that would look anything like a pad. And so, I guess if your going to utilize this tutorial, you'll have to find another model.

Now of course we must create the touch routine. So, add the following above the previous:

// ---------------------------
void() jumppad_touch =
// ---------------------------

	if (other.classname != "player" && other.classname != "bot")

	other.jump_time = time + 1;


Damn I love short subroutines! I know you're thinking there's got to be more to our jump pad, but that's it. The entity itself is done. Let me explain that little nugget of code. Firstly, if anything but a player or bot touches the pad, we leave the routine (they are the only ones allowed to use it). Secondly, we mark the guy's jump time as one second from now, which means it will be active for one second. Note that if the guy continues to stand on the pad, his jump time will remain active, because he's still touching the entity. A second after he steps off the pad, his jump time expires, and he's back to normal jumping.

Next comes the jumping part. It will be just as simple as that. Go into client.qc and scroll down to the sub PlayerJump(), to the last line, where you will see this code:

	self.velocity_z = self.velocity_z + 270;

I bet you can guess that we'll be changing that. Remember, when the player's jump time is active we want him to jump twice as high as normal. Thus, we wish to change those lines into these:

	if (time < self.jump_time)
		self.velocity_z = self.velocity_z + 540;
		else self.velocity_z = self.velocity_z + 270;

There is is, man. That works, believe me. If you stand on one of these beauties, you can now pull off a super jump. And if you want the leap to be more than double high, just increase that first value.

Moving right along. Our new entity work, and our player can jump high. We just need to get the jump pad into the map. There will be two ways of doing this: with a player impulse, and when the map loads. We'll learn both, but the choice will lay with you. I ask you now to open weapons.qc and slip down to ImpulseCommands(). Inside that routine somewhere, add this code:

	if (self.impulse == 175)

I picked 175 arbitrarily; you can change it, just make sure it doesn't match another one of your impulses. Anyway, if you type impulse 175 into the console, a jump pad will be spawned and will fall to the floor. Then if you hit your jump button, you'll catch air like Jordan. Don't believe me? Try it and see, pallie.

Mainly for map designers, the second way is to put an entity named "item_jumppad" into a level wherever you want one. Remember, the speling has to be exact. This custom entity will then call the routine named item_jumppad(). If you look closely at that routine, you'll see that it is a spawn routine -- one that gives birth to a map entity. You'll see that it doesn't spawn a new thing (we used another routine for that). The "self" in that sub is either the entity on the map, or the entity we created with an impulse. I told you I would explain why we did it that way.

There you go. Jump pads can be entertaining and useful: you can put them in locations that will help you leap to a special weapon or power-up. I like them. Of course, I'm just a weak Quakeaholic with a chronic Q3A defficiency. Can I have a hug now?