diff options
Diffstat (limited to 'src/game/g_trigger.c')
-rw-r--r-- | src/game/g_trigger.c | 469 |
1 files changed, 0 insertions, 469 deletions
diff --git a/src/game/g_trigger.c b/src/game/g_trigger.c deleted file mode 100644 index 739bf440..00000000 --- a/src/game/g_trigger.c +++ /dev/null @@ -1,469 +0,0 @@ -// Copyright (C) 1999-2000 Id Software, Inc. -// - -/* - * Portions Copyright (C) 2000-2001 Tim Angus - * - * This program 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, or (at your option) - * any later version. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* To assertain which portions are licensed under the GPL and which are - * licensed by Id Software, Inc. please run a diff between the equivalent - * versions of the "Tremulous" modification and the unmodified "Quake3" - * game source code. - */ - -#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_HUMANS ) { - return; - } - if ( ( ent->spawnflags & 2 ) && - activator->client->sess.sessionTeam != TEAM_DROIDS ) { - 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; -} - - |