1 // g_newtrig.c
2 // pmack
3 // october 1997
4
5 #include "g_local.h"
6
7 #define TELEPORT_PLAYER_ONLY 1
8 #define TELEPORT_SILENT 2
9 #define TELEPORT_CTF_ONLY 4
10 #define TELEPORT_START_ON 8
11
12 extern void TeleportEffect (vec3_t origin);
13
14 /*QUAKED info_teleport_destination (.5 .5 .5) (-16 -16 -24) (16 16 32)
15 Destination marker for a teleporter.
16 */
SP_info_teleport_destination(edict_t * self)17 void SP_info_teleport_destination (edict_t *self)
18 {
19 }
20
21 /*QUAKED trigger_teleport (.5 .5 .5) ? player_only silent ctf_only start_on
22 Any object touching this will be transported to the corresponding
23 info_teleport_destination entity. You must set the "target" field,
24 and create an object with a "targetname" field that matches.
25
26 If the trigger_teleport has a targetname, it will only teleport
27 entities when it has been fired.
28
29 player_only: only players are teleported
30 silent: <not used right now>
31 ctf_only: <not used right now>
32 start_on: when trigger has targetname, start active, deactivate when used.
33 */
trigger_teleport_touch(edict_t * self,edict_t * other,cplane_t * plane,csurface_t * surf)34 void trigger_teleport_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
35 {
36 edict_t *dest;
37 int i;
38
39 if(/*(self->spawnflags & TELEPORT_PLAYER_ONLY) &&*/ !(other->client))
40 return;
41
42 if(self->delay)
43 return;
44
45 dest = G_Find (NULL, FOFS(targetname), self->target);
46 if(!dest)
47 {
48 gi.dprintf("Teleport Destination not found!\n");
49 return;
50 }
51
52 gi.WriteByte (svc_temp_entity);
53 gi.WriteByte (TE_TELEPORT_EFFECT);
54 gi.WritePosition (other->s.origin);
55 gi.multicast (other->s.origin, MULTICAST_PVS);
56
57 // unlink to make sure it can't possibly interfere with KillBox
58 gi.unlinkentity (other);
59
60 VectorCopy (dest->s.origin, other->s.origin);
61 VectorCopy (dest->s.origin, other->s.old_origin);
62 other->s.origin[2] += 10;
63
64 // clear the velocity and hold them in place briefly
65 VectorClear (other->velocity);
66 if(other->client)
67 {
68 other->client->ps.pmove.pm_time = 160>>3; // hold time
69 other->client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT;
70
71 // draw the teleport splash at source and on the player
72 // self->s.event = EV_PLAYER_TELEPORT;
73 other->s.event = EV_PLAYER_TELEPORT;
74
75 // set angles
76 for (i=0 ; i<3 ; i++)
77 other->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(dest->s.angles[i] - other->client->resp.cmd_angles[i]);
78
79 VectorClear (other->client->ps.viewangles);
80 VectorClear (other->client->v_angle);
81 }
82
83
84 VectorClear (other->s.angles);
85
86 // kill anything at the destination
87 KillBox (other);
88
89 gi.linkentity (other);
90 }
91
trigger_teleport_use(edict_t * self,edict_t * other,edict_t * activator)92 void trigger_teleport_use (edict_t *self, edict_t *other, edict_t *activator)
93 {
94 if(self->delay)
95 self->delay = 0;
96 else
97 self->delay = 1;
98 }
99
SP_trigger_teleport(edict_t * self)100 void SP_trigger_teleport(edict_t *self)
101 {
102 if (!self->wait)
103 self->wait = 0.2;
104
105 self->delay = 0;
106
107 if (self->targetname)
108 {
109 self->use = trigger_teleport_use;
110 if(!(self->spawnflags & TELEPORT_START_ON))
111 self->delay = 1;
112 }
113
114 self->touch = trigger_teleport_touch;
115
116 self->solid = SOLID_TRIGGER;
117 self->movetype = MOVETYPE_NONE;
118 // self->flags |= FL_NOCLIENT;
119
120 if (!VectorCompare(self->s.angles, vec3_origin))
121 G_SetMovedir (self->s.angles, self->movedir);
122
123 gi.setmodel (self, self->model);
124 gi.linkentity (self);
125 }
126
127 // ***************************
128 // TRIGGER_DISGUISE
129 // ***************************
130
131 /*QUAKED trigger_disguise (.5 .5 .5) ? TOGGLE START_ON REMOVE
132 Anything passing through this trigger when it is active will
133 be marked as disguised.
134
135 TOGGLE - field is turned off and on when used.
136 START_ON - field is active when spawned.
137 REMOVE - field removes the disguise
138 */
139
trigger_disguise_touch(edict_t * self,edict_t * other,cplane_t * plane,csurface_t * surf)140 void trigger_disguise_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
141 {
142 if (other->client)
143 {
144 if(self->spawnflags & 4)
145 other->flags &= ~FL_DISGUISED;
146 else
147 other->flags |= FL_DISGUISED;
148 }
149 }
150
trigger_disguise_use(edict_t * self,edict_t * other,edict_t * activator)151 void trigger_disguise_use (edict_t *self, edict_t *other, edict_t *activator)
152 {
153 if(self->solid == SOLID_NOT)
154 self->solid = SOLID_TRIGGER;
155 else
156 self->solid = SOLID_NOT;
157
158 gi.linkentity(self);
159 }
160
SP_trigger_disguise(edict_t * self)161 void SP_trigger_disguise (edict_t *self)
162 {
163 if(self->spawnflags & 2)
164 self->solid = SOLID_TRIGGER;
165 else
166 self->solid = SOLID_NOT;
167
168 self->touch = trigger_disguise_touch;
169 self->use = trigger_disguise_use;
170 self->movetype = MOVETYPE_NONE;
171 self->svflags = SVF_NOCLIENT;
172
173 gi.setmodel (self, self->model);
174 gi.linkentity(self);
175
176 }
177