Randomly selected teleporter destinations


Posted by Maj.Bitch (24.95.222.*) at 3:03 PM, 4/29/2001:


I've been having fun on that large 64 player map called city64.bsp doing my pathing stuff. Anyway.. That map spawns 10 different teleporters each having their own target destination teleport spot. So, I was thinking about what it would take to make the destinations automatically randomly selected. Turns out it was a very easy mod.

What it does.. Everytime a teleporter is spawned into the map (at the beginning of each level when all the entities are put into the map by SpawnEntities), SP_misc_teleporter() function is called to achieve this. Each teleporter is hardwired with its own target destination. When somebody jumps into the teleporter particle field, G_Find() is called inside of teleporter_touch() to get the target destination entity. Once that information is obtained, it is a simple matter to relocate the player to the destination point.

So I set up an array of target destinations with some arbitrary number (like 32, probably won't ever be that many teleporters spawned into any given map, but who knows..) and when the SP_misc_teleporter() function is called to actually put a teleporter into the map, I grab a copy of the teleporter's targetname and keep a count of how many targetnames I've got saved up in my array. Then, in teleporter_touch(), I substituted the teleporter's hardwired targetname for a targetname randomly selected from my array.

Now, when I jump into a teleporter's particle field, I get teleported to a random teleporter destination so you never really know where you're gonna end up when you jump into one!!

Check it out!!

First, add this extern just above your SpawnEntities() function like so:

extern int num_targets;

And, at the very bottom of SpawnEntities, put this line:

num_targets=0; // reset this every level change

Second, find your SP_misc_teleporter function in your g_misc.c file and make the changes indicated below..

<C&NBSP;CODE>
// ADD THESE 3 LINES RIGHT ABOVE YOUR TELEPORTER_TOUCH() FUNCTION
int num_targets;
#define maxtargs 32
char *target[maxtargs]; // teleporter target destinations array

//=====================================================
void teleporter_touch(edict_t *teleporter,edict_t *other,cplane_t *plane,csurface_t *surf) {

  if (!G_ClientInGame(other)) return;

  // SUBSITUTE THIS LINE FOR THE ONE THAT WAS THERE ORIGINALLY 
  edict_t *dest=G_Find(NULL,FOFS(targetname),target[(int)(rand()%num_targets)-1]);

  if (!dest) return;

  gi.unlinkentity(other);

  VectorCopy(dest->s.origin,other->s.origin);
  VectorCopy(dest->s.origin,other->s.old_origin);
  other->s.origin[2]+=10;
  other->client->ps.pmove.pm_time=160>>3;
  other->client->ps.pmove.pm_flags|=PMF_time_TELEPORT;
  teleporter->owner->s.event|=EV_PLAYER_TELEPORT;
  other->s.event|=EV_PLAYER_TELEPORT;
  other->client->ps.pmove.delta_angles[0]=ANGLE2SHORT(dest->s.angles[0]-other->client->resp.cmd_angles[0]);
  other->client->ps.pmove.delta_angles[1]=ANGLE2SHORT(dest->s.angles[1]-other->client->resp.cmd_angles[1]);
  other->client->ps.pmove.delta_angles[2]=ANGLE2SHORT(dest->s.angles[2]-other->client->resp.cmd_angles[2]);
  VectorClear(other->s.angles);
  VectorClear(other->velocity);
  VectorClear(other->client->ps.viewangles);
  VectorClear(other->client->v_angle);

  KillBox(other);

  gi.linkentity(other);
}

//=====================================================
void SP_misc_teleporter(edict_t *teleporter) {

  if (!teleporter->target) {
    G_FreeEdict(teleporter);
    return; }

  gi.setmodel(teleporter,"models/objects/dmspot/tris.md2");
  teleporter->s.skinnum=1;
  teleporter->s.effects|=EF_TELEPORTER;
  teleporter->s.sound=snd[64];
  teleporter->solid=SOLID_BBOX;
  VectorSet(teleporter->mins,-32,-32,-24);
  VectorSet(teleporter->maxs,32,32,-16);
  gi.linkentity(teleporter);

// ADD THESE 2 LINES RIGHT HERE..
  if (num_targets+1<maxtargs)
    target[num_targets++]=teleporter->target; // copy the target's name

  //------ Trigger ------/
  edict_t *trig=G_Spawn();
  trig->solid=SOLID_TRIGGER;
  trig->target=teleporter->target;
  trig->owner=teleporter;
  VectorCopy(teleporter->s.origin,trig->s.origin);
  VectorSet(trig->mins,-8,-8,8);
  VectorSet(trig->maxs,8,8,24);
  trig->touch=teleporter_touch;
  gi.linkentity(trig);
}
</C&NBSP;CODE>

That's it!!

Simple to do and adds a level of uncertainty to large maps with multiple teleporters scattered around all over the place. Those players who think they know how to teleporter around will be in for a big suprise!!


Have fun!

Maj.Bitch




Replies:             (Local time is: 1:00:42 PM, 4/23/2004)

TUTORIAL: Randomly selected teleporter destinations - Maj.Bitch at 3:03 PM, 4/29/2001 (3 replies)