diff options
author | zakk <zakk@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-08-26 17:39:27 +0000 |
---|---|---|
committer | zakk <zakk@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-08-26 17:39:27 +0000 |
commit | 6bf20c78f5b69d40bcc4931df93d29198435ab67 (patch) | |
tree | e3eda937a05d7db42de725b7013bd0344b987f34 /code/game/g_trigger.c | |
parent | 872d4d7f55af706737ffb361bb76ad13e7496770 (diff) | |
download | ioquake3-aero-6bf20c78f5b69d40bcc4931df93d29198435ab67.tar.gz ioquake3-aero-6bf20c78f5b69d40bcc4931df93d29198435ab67.zip |
newlines fixed
git-svn-id: svn://svn.icculus.org/quake3/trunk@6 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'code/game/g_trigger.c')
-rwxr-xr-x | code/game/g_trigger.c | 930 |
1 files changed, 465 insertions, 465 deletions
diff --git a/code/game/g_trigger.c b/code/game/g_trigger.c index 6ec8a35..9db2304 100755 --- a/code/game/g_trigger.c +++ b/code/game/g_trigger.c @@ -1,465 +1,465 @@ -/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Foobar; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-//
-#include "g_local.h"
-
-
-void InitTrigger( gentity_t *self ) {
- if (!VectorCompare (self->s.angles, vec3_origin))
- G_SetMovedir (self->s.angles, self->movedir);
-
- trap_SetBrushModel( self, self->model );
- self->r.contents = CONTENTS_TRIGGER; // replaces the -1 from trap_SetBrushModel
- self->r.svFlags = SVF_NOCLIENT;
-}
-
-
-// the wait time has passed, so set back up for another activation
-void multi_wait( gentity_t *ent ) {
- ent->nextthink = 0;
-}
-
-
-// the trigger was just activated
-// ent->activator should be set to the activator so it can be held through a delay
-// so wait for the delay time before firing
-void multi_trigger( gentity_t *ent, gentity_t *activator ) {
- ent->activator = activator;
- if ( ent->nextthink ) {
- return; // can't retrigger until the wait is over
- }
-
- if ( activator->client ) {
- if ( ( ent->spawnflags & 1 ) &&
- activator->client->sess.sessionTeam != TEAM_RED ) {
- return;
- }
- if ( ( ent->spawnflags & 2 ) &&
- activator->client->sess.sessionTeam != TEAM_BLUE ) {
- return;
- }
- }
-
- G_UseTargets (ent, ent->activator);
-
- if ( ent->wait > 0 ) {
- ent->think = multi_wait;
- ent->nextthink = level.time + ( ent->wait + ent->random * crandom() ) * 1000;
- } else {
- // we can't just remove (self) here, because this is a touch function
- // called while looping through area links...
- ent->touch = 0;
- ent->nextthink = level.time + FRAMETIME;
- ent->think = G_FreeEntity;
- }
-}
-
-void Use_Multi( gentity_t *ent, gentity_t *other, gentity_t *activator ) {
- multi_trigger( ent, activator );
-}
-
-void Touch_Multi( gentity_t *self, gentity_t *other, trace_t *trace ) {
- if( !other->client ) {
- return;
- }
- multi_trigger( self, other );
-}
-
-/*QUAKED trigger_multiple (.5 .5 .5) ?
-"wait" : Seconds between triggerings, 0.5 default, -1 = one time only.
-"random" wait variance, default is 0
-Variable sized repeatable trigger. Must be targeted at one or more entities.
-so, the basic time between firing is a random time between
-(wait - random) and (wait + random)
-*/
-void SP_trigger_multiple( gentity_t *ent ) {
- G_SpawnFloat( "wait", "0.5", &ent->wait );
- G_SpawnFloat( "random", "0", &ent->random );
-
- if ( ent->random >= ent->wait && ent->wait >= 0 ) {
- ent->random = ent->wait - FRAMETIME;
- G_Printf( "trigger_multiple has random >= wait\n" );
- }
-
- ent->touch = Touch_Multi;
- ent->use = Use_Multi;
-
- InitTrigger( ent );
- trap_LinkEntity (ent);
-}
-
-
-
-/*
-==============================================================================
-
-trigger_always
-
-==============================================================================
-*/
-
-void trigger_always_think( gentity_t *ent ) {
- G_UseTargets(ent, ent);
- G_FreeEntity( ent );
-}
-
-/*QUAKED trigger_always (.5 .5 .5) (-8 -8 -8) (8 8 8)
-This trigger will always fire. It is activated by the world.
-*/
-void SP_trigger_always (gentity_t *ent) {
- // we must have some delay to make sure our use targets are present
- ent->nextthink = level.time + 300;
- ent->think = trigger_always_think;
-}
-
-
-/*
-==============================================================================
-
-trigger_push
-
-==============================================================================
-*/
-
-void trigger_push_touch (gentity_t *self, gentity_t *other, trace_t *trace ) {
-
- if ( !other->client ) {
- return;
- }
-
- BG_TouchJumpPad( &other->client->ps, &self->s );
-}
-
-
-/*
-=================
-AimAtTarget
-
-Calculate origin2 so the target apogee will be hit
-=================
-*/
-void AimAtTarget( gentity_t *self ) {
- gentity_t *ent;
- vec3_t origin;
- float height, gravity, time, forward;
- float dist;
-
- VectorAdd( self->r.absmin, self->r.absmax, origin );
- VectorScale ( origin, 0.5, origin );
-
- ent = G_PickTarget( self->target );
- if ( !ent ) {
- G_FreeEntity( self );
- return;
- }
-
- height = ent->s.origin[2] - origin[2];
- gravity = g_gravity.value;
- time = sqrt( height / ( .5 * gravity ) );
- if ( !time ) {
- G_FreeEntity( self );
- return;
- }
-
- // set s.origin2 to the push velocity
- VectorSubtract ( ent->s.origin, origin, self->s.origin2 );
- self->s.origin2[2] = 0;
- dist = VectorNormalize( self->s.origin2);
-
- forward = dist / time;
- VectorScale( self->s.origin2, forward, self->s.origin2 );
-
- self->s.origin2[2] = time * gravity;
-}
-
-
-/*QUAKED trigger_push (.5 .5 .5) ?
-Must point at a target_position, which will be the apex of the leap.
-This will be client side predicted, unlike target_push
-*/
-void SP_trigger_push( gentity_t *self ) {
- InitTrigger (self);
-
- // unlike other triggers, we need to send this one to the client
- self->r.svFlags &= ~SVF_NOCLIENT;
-
- // make sure the client precaches this sound
- G_SoundIndex("sound/world/jumppad.wav");
-
- self->s.eType = ET_PUSH_TRIGGER;
- self->touch = trigger_push_touch;
- self->think = AimAtTarget;
- self->nextthink = level.time + FRAMETIME;
- trap_LinkEntity (self);
-}
-
-
-void Use_target_push( gentity_t *self, gentity_t *other, gentity_t *activator ) {
- if ( !activator->client ) {
- return;
- }
-
- if ( activator->client->ps.pm_type != PM_NORMAL ) {
- return;
- }
- if ( activator->client->ps.powerups[PW_FLIGHT] ) {
- return;
- }
-
- VectorCopy (self->s.origin2, activator->client->ps.velocity);
-
- // play fly sound every 1.5 seconds
- if ( activator->fly_sound_debounce_time < level.time ) {
- activator->fly_sound_debounce_time = level.time + 1500;
- G_Sound( activator, CHAN_AUTO, self->noise_index );
- }
-}
-
-/*QUAKED target_push (.5 .5 .5) (-8 -8 -8) (8 8 8) bouncepad
-Pushes the activator in the direction.of angle, or towards a target apex.
-"speed" defaults to 1000
-if "bouncepad", play bounce noise instead of windfly
-*/
-void SP_target_push( gentity_t *self ) {
- if (!self->speed) {
- self->speed = 1000;
- }
- G_SetMovedir (self->s.angles, self->s.origin2);
- VectorScale (self->s.origin2, self->speed, self->s.origin2);
-
- if ( self->spawnflags & 1 ) {
- self->noise_index = G_SoundIndex("sound/world/jumppad.wav");
- } else {
- self->noise_index = G_SoundIndex("sound/misc/windfly.wav");
- }
- if ( self->target ) {
- VectorCopy( self->s.origin, self->r.absmin );
- VectorCopy( self->s.origin, self->r.absmax );
- self->think = AimAtTarget;
- self->nextthink = level.time + FRAMETIME;
- }
- self->use = Use_target_push;
-}
-
-/*
-==============================================================================
-
-trigger_teleport
-
-==============================================================================
-*/
-
-void trigger_teleporter_touch (gentity_t *self, gentity_t *other, trace_t *trace ) {
- gentity_t *dest;
-
- if ( !other->client ) {
- return;
- }
- if ( other->client->ps.pm_type == PM_DEAD ) {
- return;
- }
- // Spectators only?
- if ( ( self->spawnflags & 1 ) &&
- other->client->sess.sessionTeam != TEAM_SPECTATOR ) {
- return;
- }
-
-
- dest = G_PickTarget( self->target );
- if (!dest) {
- G_Printf ("Couldn't find teleporter destination\n");
- return;
- }
-
- TeleportPlayer( other, dest->s.origin, dest->s.angles );
-}
-
-
-/*QUAKED trigger_teleport (.5 .5 .5) ? SPECTATOR
-Allows client side prediction of teleportation events.
-Must point at a target_position, which will be the teleport destination.
-
-If spectator is set, only spectators can use this teleport
-Spectator teleporters are not normally placed in the editor, but are created
-automatically near doors to allow spectators to move through them
-*/
-void SP_trigger_teleport( gentity_t *self ) {
- InitTrigger (self);
-
- // unlike other triggers, we need to send this one to the client
- // unless is a spectator trigger
- if ( self->spawnflags & 1 ) {
- self->r.svFlags |= SVF_NOCLIENT;
- } else {
- self->r.svFlags &= ~SVF_NOCLIENT;
- }
-
- // make sure the client precaches this sound
- G_SoundIndex("sound/world/jumppad.wav");
-
- self->s.eType = ET_TELEPORT_TRIGGER;
- self->touch = trigger_teleporter_touch;
-
- trap_LinkEntity (self);
-}
-
-
-/*
-==============================================================================
-
-trigger_hurt
-
-==============================================================================
-*/
-
-/*QUAKED trigger_hurt (.5 .5 .5) ? START_OFF - SILENT NO_PROTECTION SLOW
-Any entity that touches this will be hurt.
-It does dmg points of damage each server frame
-Targeting the trigger will toggle its on / off state.
-
-SILENT supresses playing the sound
-SLOW changes the damage rate to once per second
-NO_PROTECTION *nothing* stops the damage
-
-"dmg" default 5 (whole numbers only)
-
-*/
-void hurt_use( gentity_t *self, gentity_t *other, gentity_t *activator ) {
- if ( self->r.linked ) {
- trap_UnlinkEntity( self );
- } else {
- trap_LinkEntity( self );
- }
-}
-
-void hurt_touch( gentity_t *self, gentity_t *other, trace_t *trace ) {
- int dflags;
-
- if ( !other->takedamage ) {
- return;
- }
-
- if ( self->timestamp > level.time ) {
- return;
- }
-
- if ( self->spawnflags & 16 ) {
- self->timestamp = level.time + 1000;
- } else {
- self->timestamp = level.time + FRAMETIME;
- }
-
- // play sound
- if ( !(self->spawnflags & 4) ) {
- G_Sound( other, CHAN_AUTO, self->noise_index );
- }
-
- if (self->spawnflags & 8)
- dflags = DAMAGE_NO_PROTECTION;
- else
- dflags = 0;
- G_Damage (other, self, self, NULL, NULL, self->damage, dflags, MOD_TRIGGER_HURT);
-}
-
-void SP_trigger_hurt( gentity_t *self ) {
- InitTrigger (self);
-
- self->noise_index = G_SoundIndex( "sound/world/electro.wav" );
- self->touch = hurt_touch;
-
- if ( !self->damage ) {
- self->damage = 5;
- }
-
- self->r.contents = CONTENTS_TRIGGER;
-
- if ( self->spawnflags & 2 ) {
- self->use = hurt_use;
- }
-
- // link in to the world if starting active
- if ( ! (self->spawnflags & 1) ) {
- trap_LinkEntity (self);
- }
-}
-
-
-/*
-==============================================================================
-
-timer
-
-==============================================================================
-*/
-
-
-/*QUAKED func_timer (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) START_ON
-This should be renamed trigger_timer...
-Repeatedly fires its targets.
-Can be turned on or off by using.
-
-"wait" base time between triggering all targets, default is 1
-"random" wait variance, default is 0
-so, the basic time between firing is a random time between
-(wait - random) and (wait + random)
-
-*/
-void func_timer_think( gentity_t *self ) {
- G_UseTargets (self, self->activator);
- // set time before next firing
- self->nextthink = level.time + 1000 * ( self->wait + crandom() * self->random );
-}
-
-void func_timer_use( gentity_t *self, gentity_t *other, gentity_t *activator ) {
- self->activator = activator;
-
- // if on, turn it off
- if ( self->nextthink ) {
- self->nextthink = 0;
- return;
- }
-
- // turn it on
- func_timer_think (self);
-}
-
-void SP_func_timer( gentity_t *self ) {
- G_SpawnFloat( "random", "1", &self->random);
- G_SpawnFloat( "wait", "1", &self->wait );
-
- self->use = func_timer_use;
- self->think = func_timer_think;
-
- if ( self->random >= self->wait ) {
- self->random = self->wait - FRAMETIME;
- G_Printf( "func_timer at %s has random >= wait\n", vtos( self->s.origin ) );
- }
-
- if ( self->spawnflags & 1 ) {
- self->nextthink = level.time + FRAMETIME;
- self->activator = self;
- }
-
- self->r.svFlags = SVF_NOCLIENT;
-}
-
-
+/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +#include "g_local.h" + + +void InitTrigger( gentity_t *self ) { + if (!VectorCompare (self->s.angles, vec3_origin)) + G_SetMovedir (self->s.angles, self->movedir); + + trap_SetBrushModel( self, self->model ); + self->r.contents = CONTENTS_TRIGGER; // replaces the -1 from trap_SetBrushModel + self->r.svFlags = SVF_NOCLIENT; +} + + +// the wait time has passed, so set back up for another activation +void multi_wait( gentity_t *ent ) { + ent->nextthink = 0; +} + + +// the trigger was just activated +// ent->activator should be set to the activator so it can be held through a delay +// so wait for the delay time before firing +void multi_trigger( gentity_t *ent, gentity_t *activator ) { + ent->activator = activator; + if ( ent->nextthink ) { + return; // can't retrigger until the wait is over + } + + if ( activator->client ) { + if ( ( ent->spawnflags & 1 ) && + activator->client->sess.sessionTeam != TEAM_RED ) { + return; + } + if ( ( ent->spawnflags & 2 ) && + activator->client->sess.sessionTeam != TEAM_BLUE ) { + return; + } + } + + G_UseTargets (ent, ent->activator); + + if ( ent->wait > 0 ) { + ent->think = multi_wait; + ent->nextthink = level.time + ( ent->wait + ent->random * crandom() ) * 1000; + } else { + // we can't just remove (self) here, because this is a touch function + // called while looping through area links... + ent->touch = 0; + ent->nextthink = level.time + FRAMETIME; + ent->think = G_FreeEntity; + } +} + +void Use_Multi( gentity_t *ent, gentity_t *other, gentity_t *activator ) { + multi_trigger( ent, activator ); +} + +void Touch_Multi( gentity_t *self, gentity_t *other, trace_t *trace ) { + if( !other->client ) { + return; + } + multi_trigger( self, other ); +} + +/*QUAKED trigger_multiple (.5 .5 .5) ? +"wait" : Seconds between triggerings, 0.5 default, -1 = one time only. +"random" wait variance, default is 0 +Variable sized repeatable trigger. Must be targeted at one or more entities. +so, the basic time between firing is a random time between +(wait - random) and (wait + random) +*/ +void SP_trigger_multiple( gentity_t *ent ) { + G_SpawnFloat( "wait", "0.5", &ent->wait ); + G_SpawnFloat( "random", "0", &ent->random ); + + if ( ent->random >= ent->wait && ent->wait >= 0 ) { + ent->random = ent->wait - FRAMETIME; + G_Printf( "trigger_multiple has random >= wait\n" ); + } + + ent->touch = Touch_Multi; + ent->use = Use_Multi; + + InitTrigger( ent ); + trap_LinkEntity (ent); +} + + + +/* +============================================================================== + +trigger_always + +============================================================================== +*/ + +void trigger_always_think( gentity_t *ent ) { + G_UseTargets(ent, ent); + G_FreeEntity( ent ); +} + +/*QUAKED trigger_always (.5 .5 .5) (-8 -8 -8) (8 8 8) +This trigger will always fire. It is activated by the world. +*/ +void SP_trigger_always (gentity_t *ent) { + // we must have some delay to make sure our use targets are present + ent->nextthink = level.time + 300; + ent->think = trigger_always_think; +} + + +/* +============================================================================== + +trigger_push + +============================================================================== +*/ + +void trigger_push_touch (gentity_t *self, gentity_t *other, trace_t *trace ) { + + if ( !other->client ) { + return; + } + + BG_TouchJumpPad( &other->client->ps, &self->s ); +} + + +/* +================= +AimAtTarget + +Calculate origin2 so the target apogee will be hit +================= +*/ +void AimAtTarget( gentity_t *self ) { + gentity_t *ent; + vec3_t origin; + float height, gravity, time, forward; + float dist; + + VectorAdd( self->r.absmin, self->r.absmax, origin ); + VectorScale ( origin, 0.5, origin ); + + ent = G_PickTarget( self->target ); + if ( !ent ) { + G_FreeEntity( self ); + return; + } + + height = ent->s.origin[2] - origin[2]; + gravity = g_gravity.value; + time = sqrt( height / ( .5 * gravity ) ); + if ( !time ) { + G_FreeEntity( self ); + return; + } + + // set s.origin2 to the push velocity + VectorSubtract ( ent->s.origin, origin, self->s.origin2 ); + self->s.origin2[2] = 0; + dist = VectorNormalize( self->s.origin2); + + forward = dist / time; + VectorScale( self->s.origin2, forward, self->s.origin2 ); + + self->s.origin2[2] = time * gravity; +} + + +/*QUAKED trigger_push (.5 .5 .5) ? +Must point at a target_position, which will be the apex of the leap. +This will be client side predicted, unlike target_push +*/ +void SP_trigger_push( gentity_t *self ) { + InitTrigger (self); + + // unlike other triggers, we need to send this one to the client + self->r.svFlags &= ~SVF_NOCLIENT; + + // make sure the client precaches this sound + G_SoundIndex("sound/world/jumppad.wav"); + + self->s.eType = ET_PUSH_TRIGGER; + self->touch = trigger_push_touch; + self->think = AimAtTarget; + self->nextthink = level.time + FRAMETIME; + trap_LinkEntity (self); +} + + +void Use_target_push( gentity_t *self, gentity_t *other, gentity_t *activator ) { + if ( !activator->client ) { + return; + } + + if ( activator->client->ps.pm_type != PM_NORMAL ) { + return; + } + if ( activator->client->ps.powerups[PW_FLIGHT] ) { + return; + } + + VectorCopy (self->s.origin2, activator->client->ps.velocity); + + // play fly sound every 1.5 seconds + if ( activator->fly_sound_debounce_time < level.time ) { + activator->fly_sound_debounce_time = level.time + 1500; + G_Sound( activator, CHAN_AUTO, self->noise_index ); + } +} + +/*QUAKED target_push (.5 .5 .5) (-8 -8 -8) (8 8 8) bouncepad +Pushes the activator in the direction.of angle, or towards a target apex. +"speed" defaults to 1000 +if "bouncepad", play bounce noise instead of windfly +*/ +void SP_target_push( gentity_t *self ) { + if (!self->speed) { + self->speed = 1000; + } + G_SetMovedir (self->s.angles, self->s.origin2); + VectorScale (self->s.origin2, self->speed, self->s.origin2); + + if ( self->spawnflags & 1 ) { + self->noise_index = G_SoundIndex("sound/world/jumppad.wav"); + } else { + self->noise_index = G_SoundIndex("sound/misc/windfly.wav"); + } + if ( self->target ) { + VectorCopy( self->s.origin, self->r.absmin ); + VectorCopy( self->s.origin, self->r.absmax ); + self->think = AimAtTarget; + self->nextthink = level.time + FRAMETIME; + } + self->use = Use_target_push; +} + +/* +============================================================================== + +trigger_teleport + +============================================================================== +*/ + +void trigger_teleporter_touch (gentity_t *self, gentity_t *other, trace_t *trace ) { + gentity_t *dest; + + if ( !other->client ) { + return; + } + if ( other->client->ps.pm_type == PM_DEAD ) { + return; + } + // Spectators only? + if ( ( self->spawnflags & 1 ) && + other->client->sess.sessionTeam != TEAM_SPECTATOR ) { + return; + } + + + dest = G_PickTarget( self->target ); + if (!dest) { + G_Printf ("Couldn't find teleporter destination\n"); + return; + } + + TeleportPlayer( other, dest->s.origin, dest->s.angles ); +} + + +/*QUAKED trigger_teleport (.5 .5 .5) ? SPECTATOR +Allows client side prediction of teleportation events. +Must point at a target_position, which will be the teleport destination. + +If spectator is set, only spectators can use this teleport +Spectator teleporters are not normally placed in the editor, but are created +automatically near doors to allow spectators to move through them +*/ +void SP_trigger_teleport( gentity_t *self ) { + InitTrigger (self); + + // unlike other triggers, we need to send this one to the client + // unless is a spectator trigger + if ( self->spawnflags & 1 ) { + self->r.svFlags |= SVF_NOCLIENT; + } else { + self->r.svFlags &= ~SVF_NOCLIENT; + } + + // make sure the client precaches this sound + G_SoundIndex("sound/world/jumppad.wav"); + + self->s.eType = ET_TELEPORT_TRIGGER; + self->touch = trigger_teleporter_touch; + + trap_LinkEntity (self); +} + + +/* +============================================================================== + +trigger_hurt + +============================================================================== +*/ + +/*QUAKED trigger_hurt (.5 .5 .5) ? START_OFF - SILENT NO_PROTECTION SLOW +Any entity that touches this will be hurt. +It does dmg points of damage each server frame +Targeting the trigger will toggle its on / off state. + +SILENT supresses playing the sound +SLOW changes the damage rate to once per second +NO_PROTECTION *nothing* stops the damage + +"dmg" default 5 (whole numbers only) + +*/ +void hurt_use( gentity_t *self, gentity_t *other, gentity_t *activator ) { + if ( self->r.linked ) { + trap_UnlinkEntity( self ); + } else { + trap_LinkEntity( self ); + } +} + +void hurt_touch( gentity_t *self, gentity_t *other, trace_t *trace ) { + int dflags; + + if ( !other->takedamage ) { + return; + } + + if ( self->timestamp > level.time ) { + return; + } + + if ( self->spawnflags & 16 ) { + self->timestamp = level.time + 1000; + } else { + self->timestamp = level.time + FRAMETIME; + } + + // play sound + if ( !(self->spawnflags & 4) ) { + G_Sound( other, CHAN_AUTO, self->noise_index ); + } + + if (self->spawnflags & 8) + dflags = DAMAGE_NO_PROTECTION; + else + dflags = 0; + G_Damage (other, self, self, NULL, NULL, self->damage, dflags, MOD_TRIGGER_HURT); +} + +void SP_trigger_hurt( gentity_t *self ) { + InitTrigger (self); + + self->noise_index = G_SoundIndex( "sound/world/electro.wav" ); + self->touch = hurt_touch; + + if ( !self->damage ) { + self->damage = 5; + } + + self->r.contents = CONTENTS_TRIGGER; + + if ( self->spawnflags & 2 ) { + self->use = hurt_use; + } + + // link in to the world if starting active + if ( ! (self->spawnflags & 1) ) { + trap_LinkEntity (self); + } +} + + +/* +============================================================================== + +timer + +============================================================================== +*/ + + +/*QUAKED func_timer (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) START_ON +This should be renamed trigger_timer... +Repeatedly fires its targets. +Can be turned on or off by using. + +"wait" base time between triggering all targets, default is 1 +"random" wait variance, default is 0 +so, the basic time between firing is a random time between +(wait - random) and (wait + random) + +*/ +void func_timer_think( gentity_t *self ) { + G_UseTargets (self, self->activator); + // set time before next firing + self->nextthink = level.time + 1000 * ( self->wait + crandom() * self->random ); +} + +void func_timer_use( gentity_t *self, gentity_t *other, gentity_t *activator ) { + self->activator = activator; + + // if on, turn it off + if ( self->nextthink ) { + self->nextthink = 0; + return; + } + + // turn it on + func_timer_think (self); +} + +void SP_func_timer( gentity_t *self ) { + G_SpawnFloat( "random", "1", &self->random); + G_SpawnFloat( "wait", "1", &self->wait ); + + self->use = func_timer_use; + self->think = func_timer_think; + + if ( self->random >= self->wait ) { + self->random = self->wait - FRAMETIME; + G_Printf( "func_timer at %s has random >= wait\n", vtos( self->s.origin ) ); + } + + if ( self->spawnflags & 1 ) { + self->nextthink = level.time + FRAMETIME; + self->activator = self; + } + + self->r.svFlags = SVF_NOCLIENT; +} + + |