|
|
Step 1
This section covers something not used in any tutorials so far - how to
call up and use specific frames from .mdl files. It's not at all
difficult, you just need to learn a bit of new syntax and you're away.
Step 1
Open up *soldier.qc* and scroll down to the army_pain() function. Edit
it to look like this:
//This function is called every time a soldier is hurt.
void(entity attacker, float damage) army_pain =
{
local float r;
//This checks if the soldier's still hurting from something else.
if (self.pain_finished > time)
return;
r = random();//For choosing a random pain sequence.
if (r < 0.2)
{
self.pain_finished = time + 0.6;
army_pain1 ();
sound (self, CHAN_VOICE, "soldier/pain1.html", 1, ATTN_NORM);
}
else if (r < 0.45)//Changed this slightly
{
self.pain_finished = time + 1.1;
army_painb1 ();
sound (self, CHAN_VOICE, "soldier/pain2.html", 1, ATTN_NORM);
}
//Added the next else if:
else if (r < 0.75) //Our pain sequence occurs a fraction of the time
{
self.pain_finished = time + 2.0;//Time enough for 20 frames.
army_paind1 ();//This is the new pain function we'll be writing
sound (self, CHAN_VOICE, "soldier/pain2.html", 1, ATTN_NORM);
}
else
{
self.pain_finished = time + 1.1;
army_painc1 ();
sound (self, CHAN_VOICE, "soldier/pain2.html", 1, ATTN_NORM);
}
};
Step 2
Now we create the animation. Put the following lines into *soldier.qc*
just above army_pain() and just below the army_painc*() functions
(where * is one in a sequence of numbers):
void() army_paind1 =[ $death1, army_paind2 ] {};//Here the soldier
void() army_paind2 =[ $death2, army_paind3 ] {};//decides that
void() army_paind3 =[ $death3, army_paind4 ] {};//he's an India
void() army_paind4 =[ $death4, army_paind5 ] {};//rubber ball.
void() army_paind5 =[ $death5, army_paind6 ] {};
void() army_paind6 =[ $death6, army_paind7 ] {};
void() army_paind7 =[ $death5, army_paind8 ] {};
void() army_paind8 =[ $death4, army_paind9 ] {};
void() army_paind9 =[ $death3, army_paind10] {};
void() army_paind10=[ $death2, army_paind11] {};
void() army_paind11=[ $death1, army_paind12] {};
void() army_paind12=[ $painc1, army_paind13] {};//Here, he decides
void() army_paind13=[ $painc2, army_paind14] {};//it wasn't such
void() army_paind14=[ $painc3, army_paind15] {};//a good idea ;)
void() army_paind15=[ $painc4, army_paind16] {};
void() army_paind16=[ $painc5, army_paind17] {};
void() army_paind17=[ $painc4, army_paind18] {};
void() army_paind18=[ $painc3, army_paind19] {};
void() army_paind19=[ $painc2, army_paind20] {};
void() army_paind20=[ $painc1, army_run1] {}; //Soldier gets on
//with life.
Step 3
Now, you've created the "India Soldier Rubber Ball" patch. Now, how many of you can open up another .qc file, and
manage to add new frames for, say the ogre? So i thought. Read on, and you'll (hopefully) understand)
Let me explain the syntax above - the square brackets before a function definition:
name =[framenum, nexttime, nextthink] {code};
Expands to:
name ()
{
self.frame=framenum;
self.nextthink = time + nexttime;
self.think = nextthink
}; //This text copyright Id Software. (don't wanna get in trouble!)
Step 4
Think I worked that out myself? Well, sorta, but it's right there at
the top of monsters.qc ripe for exploiting. In addition to what I've done
above, you could add in some extra effects during the pain sequence -
you'll need to add them in in the code section {} at the end of each line.
You could create your own sound effects and play them there, or have the
soldier fly about a bit. Whatever you like, now you know how!
Another thing to note is that if you have created NEW animation frames
(with qME or QMET for example) then you need to make sure that at the
top of whichever file you're editing (e.g zombie.qc if you edited the
zombie.mdl file, or dragon.qc if you created your own dragon entity
- damn that Id for removing it!!) these lines are included:
$cd id1/models/THEMODEL.mdl //Where the relevant .mdl file is
$origin 0 -6 24 //The centre of the model's bounding box
$base base //Umm...?
$skin skin //Which skin from the .mdl file to use?
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
$frame death1 death2 death3 death4 death5 death6 death7 death8
$frame death9 death10
$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
$frame deathc9 deathc10 deathc11
Step 5
The three example sequences are each animation sequences. If you create
a whole new animation sequence (e.g. karate-kick) then you need to
create a list like these, with all the frames of the sequence in the
right order. Then, you can increment the entity's frame member like
this:
entity.frame = entity.frame + 1;
...and it'll just change to the next frame in the sequence.
Well, that's about it. If you really want to learn QC, these tutorials
are great, but I'd definitely recommend just reading through the
original QC files from the game. They're easy to follow, for three
reasons; first QuakeC is simple compared to ANSI C; second the variables
and functions have names you'll recognise; three...you all play Quake
too much, so you're bound to recognise what all the functions actually
do in the game.
If you have any questions or any ideas you don't quite know how to
implement, drop me a line.
|