Quake Style - Quake 2 Tutorials
Tech Power Up Mayhem - TPUM - Part 4
The Switch Rune
|
The Switch Rune:
Honorary mention goes to CyberSlash of Psychosoft who set me on the right path re this rune and of whose mods I used a couple of lines. That rune has some possibilities not coded here and can easily be expanded, but you have to think about what you want. So what is it anyway?
As implemented here, this rune is for the pro's. If you own it, you can switch places with your enemy once you hit the key bound to "userune". What to do with this? You're kidding! Hop into the lava, get your target and switch places. A guy infront of you sending over a few rockets? Ahem, switch places and he'll be taken out by his own rockets! Now don't say "Nah I don't believe it" because those are things which actually happen when we play our mod. So this is for guys who are really good and cool enough to handle this in heavy combat.
Requirements:
The stuff we did in the previous parts of "Tech Power Up Mayhem". This series of tutorials builds up step-by-step and you must have done any previous pages before adding this one!
Add in the blue code and take out the pink code. Regular yellow code is Zoid's original one.
As we will add rune code more than once during these tuts, it can't hurt to have a file where you can put all the runes which do not deserve a special category. So please add a new file g_runes.c to your source code and include the following:
#include "g_local.h"
#include "g_runes.h"
// PLACE SWITCH RUNE
void Rune_PreparePlaceSwitch (edict_t *ent)
{
vec3_t start;
vec3_t forward;
vec3_t end;
trace_t tr;
edict_t *target;
VectorCopy(ent->s.origin, start);
start[2] += ent->viewheight;
AngleVectors(ent->client->v_angle, forward, NULL, NULL);
VectorMA(start, 1000, forward, end);
tr = gi.trace(start, NULL, NULL, end, ent, MASK_SHOT);
if ( (tr.ent && tr.ent->client) || (tr.ent && tr.ent->svflags & SVF_MONSTER)) // place switch!
{
gi.sound (ent, CHAN_WEAPON, gi.soundindex("runes/switch_hit.wav"), 1, ATTN_NORM, 0);
target = tr.ent;
Rune_PlaceSwitch (ent, target);
SpawnDamage (TE_SHIELD_SPARKS, tr.ent->s.origin, tr.ent->s.origin, 100);
}
else
{
// missed!
if (!((tr.surface) && (tr.surface->flags & SURF_SKY)))
{
gi.sound (ent, CHAN_WEAPON, gi.soundindex("runes/switch_miss.wav"), 1, ATTN_NORM, 0);
}
}
}
void Rune_PlaceSwitch (edict_t *ent, edict_t *targ)
{
vec3_t temp;
VectorCopy(ent->s.origin, temp);
VectorCopy(targ->s.origin, ent->s.origin);
VectorCopy(temp, targ->s.origin);
ent->s.origin[2] += ent->mins[2] - targ->mins[2] + 2;
targ->s.origin[2] += targ->mins[2] - ent->mins[2] + 2;
M_droptofloor(targ);
ent->client->bonus_alpha = 0.5;
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (ent-g_edicts);
gi.WriteByte (MZ_LOGOUT);
gi.multicast (ent->s.origin, MULTICAST_PVS);
ent->client->ps.pmove.pm_flags = PMF_TIME_TELEPORT;
ent->client->ps.pmove.pm_time = 14;
}
In your new file g_runes.h, add the following:
void Rune_PlaceSwitch (edict_t *ent, edict_t *targ);
void Rune_PreparePlaceSwitch (edict_t *ent);
With these additions, we have everything that is needed to do the switch. We yet have to make the game take notice of usage and can do this by adding this to in g_ctf.c:
void Rune_Use(edict_t *ent)
{
int index;
gitem_t *it;
char *rune_msg;
// say "no rune or automatically activated rune" if there is no
// special usage (=pressing a button) needed or if player
// doesn't own a rune
// otherwise just call the using function for that specific rune
rune_msg="No rune or automatically activated rune";
it = FindItem ("Defense Laser [U]");
index = ITEM_INDEX (it);
if (ent->client->pers.inventory[index]) {
PlaceLaser (ent);
return;
}
it = FindItem ("Place Switch Rune [U]");
index = ITEM_INDEX (it);
if (ent->client->pers.inventory[index]) {
Rune_PreparePlaceSwitch (ent);
return;
}
gi.centerprintf(ent, "%s\n",rune_msg);
}
Also in g_ctf.c, (you'll get used to this soon) replace this:
static char *tnames[] = {
"item_tech1", "item_tech2", "item_tech3", "item_tech4", "item_tech5",
NULL
};
with this:
static char *tnames[] = {
"item_tech1","item_tech2","item_tech3","item_tech4","item_tech5","item_tech6",
NULL
};
Last step in g_ctf.c takes place at the top - just below the g_local.h-include-statement add this line:
#include "g_runes.h"
Next we need to add the item itself in g_items.c. Add this to your item structure, the same way as you did with the defense laser in part three of our tutorial:
/* Place Switch Rune
by pressing the rune key, you can switch places with
the player who's in your target
*/
{
"item_tech6",
CTFPickup_Tech,
NULL,
CTFDrop_Tech, //Should this be null if we don't want players to drop it manually?
NULL,
"items/pkup.wav",
"models/ctf/regeneration/tris.md2", EF_ROTATE,
NULL,
"tech3",
"Place Switch Rune",
2,
0,
NULL,
IT_TECH,
// 0, // NOTE: activate/deactivate this line to set up for different source bases (CTF or 3.20)
NULL,
0,
"runes/switch_hit.wav runes/switch_miss.wav"
},
// end of list marker
{NULL}
};
Important note: Depending on which source base you use, you may need to include the line above ("NOTE: activate/deactivate...") to make your compilation work without warnings. If you use the CTF source as used in our tut, you can leave it like above; if you added the CTF functionality to the 3.20 source yourself, you need to include this line in your source.
That's it! Compile, try! Be sure to bind a key to "drop tech" (to throw away a rune if you want pick up a new one) and to "userune" (to use a rune like the one we just added). Now you can switch places with your enemy by pressing the bound key... if you're a good player, you should have tons of fun with this one.
Thoughts and ideas about extending this rune:
Of course, with a few modifications to the tutorial above, you can give this rune a whole different appeal, giving it some sense also for players who are not tricky enough of doing the nasty things we explained at the top of this page: It's easy not only to switch places, but also to switch health, weapons and ammo. Imagine yourself, with that rune, but down to 15 health, just ran out of ammo, no armor and generally feeling like something the cat dragged in. And imagine that camper above you who just picked up the mega health and is throwing down grenades like there is no tomorrow. Now comes your shining hour: Switch places and also health, ammo, etc. That will be devastating to that camper - even before you frag him with his own weapons!
Nick back to the tutorials page and have a look at the next tutorial in the sequence.
-- Credits:
Tutorial by peter
Return to QS Tutorials
-- Important:
If you do use something from QuakeStyle in your mod, please give us credit.
Our code is copyrighted, but we give permission to everyone to use it in any way they see fit, as long as we are recognized.