2 void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity)
7 sound (player, CHAN_TRIGGER, "misc/teleport.wav", VOL_BASE, ATTN_NORM);
8 pointparticles(particleeffectnum("teleport"), player.origin, '0 0 0', 1);
10 makevectors (to_angles);
11 pointparticles(particleeffectnum("teleport"), to + v_forward * 32, '0 0 0', 1);
13 // Relocate the player
14 // assuming to allows PL_MIN to PL_MAX box and some more
15 setorigin (player, to + '0 0 1' * (1 - player.mins_z - 24));
16 player.angles = to_angles;
17 player.fixangle = TRUE;
18 player.velocity = to_velocity;
20 if(player.classname == "player")
22 RemoveGrapplingHook(player);
24 // Kill anyone else in the teleporter box (NO MORE TDEATH)
25 if(player.takedamage && !g_race)
30 deathmin = player.absmin;
31 deathmax = player.absmax;
32 deathradius = max(vlen(deathmin), vlen(deathmax));
33 for(head = findradius(player.origin, deathradius); head; head = head.chain)
36 if(boxesoverlap(deathmin, deathmax, head.absmin, head.absmax))
38 if ((player.classname == "player") && (player.health >= 1))
39 Damage (head, teleporter, player, 10000, DEATH_TELEFRAG, head.origin, '0 0 0');
40 else if (player.health < 1) // corpses gib
41 Damage (head, teleporter, player, 10000, DEATH_TELEFRAG, head.origin, '0 0 0');
42 else // dead bodies and monsters gib themselves instead of telefragging
43 Damage (player, teleporter, player, 10000, DEATH_TELEFRAG, player.origin, '0 0 0');
48 player.effects = player.effects | EF_NODRAW;
49 if (player.weaponentity) // misuse FL_FLY to avoid EF_NODRAW on viewmodel
50 player.weaponentity.flags = player.weaponentity.flags | FL_FLY;
51 player.teleport_time = time + cvar("sys_ticrate");
53 // player no longer is on ground
54 player.flags = player.flags - (player.flags & FL_ONGROUND);
56 // reset tracking of oldvelocity for impact damage (sudden velocity changes)
57 player.oldvelocity = player.velocity;
59 // reset tracking of who pushed you into a hazard (for kill credit)
62 player.pusher = teleporter.owner;
63 player.pushltime = time + cvar("g_maxpushtime");
70 // stop player name display
74 ClearSelectedPlayer();
80 void Teleport_Touch (void)
86 if (!other.flags & FL_CLIENT) // FIXME: Make missiles firable through the teleport too
91 makevectors(self.enemy.mangle);
92 TeleportPlayer(self, other, self.enemy.origin + '0 0 1' * (1 - other.mins_z - 24), self.enemy.mangle, v_forward * vlen(other.velocity));
104 void spawnfunc_info_teleport_destination (void)
106 self.mangle = self.angles;
107 self.angles = '0 0 0';
109 //setorigin (self, self.origin + '0 0 27'); // To fix a mappers' habit as old as Quake
110 setorigin (self, self.origin);
116 objerror ("Teleport destination without a targetname");
119 void spawnfunc_misc_teleporter_dest (void)
121 spawnfunc_info_teleport_destination();
124 void spawnfunc_target_teleporter (void)
126 spawnfunc_info_teleport_destination();
129 void teleport_findtarget (void)
132 self.touch = Teleport_Touch;
134 self.enemy = find (world, targetname, self.target);
137 objerror ("Teleporter with nonexistant target");
142 self.dest = self.enemy.origin;
143 waypoint_spawnforteleporter(self, self.dest, 0);
146 void spawnfunc_trigger_teleport (void)
148 self.angles = '0 0 0';
152 // this must be called to spawn the teleport waypoints for bots
153 InitializeEntity(self, teleport_findtarget, INITPRIO_FINDTARGET);
156 objerror ("Teleporter with no target");