
|
Created By: |
Kryten |
|
eMail: |
|
|
Difficulty Scale: |
Easy |
Here is a nice self teleporter for Quake2. It works best
in deathmatch, but can also be used in SP. But beware in some cases in SP you
could end up teleporting to a worse place then where you started! This
teleporter teleports you to a random deathmatch spot. It is set up so with a
little work you could make it use the "mark/recall" system, but that
code is not provided.
First open the p_client.c and go to about line 106, there you should see these
lines in the info_player_deathmatch:
if (!deathmatch->value) { G_FreeEdict (self); return; } SP_misc_teleporter_dest (self);
Now
delete everything and add this:
if (deathmatch->value) SP_misc_teleporter_dest (self);
That
will force Quake2 to keep the deathmatch spots in SP and not delete them. The
deathmatch spots are required if the self teleporter will work in single
player.
When you spawn into Quake2 you will have 5 teleporters, every time you start a
new level or die this number will be reset. To do this go to the bottom of
PutClientInServer and add this line:
client->pers.inventory[ITEM_INDEX(FindItem("Self Teleporter"))] = 5;
Ok
you are now done with the p_client.c file. Now move onto the g_items.c file. At
the about line 33 you want to add:
void Use_Teleporter (edict_t *ent, gitem_t *item);
Now
go down until you get to the gitem_t itemlist[]. Right after these lines:
// // POWERUP ITEMS //
Add
this:
/*QUAKED item_tele
*/
{ "item_tele", NULL, Use_Teleporter, NULL, NULL, "items/pkup.wav", NULL, 0, NULL, "p_tele", "Self Teleporter", 0, 1, NULL, IT_POWERUP, 0, NULL, 0, "" },
Now I
am not going to lie to you. I don't really know what half that stuff does. I
have all that I need here. Some of the NULL's keep the item from being placed
in a map or dropped. The "p_tele" refers to the icon to use in the
HUD, I have provided this and you do need it so it can be selected in the
inventory. Now go all the way to the bottom of this file, there we will add the
code to teleport the player. Start by adding this at the bottom:
/*
=================================================================================
Personal Teleporter tutorial
=================================================================================
*/
edict_t *SelectRandomDeathmatchSpawnPoint (void);
void teleport_me (edict_t *ent, edict_t *dest){int i;
// unlink to make sure player can't possibly interfere with KillBox gi.unlinkentity (ent); // draw the teleport splash at dest gi.WriteByte (svc_temp_entity); // this is a really cool teleporter effect.
gi.WriteByte (TE_BOSSTPORT); // since we are moving the player
gi.WritePosition (ent->s.origin); // we cant use the other way to
gi.multicast (ent->s.origin, MULTICAST_PVS) // write the teleporter splash,
dest->s.event = EV_PLAYER_TELEPORT; // but we can at the dest
//move the player VectorCopy (dest->s.origin, ent->s.origin); VectorCopy (dest->s.origin, ent->s.old_origin); ent->s.origin[2] += 10; // clear the velocity and hold them in place briefly VectorClear (ent->velocity);ent->client->ps.pmove.pm_time = 160>>3; // hold time
ent->client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT; // set angles for (i=0 ; i<3 ; i++) { ent->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(dest->s.angles[i] - ent->client->resp.cmd_angles[i]); } VectorClear (ent->s.angles); VectorClear (ent->client->ps.viewangles); VectorClear (ent->client->v_angle); // kill anything at the destination KillBox (ent); gi.linkentity (ent);}
That
is the main body of the teleporter code. It is just modified from ids
teleporter code. Now below that add this lines:
void Use_Teleporter (edict_t *ent, gitem_t *item)
{edict_t *dest;
// if you wanted to use a "mark/recall" system the replace the above line with that code.
// sorry but you will have to make that code yourself (hint: one way is to drop an entity)
dest = SelectRandomDeathmatchSpawnPoint(); ent->client->pers.inventory[ITEM_INDEX(item)]--; ValidateSelectedItem (ent); teleport_me (ent, dest);}
That
finds a random deathmatch spot then removes one self teleporter from the
inventory, and then calls the function above to actually teleport the player.
Compile your code and test it out! You are done!