00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "g_local.h"
00024
00025
00026 void InitTrigger( gentity_t *self ) {
00027 if (!VectorCompare (self->s.angles, vec3_origin))
00028 G_SetMovedir (self->s.angles, self->movedir);
00029
00030 trap_SetBrushModel( self, self->model );
00031 self->r.contents = CONTENTS_TRIGGER;
00032 self->r.svFlags = SVF_NOCLIENT;
00033 }
00034
00035
00036
00037 void multi_wait( gentity_t *ent ) {
00038 ent->nextthink = 0;
00039 }
00040
00041
00042
00043
00044
00045 void multi_trigger( gentity_t *ent, gentity_t *activator ) {
00046 ent->activator = activator;
00047 if ( ent->nextthink ) {
00048 return;
00049 }
00050
00051 if ( activator->client ) {
00052 if ( ( ent->spawnflags & 1 ) &&
00053 activator->client->sess.sessionTeam != TEAM_RED ) {
00054 return;
00055 }
00056 if ( ( ent->spawnflags & 2 ) &&
00057 activator->client->sess.sessionTeam != TEAM_BLUE ) {
00058 return;
00059 }
00060 }
00061
00062 G_UseTargets (ent, ent->activator);
00063
00064 if ( ent->wait > 0 ) {
00065 ent->think = multi_wait;
00066 ent->nextthink = level.time + ( ent->wait + ent->random * crandom() ) * 1000;
00067 } else {
00068
00069
00070 ent->touch = 0;
00071 ent->nextthink = level.time + FRAMETIME;
00072 ent->think = G_FreeEntity;
00073 }
00074 }
00075
00076 void Use_Multi( gentity_t *ent, gentity_t *other, gentity_t *activator ) {
00077 multi_trigger( ent, activator );
00078 }
00079
00080 void Touch_Multi( gentity_t *self, gentity_t *other, trace_t *trace ) {
00081 if( !other->client ) {
00082 return;
00083 }
00084 multi_trigger( self, other );
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094 void SP_trigger_multiple( gentity_t *ent ) {
00095 G_SpawnFloat( "wait", "0.5", &ent->wait );
00096 G_SpawnFloat( "random", "0", &ent->random );
00097
00098 if ( ent->random >= ent->wait && ent->wait >= 0 ) {
00099 ent->random = ent->wait - FRAMETIME;
00100 G_Printf( "trigger_multiple has random >= wait\n" );
00101 }
00102
00103 ent->touch = Touch_Multi;
00104 ent->use = Use_Multi;
00105
00106 InitTrigger( ent );
00107 trap_LinkEntity (ent);
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 void trigger_always_think( gentity_t *ent ) {
00121 G_UseTargets(ent, ent);
00122 G_FreeEntity( ent );
00123 }
00124
00125
00126
00127
00128 void SP_trigger_always (gentity_t *ent) {
00129
00130 ent->nextthink = level.time + 300;
00131 ent->think = trigger_always_think;
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 void trigger_push_touch (gentity_t *self, gentity_t *other, trace_t *trace ) {
00144
00145 if ( !other->client ) {
00146 return;
00147 }
00148
00149 BG_TouchJumpPad( &other->client->ps, &self->s );
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 void AimAtTarget( gentity_t *self ) {
00161 gentity_t *ent;
00162 vec3_t origin;
00163 float height, gravity, time, forward;
00164 float dist;
00165
00166 VectorAdd( self->r.absmin, self->r.absmax, origin );
00167 VectorScale ( origin, 0.5, origin );
00168
00169 ent = G_PickTarget( self->target );
00170 if ( !ent ) {
00171 G_FreeEntity( self );
00172 return;
00173 }
00174
00175 height = ent->s.origin[2] - origin[2];
00176 gravity = g_gravity.value;
00177 time = sqrt( height / ( .5 * gravity ) );
00178 if ( !time ) {
00179 G_FreeEntity( self );
00180 return;
00181 }
00182
00183
00184 VectorSubtract ( ent->s.origin, origin, self->s.origin2 );
00185 self->s.origin2[2] = 0;
00186 dist = VectorNormalize( self->s.origin2);
00187
00188 forward = dist / time;
00189 VectorScale( self->s.origin2, forward, self->s.origin2 );
00190
00191 self->s.origin2[2] = time * gravity;
00192 }
00193
00194
00195
00196
00197
00198
00199 void SP_trigger_push( gentity_t *self ) {
00200 InitTrigger (self);
00201
00202
00203 self->r.svFlags &= ~SVF_NOCLIENT;
00204
00205
00206 G_SoundIndex("sound/world/jumppad.wav");
00207
00208 self->s.eType = ET_PUSH_TRIGGER;
00209 self->touch = trigger_push_touch;
00210 self->think = AimAtTarget;
00211 self->nextthink = level.time + FRAMETIME;
00212 trap_LinkEntity (self);
00213 }
00214
00215
00216 void Use_target_push( gentity_t *self, gentity_t *other, gentity_t *activator ) {
00217 if ( !activator->client ) {
00218 return;
00219 }
00220
00221 if ( activator->client->ps.pm_type != PM_NORMAL ) {
00222 return;
00223 }
00224 if ( activator->client->ps.powerups[PW_FLIGHT] ) {
00225 return;
00226 }
00227
00228 VectorCopy (self->s.origin2, activator->client->ps.velocity);
00229
00230
00231 if ( activator->fly_sound_debounce_time < level.time ) {
00232 activator->fly_sound_debounce_time = level.time + 1500;
00233 G_Sound( activator, CHAN_AUTO, self->noise_index );
00234 }
00235 }
00236
00237
00238
00239
00240
00241
00242 void SP_target_push( gentity_t *self ) {
00243 if (!self->speed) {
00244 self->speed = 1000;
00245 }
00246 G_SetMovedir (self->s.angles, self->s.origin2);
00247 VectorScale (self->s.origin2, self->speed, self->s.origin2);
00248
00249 if ( self->spawnflags & 1 ) {
00250 self->noise_index = G_SoundIndex("sound/world/jumppad.wav");
00251 } else {
00252 self->noise_index = G_SoundIndex("sound/misc/windfly.wav");
00253 }
00254 if ( self->target ) {
00255 VectorCopy( self->s.origin, self->r.absmin );
00256 VectorCopy( self->s.origin, self->r.absmax );
00257 self->think = AimAtTarget;
00258 self->nextthink = level.time + FRAMETIME;
00259 }
00260 self->use = Use_target_push;
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 void trigger_teleporter_touch (gentity_t *self, gentity_t *other, trace_t *trace ) {
00272 gentity_t *dest;
00273
00274 if ( !other->client ) {
00275 return;
00276 }
00277 if ( other->client->ps.pm_type == PM_DEAD ) {
00278 return;
00279 }
00280
00281 if ( ( self->spawnflags & 1 ) &&
00282 other->client->sess.sessionTeam != TEAM_SPECTATOR ) {
00283 return;
00284 }
00285
00286
00287 dest = G_PickTarget( self->target );
00288 if (!dest) {
00289 G_Printf ("Couldn't find teleporter destination\n");
00290 return;
00291 }
00292
00293 TeleportPlayer( other, dest->s.origin, dest->s.angles );
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 void SP_trigger_teleport( gentity_t *self ) {
00306 InitTrigger (self);
00307
00308
00309
00310 if ( self->spawnflags & 1 ) {
00311 self->r.svFlags |= SVF_NOCLIENT;
00312 } else {
00313 self->r.svFlags &= ~SVF_NOCLIENT;
00314 }
00315
00316
00317 G_SoundIndex("sound/world/jumppad.wav");
00318
00319 self->s.eType = ET_TELEPORT_TRIGGER;
00320 self->touch = trigger_teleporter_touch;
00321
00322 trap_LinkEntity (self);
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 void hurt_use( gentity_t *self, gentity_t *other, gentity_t *activator ) {
00347 if ( self->r.linked ) {
00348 trap_UnlinkEntity( self );
00349 } else {
00350 trap_LinkEntity( self );
00351 }
00352 }
00353
00354 void hurt_touch( gentity_t *self, gentity_t *other, trace_t *trace ) {
00355 int dflags;
00356
00357 if ( !other->takedamage ) {
00358 return;
00359 }
00360
00361 if ( self->timestamp > level.time ) {
00362 return;
00363 }
00364
00365 if ( self->spawnflags & 16 ) {
00366 self->timestamp = level.time + 1000;
00367 } else {
00368 self->timestamp = level.time + FRAMETIME;
00369 }
00370
00371
00372 if ( !(self->spawnflags & 4) ) {
00373 G_Sound( other, CHAN_AUTO, self->noise_index );
00374 }
00375
00376 if (self->spawnflags & 8)
00377 dflags = DAMAGE_NO_PROTECTION;
00378 else
00379 dflags = 0;
00380 G_Damage (other, self, self, NULL, NULL, self->damage, dflags, MOD_TRIGGER_HURT);
00381 }
00382
00383 void SP_trigger_hurt( gentity_t *self ) {
00384 InitTrigger (self);
00385
00386 self->noise_index = G_SoundIndex( "sound/world/electro.wav" );
00387 self->touch = hurt_touch;
00388
00389 if ( !self->damage ) {
00390 self->damage = 5;
00391 }
00392
00393 self->r.contents = CONTENTS_TRIGGER;
00394
00395 if ( self->spawnflags & 2 ) {
00396 self->use = hurt_use;
00397 }
00398
00399
00400 if ( ! (self->spawnflags & 1) ) {
00401 trap_LinkEntity (self);
00402 }
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 void func_timer_think( gentity_t *self ) {
00427 G_UseTargets (self, self->activator);
00428
00429 self->nextthink = level.time + 1000 * ( self->wait + crandom() * self->random );
00430 }
00431
00432 void func_timer_use( gentity_t *self, gentity_t *other, gentity_t *activator ) {
00433 self->activator = activator;
00434
00435
00436 if ( self->nextthink ) {
00437 self->nextthink = 0;
00438 return;
00439 }
00440
00441
00442 func_timer_think (self);
00443 }
00444
00445 void SP_func_timer( gentity_t *self ) {
00446 G_SpawnFloat( "random", "1", &self->random);
00447 G_SpawnFloat( "wait", "1", &self->wait );
00448
00449 self->use = func_timer_use;
00450 self->think = func_timer_think;
00451
00452 if ( self->random >= self->wait ) {
00453 self->random = self->wait - FRAMETIME;
00454 G_Printf( "func_timer at %s has random >= wait\n", vtos( self->s.origin ) );
00455 }
00456
00457 if ( self->spawnflags & 1 ) {
00458 self->nextthink = level.time + FRAMETIME;
00459 self->activator = self;
00460 }
00461
00462 self->r.svFlags = SVF_NOCLIENT;
00463 }
00464
00465