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