
I designed this so I didn't have to go through
most of a level when I was playing coop and my friend 'accidentally' killed me
[generally by shoving me into a pit of lava]. It uses Major Bitch's random
spawn point code in a slightly modifided format (it checks to see if the point
is within 400 units of the other player and also if you will telefrag anything)
Currently it will only teleport you to the first
other player it finds. while this suited my purposes fine, you will probably
want to modify this so it teleports you to people on a team, or allow you to
choose a target player. I'd also suggest putting a timer in, to limit how often
people can teleport, or make it cost something. I'll mark the areas to do this.
On to the code. I'll put a file with everything in
it at the bottom, but heres the code with an explanation of everything
Add all of this code to a new file and add it to
your project (to make sure you don't have typos i'd suggest grabbing the code
from below)
#include "g_local.h" // Gives the file all the access to definitions it needs. required line /* BossTeleport is a helper function that I created to allow the easy creation of a teleport effectIt creates a cloud of particles that moves upwards and disapates. If you have downloaded my tempent files you don't need this. (it might even cause conflicts) */ void BossTeleport(edict_t *ent) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BOSSTPORT); gi.WritePosition (ent->s.origin); gi.multicast (ent->s.origin, MULTICAST_PVS);} /* This is a modified version of Major Bitch's findrandomspawnpoint code.I changed it so it takes the player to be teleported, the player to be teleported to and a return value for the new location. (not sure why the return val works, I thought it wouldn't) */ qboolean findteleportpoint (edict_t *ent,edict_t *targent,vec3_t returnval){ vec3_t loc = {0,0,0}; vec3_t floor; vec3_t v; int i; int j = 0; int k = 0; int jmax = 1000; int kmax = (int)(jmax/2); qboolean found = false; trace_t tr; float distance; do { if (found || j >= jmax || k >= kmax) break; j++; for (i = 0; i < 3; i++) loc[i] = rand() % (8192 + 1) - 4096; if (gi.pointcontents(loc) == 0) { VectorCopy(loc, floor); floor[2] = -4096; tr = gi.trace (loc, ent->maxs, ent->mins, floor, NULL, MASK_SOLID|MASK_WATER); k++; if (tr.contents & MASK_WATER) found = false; else { VectorCopy (tr.endpos, loc); loc[2] += ent->maxs[2] - ent->mins[2]; // make sure the entity can fit! found = (gi.pointcontents(loc) == 0 ? true : false); if (found) { VectorSubtract (loc, targent->s.origin, v); // this bit checks to see if the target distance = VectorLength (v); // player is within 400 units if (distance>400) found=false; tr = gi.trace (loc, ent->mins, ent->maxs, loc, NULL, MASK_PLAYERSOLID); // this is to make sure you don't telefrag anyone if (tr.ent) found=false; } } } else found = false; } while (!found && j < jmax && k < kmax); if (!found && (j >= jmax || k >= kmax)) return false; VectorCopy(loc,returnval); return true;} void Cmd_Teleport_f(edict_t *ent){ int n; edict_t *player; vec3_t spot; int iter=0; int found=0; /* The for loop below goes through the list of plaers looking for one that exists and is ready to be a teleport target. You will probably want to change this so it also checks that team against the teleportees team.another possible idea is to use a menu and generate the menu to list all the players you can teleport to. you would want to move all the code below the loop to the menu results function. I'm not going to put up instructionson how to do this here. Mail me and I may get round to sending you instructions. (for my menu tut only as I don't know the others as well) */ for (n = 1; n <= maxclients->value; n++) { player = &g_edicts[n]; if (!player->inuse) continue; if (player->health <= 0) continue; if (player==ent) continue; found=1; break; } if (!found) { gi.centerprintf(ent,"No Other Players for teleport\n"); return; } // Checks for a new spawnpoint. the iter section is to make sure it doesn't hang the system if no point exists while ((findspawnpoint(ent,player,spot) == false) & (iter<10000)) {iter++;} if (iter==10000) { gi.cprintf(ent,PRINT_HIGH,"No teleport spot available\n"); return; } BossTeleport(ent); gi.unlinkentity (ent); VectorCopy(spot,ent->s.origin); ent->s.event = EV_PLAYER_TELEPORT; gi.sound (ent, CHAN_ITEM, gi.soundindex ("world/blackhole.wav"), 1, ATTN_NORM, 0); gi.linkentity (ent);}
To use this code, add a command to the command
parser in g_cmds.c that calls Cmd_Teleport_f(ent); you should know how. If you
don't, check out other tuts on this site. Remember to prototype it.
As another though, maybe having a command that
does a trace forward and store a pointer to a player entity as a teleport link
would be an idea. Again, mail me if you want to do it and can't