codemp/game/g_trigger.c File Reference

#include "g_local.h"
#include "bg_saga.h"

Go to the source code of this file.

Defines

#define PUSH_LINEAR   4
#define PUSH_RELATIVE   16
#define PUSH_MULTIPLE   2048
#define PUSH_CONSTANT   2
#define INITIAL_SUFFOCATION_DELAY   500

Functions

void InitTrigger (gentity_t *self)
void multi_wait (gentity_t *ent)
void trigger_cleared_fire (gentity_t *self)
void multi_trigger_run (gentity_t *ent)
qboolean G_NameInTriggerClassList (char *list, char *str)
void SiegeItemRemoveOwner (gentity_t *ent, gentity_t *carrier)
void multi_trigger (gentity_t *ent, gentity_t *activator)
void Use_Multi (gentity_t *ent, gentity_t *other, gentity_t *activator)
qboolean G_PointInBounds (vec3_t point, vec3_t mins, vec3_t maxs)
void Touch_Multi (gentity_t *self, gentity_t *other, trace_t *trace)
void SP_trigger_multiple (gentity_t *ent)
void SP_trigger_once (gentity_t *ent)
void Do_Strike (gentity_t *ent)
void Think_Strike (gentity_t *ent)
void Use_Strike (gentity_t *ent, gentity_t *other, gentity_t *activator)
void SP_trigger_lightningstrike (gentity_t *ent)
void trigger_always_think (gentity_t *ent)
void SP_trigger_always (gentity_t *ent)
void trigger_push_touch (gentity_t *self, gentity_t *other, trace_t *trace)
void AimAtTarget (gentity_t *self)
void SP_trigger_push (gentity_t *self)
void Use_target_push (gentity_t *self, gentity_t *other, gentity_t *activator)
void SP_target_push (gentity_t *self)
void trigger_teleporter_touch (gentity_t *self, gentity_t *other, trace_t *trace)
void SP_trigger_teleport (gentity_t *self)
void hurt_use (gentity_t *self, gentity_t *other, gentity_t *activator)
void hurt_touch (gentity_t *self, gentity_t *other, trace_t *trace)
void SP_trigger_hurt (gentity_t *self)
void space_touch (gentity_t *self, gentity_t *other, trace_t *trace)
void SP_trigger_space (gentity_t *self)
void shipboundary_touch (gentity_t *self, gentity_t *other, trace_t *trace)
void shipboundary_think (gentity_t *ent)
void SP_trigger_shipboundary (gentity_t *self)
void hyperspace_touch (gentity_t *self, gentity_t *other, trace_t *trace)
void SP_trigger_hyperspace (gentity_t *self)
void func_timer_think (gentity_t *self)
void func_timer_use (gentity_t *self, gentity_t *other, gentity_t *activator)
void SP_func_timer (gentity_t *self)
gentity_tasteroid_pick_random_asteroid (gentity_t *self)
int asteroid_count_num_asteroids (gentity_t *self)
void SP_func_rotating (gentity_t *ent)
void Q3_Lerp2Origin (int taskID, int entID, vec3_t origin, float duration)
void asteroid_field_think (gentity_t *self)
void SP_trigger_asteroid_field (gentity_t *self)

Variables

int gTrigFallSound
qboolean gSiegeRoundBegun


Define Documentation

#define INITIAL_SUFFOCATION_DELAY   500
 

Definition at line 1438 of file g_trigger.c.

Referenced by space_touch().

#define PUSH_CONSTANT   2
 

Definition at line 899 of file g_trigger.c.

Referenced by AimAtTarget().

#define PUSH_LINEAR   4
 

Definition at line 895 of file g_trigger.c.

Referenced by AimAtTarget(), and trigger_push_touch().

#define PUSH_MULTIPLE   2048
 

Definition at line 897 of file g_trigger.c.

Referenced by trigger_push_touch().

#define PUSH_RELATIVE   16
 

Definition at line 896 of file g_trigger.c.

Referenced by AimAtTarget(), and trigger_push_touch().


Function Documentation

void AimAtTarget gentity_t self  ) 
 

Definition at line 1039 of file g_trigger.c.

References entityShared_t::absmax, entityShared_t::absmin, gentity_s::classname, entityShared_t::currentOrigin, G_FreeEntity(), g_gravity, G_PickTarget(), gentity_t, entityState_s::origin, entityState_s::origin2, PUSH_CONSTANT, PUSH_LINEAR, PUSH_RELATIVE, Q_stricmp(), gentity_s::r, gentity_s::s, gentity_s::spawnflags, gentity_s::speed, sqrt(), gentity_s::target, vmCvar_t::value, vec3_t, VectorAdd, VectorCopy, VectorNormalize(), VectorScale, and VectorSubtract.

Referenced by SP_target_push(), and SP_trigger_push().

01039                                     {
01040         gentity_t       *ent;
01041         vec3_t          origin;
01042         float           height, gravity, time, forward;
01043         float           dist;
01044 
01045         VectorAdd( self->r.absmin, self->r.absmax, origin );
01046         VectorScale ( origin, 0.5f, origin );
01047 
01048         ent = G_PickTarget( self->target );
01049         if ( !ent ) {
01050                 G_FreeEntity( self );
01051                 return;
01052         }
01053 
01054         if ( self->classname && !Q_stricmp( "trigger_push", self->classname ) )
01055         {
01056                 if ( (self->spawnflags&PUSH_RELATIVE) )
01057                 {//relative, not an arc or linear
01058                         VectorCopy( ent->r.currentOrigin, self->s.origin2 );
01059                         return;
01060                 }
01061                 else if ( (self->spawnflags&PUSH_LINEAR) )
01062                 {//linear, not an arc
01063                         VectorSubtract( ent->r.currentOrigin, origin, self->s.origin2 );
01064                         VectorNormalize( self->s.origin2 );
01065                         return;
01066                 }
01067         }
01068 
01069         if ( self->classname && !Q_stricmp( "target_push", self->classname ) )
01070         {
01071                 if( self->spawnflags & PUSH_CONSTANT )
01072                 {
01073                         VectorSubtract ( ent->s.origin, self->s.origin, self->s.origin2 );
01074                         VectorNormalize( self->s.origin2);
01075                         VectorScale (self->s.origin2, self->speed, self->s.origin2);
01076                         return;
01077                 }
01078         }
01079 
01080         height = ent->s.origin[2] - origin[2];
01081         gravity = g_gravity.value;
01082         time = sqrt( height / ( .5 * gravity ) );
01083         if ( !time ) {
01084                 G_FreeEntity( self );
01085                 return;
01086         }
01087 
01088         // set s.origin2 to the push velocity
01089         VectorSubtract ( ent->s.origin, origin, self->s.origin2 );
01090         self->s.origin2[2] = 0;
01091         dist = VectorNormalize( self->s.origin2);
01092 
01093         forward = dist / time;
01094         VectorScale( self->s.origin2, forward, self->s.origin2 );
01095 
01096         self->s.origin2[2] = time * gravity;
01097 }

int asteroid_count_num_asteroids gentity_t self  ) 
 

Definition at line 1836 of file g_trigger.c.

References ENTITYNUM_WORLD, g_entities, gentity_t, gentity_s::inuse, MAX_CLIENTS, entityState_s::number, entityShared_t::ownerNum, gentity_s::r, and gentity_s::s.

Referenced by asteroid_field_think().

01837 {
01838         int     i, count = 0;
01839 
01840         for ( i = MAX_CLIENTS; i < ENTITYNUM_WORLD; i++ )
01841         {
01842                 if ( !g_entities[i].inuse )
01843                 {
01844                         continue;
01845                 }
01846                 if ( g_entities[i].r.ownerNum == self->s.number )
01847                 {
01848                         count++;
01849                 }
01850         }
01851         return count;
01852 }

void asteroid_field_think gentity_t self  ) 
 

Definition at line 1856 of file g_trigger.c.

References entityState_s::angles, entityState_s::apos, asteroid_count_num_asteroids(), asteroid_pick_random_asteroid(), ceil(), gentity_s::classname, gentity_s::count, gentity_s::damage, flrand(), G_FreeEntity(), G_ScaleNetHealth(), G_SetAngles(), G_SetOrigin(), G_Spawn(), gentity_s::genericValue15, gentity_t, gentity_s::health, entityState_s::iModelScale, level, gentity_s::mass, gentity_s::material, gentity_s::maxHealth, entityShared_t::maxs, entityShared_t::mins, gentity_s::model, gentity_s::model2, gentity_s::nextthink, entityState_s::number, entityState_s::origin, entityShared_t::ownerNum, Q3_Lerp2Origin(), Q_irand(), gentity_s::r, gentity_s::radius, gentity_s::s, SP_func_rotating(), gentity_s::spawnflags, gentity_s::speed, gentity_s::think, level_locals_t::time, TR_LINEAR, trajectory_t::trDelta, trajectory_t::trTime, trajectory_t::trType, and vec3_t.

Referenced by SP_trigger_asteroid_field().

01857 {
01858         int numAsteroids = asteroid_count_num_asteroids( self );
01859 
01860         self->nextthink = level.time + 500;
01861 
01862         if ( numAsteroids < self->count )
01863         {
01864                 //need to spawn a new asteroid
01865                 gentity_t *newAsteroid = G_Spawn();
01866                 if ( newAsteroid )
01867                 {
01868                         vec3_t startSpot, endSpot, startAngles;
01869                         float dist, speed = flrand( self->speed * 0.25f, self->speed * 2.0f );
01870                         int     capAxis, axis, time = 0;
01871                         gentity_t *copyAsteroid = asteroid_pick_random_asteroid( self );
01872                         if ( copyAsteroid )
01873                         {
01874                                 newAsteroid->model = copyAsteroid->model;
01875                                 newAsteroid->model2 = copyAsteroid->model2;
01876                                 newAsteroid->health = copyAsteroid->health;
01877                                 newAsteroid->spawnflags = copyAsteroid->spawnflags;
01878                                 newAsteroid->mass = copyAsteroid->mass;
01879                                 newAsteroid->damage = copyAsteroid->damage;
01880                                 newAsteroid->speed = copyAsteroid->speed;
01881 
01882                                 G_SetOrigin( newAsteroid, copyAsteroid->s.origin );
01883                                 G_SetAngles( newAsteroid, copyAsteroid->s.angles );
01884                                 newAsteroid->classname = "func_rotating";
01885 
01886                                 SP_func_rotating( newAsteroid );
01887 
01888                                 newAsteroid->genericValue15 = copyAsteroid->genericValue15;
01889                                 newAsteroid->s.iModelScale = copyAsteroid->s.iModelScale;
01890                                 newAsteroid->maxHealth = newAsteroid->health;
01891                                 G_ScaleNetHealth(newAsteroid);
01892                                 newAsteroid->radius = copyAsteroid->radius;
01893                                 newAsteroid->material = copyAsteroid->material;
01894                                 //CacheChunkEffects( self->material );
01895 
01896                                 //keep track of it
01897                                 newAsteroid->r.ownerNum = self->s.number;
01898 
01899                                 //move it
01900                                 capAxis = Q_irand( 0, 2 );
01901                                 for ( axis = 0; axis < 3; axis++ )
01902                                 {
01903                                         if ( axis == capAxis )
01904                                         {
01905                                                 if ( Q_irand( 0, 1 ) )
01906                                                 {
01907                                                         startSpot[axis] = self->r.mins[axis];
01908                                                         endSpot[axis] = self->r.maxs[axis];
01909                                                 }
01910                                                 else
01911                                                 {
01912                                                         startSpot[axis] = self->r.maxs[axis];
01913                                                         endSpot[axis] = self->r.mins[axis];
01914                                                 }
01915                                         }
01916                                         else
01917                                         {
01918                                                 startSpot[axis] = self->r.mins[axis]+(flrand(0,1.0f)*(self->r.maxs[axis]-self->r.mins[axis]));
01919                                                 endSpot[axis] = self->r.mins[axis]+(flrand(0,1.0f)*(self->r.maxs[axis]-self->r.mins[axis]));
01920                                         }
01921                                 }
01922                                 //FIXME: maybe trace from start to end to make sure nothing is in the way?  How big of a trace?
01923 
01924                                 G_SetOrigin( newAsteroid, startSpot );
01925                                 dist = Distance( endSpot, startSpot );
01926                                 time = ceil(dist/speed)*1000;
01927                                 Q3_Lerp2Origin( -1, newAsteroid->s.number, endSpot, time );
01928 
01929                                 //spin it
01930                                 startAngles[0] = flrand( -360, 360 );
01931                                 startAngles[1] = flrand( -360, 360 );
01932                                 startAngles[2] = flrand( -360, 360 );
01933                                 G_SetAngles( newAsteroid, startAngles );
01934                                 newAsteroid->s.apos.trDelta[0] = flrand( -100, 100 );
01935                                 newAsteroid->s.apos.trDelta[1] = flrand( -100, 100 );
01936                                 newAsteroid->s.apos.trDelta[2] = flrand( -100, 100 );
01937                                 newAsteroid->s.apos.trTime = level.time;
01938                                 newAsteroid->s.apos.trType = TR_LINEAR;
01939 
01940                                 //remove itself when done
01941                                 newAsteroid->think = G_FreeEntity;
01942                                 newAsteroid->nextthink = level.time+time;
01943 
01944                                 //think again sooner if need even more
01945                                 if ( numAsteroids+1 < self->count )
01946                                 {//still need at least one more
01947                                         //spawn it in 100ms
01948                                         self->nextthink = level.time + 100;
01949                                 }
01950                         }
01951                 }
01952         }
01953 }

gentity_t* asteroid_pick_random_asteroid gentity_t self  ) 
 

Definition at line 1791 of file g_trigger.c.

References FOFS, G_Find(), gentity_t, NULL, Q_irand(), and gentity_s::target.

Referenced by asteroid_field_think().

01792 {
01793         int                     t_count = 0, pick;
01794         gentity_t       *t = NULL;
01795 
01796         while ( (t = G_Find (t, FOFS(targetname), self->target)) != NULL )
01797         {
01798                 if (t != self)
01799                 {
01800                         t_count++;
01801                 }
01802         }
01803 
01804         if(!t_count)
01805         {
01806                 return NULL;
01807         }
01808 
01809         if(t_count == 1)
01810         {
01811                 return t;
01812         }
01813 
01814         //FIXME: need a seed
01815         pick = Q_irand(1, t_count);
01816         t_count = 0;
01817         while ( (t = G_Find (t, FOFS(targetname), self->target)) != NULL )
01818         {
01819                 if (t != self)
01820                 {
01821                         t_count++;
01822                 }
01823                 else
01824                 {
01825                         continue;
01826                 }
01827                 
01828                 if(t_count == pick)
01829                 {
01830                         return t;
01831                 }
01832         }
01833         return NULL;
01834 }

void Do_Strike gentity_t ent  ) 
 

Definition at line 739 of file g_trigger.c.

References entityShared_t::absmax, entityShared_t::absmin, trace_t::allsolid, entityShared_t::currentOrigin, gentity_s::damage, trace_t::endpos, trace_t::entityNum, flrand(), G_Damage(), g_entities, G_PlayEffectID(), G_RadiusDamage(), gentity_s::genericValue2, gentity_t, gentity_s::inuse, level, MASK_PLAYERSOLID, MOD_SUICIDE, gentity_s::nextthink, NULL, entityState_s::number, gentity_s::r, gentity_s::radius, gentity_s::s, trace_t::startsolid, gentity_s::takedamage, level_locals_t::time, trap_Trace(), vec3_t, VectorCopy, and VectorSet.

Referenced by Think_Strike().

00740 {
00741         trace_t localTrace;
00742         vec3_t strikeFrom;
00743         vec3_t strikePoint;
00744         vec3_t fxAng;
00745         
00746         //maybe allow custom fx direction at some point?
00747         VectorSet(fxAng, 90.0f, 0.0f, 0.0f);
00748 
00749         //choose a random point to strike within the bounds of the trigger
00750         strikePoint[0] = flrand(ent->r.absmin[0], ent->r.absmax[0]);
00751         strikePoint[1] = flrand(ent->r.absmin[1], ent->r.absmax[1]);
00752 
00753         //consider the bottom mins the ground level
00754         strikePoint[2] = ent->r.absmin[2];
00755 
00756         //set the from point
00757         strikeFrom[0] = strikePoint[0];
00758         strikeFrom[1] = strikePoint[1];
00759         strikeFrom[2] = ent->r.absmax[2]-4.0f;
00760 
00761         //now trace for damaging stuff, and do the effect
00762         trap_Trace(&localTrace, strikeFrom, NULL, NULL, strikePoint, ent->s.number, MASK_PLAYERSOLID);
00763         VectorCopy(localTrace.endpos, strikePoint);
00764 
00765         if (localTrace.startsolid || localTrace.allsolid)
00766         { //got a bad spot, think again next frame to try another strike
00767                 ent->nextthink = level.time;
00768                 return;
00769         }
00770 
00771         if (ent->radius)
00772         { //do a radius damage at the end pos
00773                 G_RadiusDamage(strikePoint, ent, ent->damage, ent->radius, ent, NULL, MOD_SUICIDE);
00774         }
00775         else
00776         { //only damage individuals
00777                 gentity_t *trHit = &g_entities[localTrace.entityNum];
00778 
00779                 if (trHit->inuse && trHit->takedamage)
00780                 { //damage it then
00781                         G_Damage(trHit, ent, ent, NULL, trHit->r.currentOrigin, ent->damage, 0, MOD_SUICIDE);
00782                 }
00783         }
00784 
00785         G_PlayEffectID(ent->genericValue2, strikeFrom, fxAng);
00786 }

void func_timer_think gentity_t self  ) 
 

Definition at line 1750 of file g_trigger.c.

References gentity_s::activator, crandom, G_UseTargets(), gentity_t, level, gentity_s::nextthink, gentity_s::random, level_locals_t::time, and gentity_s::wait.

Referenced by func_timer_use(), and SP_func_timer().

01750                                          {
01751         G_UseTargets (self, self->activator);
01752         // set time before next firing
01753         self->nextthink = level.time + 1000 * ( self->wait + crandom() * self->random );
01754 }

void func_timer_use gentity_t self,
gentity_t other,
gentity_t activator
 

Definition at line 1756 of file g_trigger.c.

References gentity_s::activator, BSET_USE, func_timer_think(), G_ActivateBehavior(), gentity_t, and gentity_s::nextthink.

Referenced by SP_func_timer().

01756                                                                                {
01757         self->activator = activator;
01758 
01759         G_ActivateBehavior(self,BSET_USE);
01760 
01761         // if on, turn it off
01762         if ( self->nextthink ) {
01763                 self->nextthink = 0;
01764                 return;
01765         }
01766 
01767         // turn it on
01768         func_timer_think (self);
01769 }

qboolean G_NameInTriggerClassList char *  list,
char *  str
 

Definition at line 97 of file g_trigger.c.

References MAX_STRING_CHARS, Q_stricmp(), qboolean, qfalse, and qtrue.

Referenced by multi_trigger(), and Touch_Multi().

00098 {
00099         char cmp[MAX_STRING_CHARS];
00100         int i = 0;
00101         int j;
00102 
00103         while (list[i])
00104         {
00105         j = 0;
00106         while (list[i] && list[i] != '|')
00107                 {
00108                         cmp[j] = list[i];
00109                         i++;
00110                         j++;
00111                 }
00112                 cmp[j] = 0;
00113 
00114                 if (!Q_stricmp(str, cmp))
00115                 { //found it
00116                         return qtrue;
00117                 }
00118                 if (list[i] != '|')
00119                 { //reached the end and never found it
00120                         return qfalse;
00121                 }
00122                 i++;
00123         }
00124 
00125         return qfalse;
00126 }

qboolean G_PointInBounds vec3_t  point,
vec3_t  mins,
vec3_t  maxs
 

Definition at line 1877 of file g_utils.c.

References qboolean, qfalse, qtrue, and vec3_t.

Referenced by G_RunFrame(), space_touch(), and Touch_Multi().

01878 {
01879         int i;
01880 
01881         for(i = 0; i < 3; i++ )
01882         {
01883                 if ( point[i] < mins[i] )
01884                 {
01885                         return qfalse;
01886                 }
01887                 if ( point[i] > maxs[i] )
01888                 {
01889                         return qfalse;
01890                 }
01891         }
01892 
01893         return qtrue;
01894 }

void hurt_touch gentity_t self,
gentity_t other,
trace_t trace
 

Definition at line 1299 of file g_trigger.c.

References gentity_s::activator, atoi(), CHAN_VOICE, CLASS_VEHICLE, gentity_s::client, gentity_s::damage, DAMAGE_NO_PROTECTION, EF_RAG, playerState_s::eFlags, ET_NPC, entityState_s::eType, playerState_s::fallingToDeath, FL_INACTIVE, gentity_s::flags, FRAMETIME, G_Damage(), G_EntitySound(), g_gametype, G_SoundIndex(), gentity_t, GT_SIEGE, gentity_s::health, vmCvar_t::integer, gentity_s::inuse, Jetpack_Off(), level, MAX_CLIENTS, MOD_FALLING, MOD_TRIGGER_HURT, gentity_s::NPC, entityState_s::NPC_class, NULL, entityState_s::number, playerState_s::origin, playerState_s::otherKillerDebounceTime, playerState_s::otherKillerTime, gclient_s::ps, Q3_INFINITE, respawn(), gentity_s::s, gclient_s::sess, clientSession_t::sessionTeam, gentity_s::spawnflags, gentity_s::takedamage, gentity_s::team, entityState_s::teamowner, level_locals_t::time, gentity_s::timestamp, vec3_t, and VectorSet.

Referenced by SP_trigger_hurt().

01299                                                                      {
01300         int             dflags;
01301 
01302         if (g_gametype.integer == GT_SIEGE && self->team && self->team[0])
01303         {
01304                 int team = atoi(self->team);
01305 
01306                 if (other->inuse && other->s.number < MAX_CLIENTS && other->client &&
01307                         other->client->sess.sessionTeam != team)
01308                 { //real client don't hurt
01309                         return;
01310                 }
01311                 else if (other->inuse && other->client && other->s.eType == ET_NPC &&
01312                         other->s.NPC_class == CLASS_VEHICLE && other->s.teamowner != team)
01313                 { //vehicle owned by team don't hurt
01314                         return;
01315                 }
01316         }
01317 
01318         if ( self->flags & FL_INACTIVE )
01319         {//set by target_deactivate
01320                 return;
01321         }
01322 
01323         if ( !other->takedamage ) {
01324                 return;
01325         }
01326 
01327         if ( self->timestamp > level.time ) {
01328                 return;
01329         }
01330 
01331         if (self->damage == -1 && other && other->client && other->health < 1)
01332         {
01333                 other->client->ps.fallingToDeath = 0;
01334                 respawn(other);
01335                 return;
01336         }
01337 
01338         if (self->damage == -1 && other && other->client && other->client->ps.fallingToDeath)
01339         {
01340                 return;
01341         }
01342 
01343         if ( self->spawnflags & 16 ) {
01344                 self->timestamp = level.time + 1000;
01345         } else {
01346                 self->timestamp = level.time + FRAMETIME;
01347         }
01348 
01349         // play sound
01350         /*
01351         if ( !(self->spawnflags & 4) && self->damage != -1 ) {
01352                 G_Sound( other, CHAN_AUTO, self->noise_index );
01353         }
01354         */
01355 
01356         if (self->spawnflags & 8)
01357                 dflags = DAMAGE_NO_PROTECTION;
01358         else
01359                 dflags = 0;
01360 
01361         if (self->damage == -1 && other && other->client)
01362         {
01363                 if (other->client->ps.otherKillerTime > level.time)
01364                 { //we're as good as dead, so if someone pushed us into this then remember them
01365                         other->client->ps.otherKillerTime = level.time + 20000;
01366                         other->client->ps.otherKillerDebounceTime = level.time + 10000;
01367                 }
01368                 other->client->ps.fallingToDeath = level.time;
01369 
01370                 //rag on the way down, this flag will automatically be cleared for us on respawn
01371                 other->client->ps.eFlags |= EF_RAG;
01372 
01373                 //make sure his jetpack is off
01374                 Jetpack_Off(other);
01375 
01376                 if (other->NPC)
01377                 { //kill it now
01378                         vec3_t vDir;
01379 
01380                         VectorSet(vDir, 0, 1, 0);
01381                         G_Damage(other, other, other, vDir, other->client->ps.origin, Q3_INFINITE, 0, MOD_FALLING);
01382                 }
01383                 else
01384                 {
01385                         G_EntitySound(other, CHAN_VOICE, G_SoundIndex("*falling1.wav"));
01386                 }
01387 
01388                 self->timestamp = 0; //do not ignore others
01389         }
01390         else    
01391         {
01392                 int dmg = self->damage;
01393 
01394                 if (dmg == -1)
01395                 { //so fall-to-blackness triggers destroy evertyhing
01396                         dmg = 99999;
01397                         self->timestamp = 0;
01398                 }
01399                 if (self->activator && self->activator->inuse && self->activator->client)
01400                 {
01401                         G_Damage (other, self->activator, self->activator, NULL, NULL, dmg, dflags|DAMAGE_NO_PROTECTION, MOD_TRIGGER_HURT);
01402                 }
01403                 else
01404                 {
01405                         G_Damage (other, self, self, NULL, NULL, dmg, dflags|DAMAGE_NO_PROTECTION, MOD_TRIGGER_HURT);
01406                 }
01407         }
01408 }

void hurt_use gentity_t self,
gentity_t other,
gentity_t activator
 

Definition at line 1280 of file g_trigger.c.

References gentity_s::activator, BSET_USE, gentity_s::client, G_ActivateBehavior(), gentity_t, gentity_s::inuse, entityShared_t::linked, NULL, gentity_s::r, trap_LinkEntity(), and trap_UnlinkEntity().

Referenced by SP_trigger_hurt().

01280                                                                          {
01281         if (activator && activator->inuse && activator->client)
01282         {
01283                 self->activator = activator;
01284         }
01285         else
01286         {
01287                 self->activator = NULL;
01288         }
01289 
01290         G_ActivateBehavior(self,BSET_USE);
01291 
01292         if ( self->r.linked ) {
01293                 trap_UnlinkEntity( self );
01294         } else {
01295                 trap_LinkEntity( self );
01296         }
01297 }

void hyperspace_touch gentity_t self,
gentity_t other,
trace_t trace
 

Definition at line 1594 of file g_trigger.c.

References entityState_s::angles, AngleVectors(), CHAN_LOCAL, gentity_s::client, DAMAGE_NO_PROTECTION, DotProduct, EF2_HYPERSPACE, playerState_s::eFlags2, FOFS, G_Damage(), G_Error(), G_Find(), G_Sound(), G_SoundIndex(), gentity_t, HYPERSPACE_TELEPORT_FRAC, HYPERSPACE_TIME, playerState_s::hyperSpaceAngles, playerState_s::hyperSpaceTime, gentity_s::inuse, level, Vehicle_s::m_iRemovedSurfaces, playerState_s::m_iVehicleNum, Vehicle_s::m_pPilot, gentity_s::m_pVehicle, MAX_CLIENTS, MOD_SUICIDE, NULL, entityState_s::number, entityState_s::origin, playerState_s::origin, gclient_s::ps, gentity_s::s, gentity_s::target, gentity_s::target2, TeleportPlayer(), level_locals_t::time, vec3_t, VectorCopy, VectorMA, and VectorSubtract.

Referenced by SP_trigger_hyperspace().

01595 {
01596         gentity_t *ent;
01597 
01598         if (!other || !other->inuse || !other->client ||
01599                 other->s.number < MAX_CLIENTS ||
01600                 !other->m_pVehicle)
01601         { //only let vehicles touch
01602                 return;
01603         }
01604 
01605         if ( other->client->ps.hyperSpaceTime && level.time - other->client->ps.hyperSpaceTime < HYPERSPACE_TIME )
01606         {//already hyperspacing, just keep us moving
01607                 if ( (other->client->ps.eFlags2&EF2_HYPERSPACE) )
01608                 {//they've started the hyperspace but haven't been teleported yet
01609                         float timeFrac = ((float)(level.time-other->client->ps.hyperSpaceTime))/HYPERSPACE_TIME;
01610                         if ( timeFrac >= HYPERSPACE_TELEPORT_FRAC )
01611                         {//half-way, now teleport them!
01612                                 vec3_t  diff, fwd, right, up, newOrg;
01613                                 float   fDiff, rDiff, uDiff;
01614                                 //take off the flag so we only do this once
01615                                 other->client->ps.eFlags2 &= ~EF2_HYPERSPACE;
01616                                 //Get the offset from the local position
01617                                 ent = G_Find (NULL, FOFS(targetname), self->target);
01618                                 if (!ent || !ent->inuse)
01619                                 { //this is bad
01620                                         G_Error("trigger_hyperspace has invalid target '%s'\n", self->target);
01621                                         return;
01622                                 }
01623                                 VectorSubtract( other->client->ps.origin, ent->s.origin, diff );
01624                                 AngleVectors( ent->s.angles, fwd, right, up );
01625                                 fDiff = DotProduct( fwd, diff );
01626                                 rDiff = DotProduct( right, diff );
01627                                 uDiff = DotProduct( up, diff );
01628                                 //Now get the base position of the destination
01629                                 ent = G_Find (NULL, FOFS(targetname), self->target2);
01630                                 if (!ent || !ent->inuse)
01631                                 { //this is bad
01632                                         G_Error("trigger_hyperspace has invalid target2 '%s'\n", self->target2);
01633                                         return;
01634                                 }
01635                                 VectorCopy( ent->s.origin, newOrg );
01636                                 //finally, add the offset into the new origin
01637                                 AngleVectors( ent->s.angles, fwd, right, up );
01638                                 VectorMA( newOrg, fDiff, fwd, newOrg );
01639                                 VectorMA( newOrg, rDiff, right, newOrg );
01640                                 VectorMA( newOrg, uDiff, up, newOrg );
01641                                 //G_Printf("hyperspace from %s to %s\n", vtos(other->client->ps.origin), vtos(newOrg) );
01642                                 //now put them in the offset position, facing the angles that position wants them to be facing
01643                                 TeleportPlayer( other, newOrg, ent->s.angles );
01644                                 if ( other->m_pVehicle && other->m_pVehicle->m_pPilot )
01645                                 {//teleport the pilot, too
01646                                         TeleportPlayer( (gentity_t*)other->m_pVehicle->m_pPilot, newOrg, ent->s.angles );
01647                                         //FIXME: and the passengers?
01648                                 }
01649                                 //make them face the new angle
01650                                 //other->client->ps.hyperSpaceIndex = ent->s.number;
01651                                 VectorCopy( ent->s.angles, other->client->ps.hyperSpaceAngles );
01652                                 //sound
01653                                 G_Sound( other, CHAN_LOCAL, G_SoundIndex( "sound/vehicles/common/hyperend.wav" ) );
01654                         }
01655                 }
01656                 return;
01657         }
01658         else
01659         {
01660                 ent = G_Find (NULL, FOFS(targetname), self->target);
01661                 if (!ent || !ent->inuse)
01662                 { //this is bad
01663                         G_Error("trigger_hyperspace has invalid target '%s'\n", self->target);
01664                         return;
01665                 }
01666 
01667                 if (!other->client->ps.m_iVehicleNum || other->m_pVehicle->m_iRemovedSurfaces)
01668                 { //if a vehicle touches a boundary without a pilot in it or with parts missing, just blow the thing up
01669                         G_Damage(other, other, other, NULL, other->client->ps.origin, 99999, DAMAGE_NO_PROTECTION, MOD_SUICIDE);
01670                         return;
01671                 }
01672                 //other->client->ps.hyperSpaceIndex = ent->s.number;
01673                 VectorCopy( ent->s.angles, other->client->ps.hyperSpaceAngles );
01674                 other->client->ps.hyperSpaceTime = level.time;
01675         }
01676 }

void InitTrigger gentity_t self  ) 
 

Definition at line 8 of file g_trigger.c.

References entityState_s::angles, entityShared_t::contents, CONTENTS_TRIGGER, FL_INACTIVE, gentity_s::flags, G_SetMovedir(), gentity_t, gentity_s::model, gentity_s::movedir, gentity_s::r, gentity_s::s, gentity_s::spawnflags, SVF_NOCLIENT, entityShared_t::svFlags, trap_SetBrushModel(), and vec3_origin.

Referenced by SP_trigger_hurt(), SP_trigger_hyperspace(), SP_trigger_lightningstrike(), SP_trigger_multiple(), SP_trigger_once(), SP_trigger_push(), SP_trigger_shipboundary(), SP_trigger_space(), and SP_trigger_teleport().

00008                                     {
00009         if (!VectorCompare (self->s.angles, vec3_origin))
00010                 G_SetMovedir (self->s.angles, self->movedir);
00011 
00012         trap_SetBrushModel( self, self->model );
00013         self->r.contents = CONTENTS_TRIGGER;            // replaces the -1 from trap_SetBrushModel
00014         self->r.svFlags = SVF_NOCLIENT;
00015 
00016         if(self->spawnflags & 128)
00017         {
00018                 self->flags |= FL_INACTIVE;
00019         }
00020 }

void multi_trigger gentity_t ent,
gentity_t activator
 

Definition at line 130 of file g_trigger.c.

References entityShared_t::absmax, entityShared_t::absmin, gentity_s::activator, gentity_s::aimDebounceTime, gentity_s::alliedTeam, bgSiegeClasses, gentity_s::client, gentity_s::delay, EF_DEAD, playerState_s::eFlags, FL_INACTIVE, gentity_s::flags, g_entities, G_FreeEntity(), g_gametype, G_NameInTriggerClassList(), G_UseTargets2(), gentity_s::genericValue1, gentity_s::genericValue2, gentity_s::genericValue3, gentity_s::genericValue4, gentity_s::genericValue7, gentity_t, gentity_s::goaltarget, gSiegeRoundBegun, GT_SIEGE, gentity_s::health, gclient_s::holdingObjectiveItem, gentity_s::idealclass, vmCvar_t::integer, gentity_s::inuse, level, MAX_CLIENTS, MAX_GENTITIES, multi_trigger_run(), gentity_s::neverFree, gentity_s::nextthink, entityState_s::number, gentity_s::painDebounceTime, gclient_s::ps, Q_stricmp(), qboolean, qfalse, qtrue, gentity_s::r, gentity_s::s, gclient_s::sess, clientSession_t::sessionTeam, gclient_s::siegeClass, SiegeItemRemoveOwner(), SIEGETEAM_TEAM1, SIEGETEAM_TEAM2, gentity_s::spawnflags, gentity_s::target3, gentity_s::targetname, gentity_s::think, level_locals_t::time, and trap_EntitiesInBox().

Referenced by Touch_Multi(), and Use_Multi().

00131 {
00132         qboolean haltTrigger = qfalse;
00133 
00134         if ( ent->think == multi_trigger_run )
00135         {//already triggered, just waiting to run
00136                 return;
00137         }
00138 
00139         if (g_gametype.integer == GT_SIEGE &&
00140                 !gSiegeRoundBegun)
00141         { //nothing can be used til the round starts.
00142                 return;
00143         }
00144 
00145         if (g_gametype.integer == GT_SIEGE &&
00146                 activator && activator->client &&
00147                 ent->alliedTeam &&
00148                 activator->client->sess.sessionTeam != ent->alliedTeam)
00149         { //this team can't activate this trigger.
00150                 return;
00151         }
00152 
00153         if (g_gametype.integer == GT_SIEGE &&
00154                 ent->idealclass && ent->idealclass[0])
00155         { //only certain classes can activate it
00156                 if (!activator ||
00157                         !activator->client ||
00158                         activator->client->siegeClass < 0)
00159                 { //no class
00160                         return;
00161                 }
00162 
00163                 if (!G_NameInTriggerClassList(bgSiegeClasses[activator->client->siegeClass].name, ent->idealclass))
00164                 { //wasn't in the list
00165                         return;
00166                 }
00167         }
00168 
00169         if (g_gametype.integer == GT_SIEGE && ent->genericValue1)
00170         {
00171                 haltTrigger = qtrue;
00172 
00173                 if (activator && activator->client &&
00174                         activator->client->holdingObjectiveItem &&
00175                         ent->targetname && ent->targetname[0])
00176                 {
00177                         gentity_t *objItem = &g_entities[activator->client->holdingObjectiveItem];
00178 
00179                         if (objItem && objItem->inuse)
00180                         {
00181                                 if (objItem->goaltarget && objItem->goaltarget[0] &&
00182                                         !Q_stricmp(ent->targetname, objItem->goaltarget))
00183                                 {
00184                                         if (objItem->genericValue7 != activator->client->sess.sessionTeam)
00185                                         { //The carrier of the item is not on the team which disallows objective scoring for it
00186                                                 if (objItem->target3 && objItem->target3[0])
00187                                                 { //if it has a target3, fire it off instead of using the trigger
00188                                                         G_UseTargets2(objItem, objItem, objItem->target3);
00189 
00190                             //3-24-03 - want to fire off the target too I guess, if we have one.
00191                                                         if (ent->targetname && ent->targetname[0])
00192                                                         {
00193                                                                 haltTrigger = qfalse;
00194                                                         }
00195                                                 }
00196                                                 else
00197                                                 {
00198                                                         haltTrigger = qfalse;
00199                                                 }
00200 
00201                                                 //now that the item has been delivered, it can go away.
00202                                                 SiegeItemRemoveOwner(objItem, activator);
00203                                                 objItem->nextthink = 0;
00204                                                 objItem->neverFree = qfalse;
00205                                                 G_FreeEntity(objItem);
00206                                         }
00207                                 }
00208                         }
00209                 }
00210         }
00211         else if (ent->genericValue1)
00212         { //Never activate in non-siege gametype I guess.
00213                 return;
00214         }
00215 
00216         if (ent->genericValue2)
00217         { //has "teambalance" property
00218                 int i = 0;
00219                 int team1ClNum = 0;
00220                 int team2ClNum = 0;
00221                 int owningTeam = ent->genericValue3;
00222                 int newOwningTeam = 0;
00223                 int numEnts = 0;
00224                 int entityList[MAX_GENTITIES];
00225                 gentity_t *cl;
00226 
00227                 if (g_gametype.integer != GT_SIEGE)
00228                 {
00229                         return;
00230                 }
00231 
00232                 if (!activator->client ||
00233                         (activator->client->sess.sessionTeam != SIEGETEAM_TEAM1 && activator->client->sess.sessionTeam != SIEGETEAM_TEAM2))
00234                 { //activator must be a valid client to begin with
00235                         return;
00236                 }
00237 
00238                 //Count up the number of clients standing within the bounds of the trigger and the number of them on each team
00239                 numEnts = trap_EntitiesInBox( ent->r.absmin, ent->r.absmax, entityList, MAX_GENTITIES );
00240                 while (i < numEnts)
00241                 {
00242                         if (entityList[i] < MAX_CLIENTS)
00243                         { //only care about clients
00244                                 cl = &g_entities[entityList[i]];
00245 
00246                                 //the client is valid
00247                                 if (cl->inuse && cl->client &&
00248                                         (cl->client->sess.sessionTeam == SIEGETEAM_TEAM1 || cl->client->sess.sessionTeam == SIEGETEAM_TEAM2) &&
00249                                         cl->health > 0 &&
00250                                         !(cl->client->ps.eFlags & EF_DEAD))
00251                                 {
00252                                         //See which team he's on
00253                                         if (cl->client->sess.sessionTeam == SIEGETEAM_TEAM1)
00254                                         {
00255                                                 team1ClNum++;
00256                                         }
00257                                         else
00258                                         {
00259                                                 team2ClNum++;
00260                                         }
00261                                 }
00262                         }
00263                         i++;
00264                 }
00265 
00266                 if (!team1ClNum && !team2ClNum)
00267                 { //no one in the box? How did we get activated? Oh well.
00268                         return;
00269                 }
00270 
00271                 if (team1ClNum == team2ClNum)
00272                 { //if equal numbers the ownership will remain the same as it is now
00273                         return;
00274                 }
00275 
00276                 //decide who owns it now
00277                 if (team1ClNum > team2ClNum)
00278                 {
00279                         newOwningTeam = SIEGETEAM_TEAM1;
00280                 }
00281                 else
00282                 {
00283                         newOwningTeam = SIEGETEAM_TEAM2;
00284                 }
00285 
00286                 if (owningTeam == newOwningTeam)
00287                 { //it's the same one it already was, don't care then.
00288                         return;
00289                 }
00290 
00291                 //Set the new owner and set the variable which will tell us to activate a team-specific target
00292                 ent->genericValue3 = newOwningTeam;
00293                 ent->genericValue4 = newOwningTeam;
00294         }
00295 
00296         if (haltTrigger)
00297         { //This is an objective trigger and the activator is not carrying an objective item that matches the targetname.
00298                 return;
00299         }
00300 
00301         if ( ent->nextthink > level.time ) 
00302         {
00303                 if( ent->spawnflags & 2048 ) // MULTIPLE - allow multiple entities to touch this trigger in a single frame
00304                 {
00305                         if ( ent->painDebounceTime && ent->painDebounceTime != level.time )
00306                         {//this should still allow subsequent ents to fire this trigger in the current frame
00307                                 return;         // can't retrigger until the wait is over
00308                         }
00309                 }
00310                 else
00311                 {
00312                         return;
00313                 }
00314 
00315         }
00316 
00317         // if the player has already activated this trigger this frame
00318         if( activator && !activator->s.number && ent->aimDebounceTime == level.time )
00319         {
00320                 return; 
00321         }
00322 
00323         if ( ent->flags & FL_INACTIVE )
00324         {//Not active at this time
00325                 return;
00326         }
00327 
00328         ent->activator = activator;
00329 
00330         if(ent->delay && ent->painDebounceTime < (level.time + ent->delay) )
00331         {//delay before firing trigger
00332                 ent->think = multi_trigger_run;
00333                 ent->nextthink = level.time + ent->delay;
00334                 ent->painDebounceTime = level.time;
00335                 
00336         }
00337         else
00338         {
00339                 multi_trigger_run (ent);
00340         }
00341 }

void multi_trigger_run gentity_t ent  ) 
 

Definition at line 32 of file g_trigger.c.

References gentity_s::activator, gentity_s::aimDebounceTime, BSET_USE, CHAN_AUTO, gentity_s::client, entityShared_t::contents, CONTENTS_TRIGGER, crandom, CS_GLOBAL_AMBIENT_SET, G_ActivateBehavior(), G_Sound(), G_UseTargets(), G_UseTargets2(), gentity_s::genericValue4, gentity_t, level, gentity_s::nextthink, gentity_s::noise_index, gentity_s::painDebounceTime, gentity_s::r, gentity_s::random, SIEGETEAM_TEAM1, SIEGETEAM_TEAM2, gentity_s::soundSet, gentity_s::speed, gentity_s::target2, gentity_s::target3, gentity_s::target4, gentity_s::think, level_locals_t::time, trap_SetConfigstring(), trigger_cleared_fire(), gentity_s::use, and gentity_s::wait.

Referenced by multi_trigger().

00033 {
00034         ent->think = 0;
00035 
00036         G_ActivateBehavior( ent, BSET_USE );
00037 
00038         if ( ent->soundSet && ent->soundSet[0] )
00039         {
00040                 trap_SetConfigstring( CS_GLOBAL_AMBIENT_SET, ent->soundSet );
00041         }
00042 
00043         if (ent->genericValue4)
00044         { //we want to activate target3 for team1 or target4 for team2
00045                 if (ent->genericValue4 == SIEGETEAM_TEAM1 &&
00046                         ent->target3 && ent->target3[0])
00047                 {
00048                         G_UseTargets2(ent, ent->activator, ent->target3);
00049                 }
00050                 else if (ent->genericValue4 == SIEGETEAM_TEAM2 &&
00051                         ent->target4 && ent->target4[0])
00052                 {
00053                         G_UseTargets2(ent, ent->activator, ent->target4);
00054                 }
00055 
00056                 ent->genericValue4 = 0;
00057         }
00058 
00059         G_UseTargets (ent, ent->activator);
00060         if ( ent->noise_index ) 
00061         {
00062                 G_Sound( ent->activator, CHAN_AUTO, ent->noise_index );
00063         }
00064 
00065         if ( ent->target2 && ent->target2[0] && ent->wait >= 0 )
00066         {
00067                 ent->think = trigger_cleared_fire;
00068                 ent->nextthink = level.time + ent->speed;
00069         }
00070         else if ( ent->wait > 0 ) 
00071         {
00072                 if ( ent->painDebounceTime != level.time )
00073                 {//first ent to touch it this frame
00074                         //ent->e_ThinkFunc = thinkF_multi_wait;
00075                         ent->nextthink = level.time + ( ent->wait + ent->random * crandom() ) * 1000;
00076                         ent->painDebounceTime = level.time;
00077                 }
00078         } 
00079         else if ( ent->wait < 0 )
00080         {
00081                 // we can't just remove (self) here, because this is a touch function
00082                 // called while looping through area links...
00083                 ent->r.contents &= ~CONTENTS_TRIGGER;//so the EntityContact trace doesn't have to be done against me
00084                 ent->think = 0;
00085                 ent->use = 0;
00086                 //Don't remove, Icarus may barf?
00087                 //ent->nextthink = level.time + FRAMETIME;
00088                 //ent->think = G_FreeEntity;
00089         }
00090         if( ent->activator && ent->activator->client )
00091         {       // mark the trigger as being touched by the player
00092                 ent->aimDebounceTime = level.time;
00093         }
00094 }

void multi_wait gentity_t ent  ) 
 

Definition at line 23 of file g_trigger.c.

References gentity_t, and gentity_s::nextthink.

00023                                   {
00024         ent->nextthink = 0;
00025 }

void Q3_Lerp2Origin int  taskID,
int  entID,
vec3_t  origin,
float  duration
 

Definition at line 2051 of file g_ICARUScb.c.

References gentity_s::blocked, Blocked_Mover(), BMS_START, gentity_s::classname, gentity_s::client, entityShared_t::currentOrigin, gentity_s::damage, ET_MOVER, entityState_s::eType, G_DebugPrint(), g_entities, G_PlayDoorLoopSound(), G_PlayDoorSound(), gentity_t, InitMoverTrData(), level, MatchTeam(), MOVER_1TO2, MOVER_2TO1, MOVER_POS1, MOVER_POS2, moverCallback(), gentity_s::moverState, moverState_t, entityState_s::pos, gentity_s::pos1, gentity_s::pos2, Q_stricmp(), gentity_s::r, gentity_s::reached, gentity_s::s, TID_MOVE_NAV, level_locals_t::time, trap_ICARUS_TaskIDSet(), trap_LinkEntity(), trajectory_t::trDuration, vec3_t, VectorCopy, WL_ERROR, and WL_WARNING.

Referenced by asteroid_field_think(), and vmMain().

02052 {
02053         gentity_t       *ent = &g_entities[entID];
02054         moverState_t moverState;
02055 
02056         if(!ent)
02057         {
02058                 G_DebugPrint( WL_WARNING, "Q3_Lerp2Origin: invalid entID %d\n", entID);
02059                 return;
02060         }
02061         
02062         if ( ent->client || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
02063         {
02064                 G_DebugPrint( WL_ERROR, "Q3_Lerp2Origin: ent %d is NOT a mover!\n", entID);
02065                 return;
02066         }
02067 
02068         if ( ent->s.eType != ET_MOVER )
02069         {
02070                 ent->s.eType = ET_MOVER;
02071         }
02072 
02073         moverState = ent->moverState;
02074 
02075         if ( moverState == MOVER_POS1 || moverState == MOVER_2TO1 )
02076         {
02077                 VectorCopy( ent->r.currentOrigin, ent->pos1 );
02078                 VectorCopy( origin, ent->pos2 );
02079 
02080                 moverState = MOVER_1TO2;
02081         }
02082         else if ( moverState == MOVER_POS2 || moverState == MOVER_1TO2 )
02083         {
02084                 VectorCopy( ent->r.currentOrigin, ent->pos2 );
02085                 VectorCopy( origin, ent->pos1 );
02086 
02087                 moverState = MOVER_2TO1;
02088         }
02089 
02090         InitMoverTrData( ent ); //FIXME: This will probably break normal things that are being moved...
02091 
02092         ent->s.pos.trDuration = duration;
02093 
02094         // start it going
02095         MatchTeam( ent, moverState, level.time );
02096         //SetMoverState( ent, moverState, level.time );
02097 
02098         ent->reached = moverCallback;
02099         if ( ent->damage )
02100         {
02101                 ent->blocked = Blocked_Mover;
02102         }
02103         if ( taskID != -1 )
02104         {
02105                 trap_ICARUS_TaskIDSet( ent, TID_MOVE_NAV, taskID );
02106         }
02107         // starting sound
02108         G_PlayDoorLoopSound( ent );//start looping sound
02109         G_PlayDoorSound( ent, BMS_START );      //play start sound
02110 
02111         trap_LinkEntity( ent );
02112 }

void shipboundary_think gentity_t ent  ) 
 

Definition at line 1530 of file g_trigger.c.

References entityShared_t::absmax, entityShared_t::absmin, CLASS_VEHICLE, gentity_s::client, ET_NPC, entityState_s::eType, g_entities, gentity_s::genericValue7, gentity_t, gentity_s::inuse, level, playerState_s::m_iVehicleNum, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, MAX_GENTITIES, gentity_s::nextthink, entityState_s::NPC_class, NULL, gclient_s::ps, gentity_s::r, gentity_s::s, shipboundary_touch(), level_locals_t::time, trap_EntitiesInBox(), vehicleInfo_t::type, Vehicle_t, and VH_FIGHTER.

Referenced by SP_trigger_shipboundary().

01531 {
01532         int                     iEntityList[MAX_GENTITIES];
01533         int                     numListedEntities;
01534         int                     i = 0;
01535         gentity_t       *listedEnt;
01536 
01537         ent->nextthink = level.time + 100;
01538 
01539         if (ent->genericValue7 < level.time)
01540         { //don't need to be doing this check, no one has touched recently
01541                 return;
01542         }
01543 
01544         numListedEntities = trap_EntitiesInBox( ent->r.absmin, ent->r.absmax, iEntityList, MAX_GENTITIES );
01545         while (i < numListedEntities)
01546         {
01547                 listedEnt = &g_entities[iEntityList[i]];
01548                 if (listedEnt->inuse && listedEnt->client && listedEnt->client->ps.m_iVehicleNum)
01549                 {
01550             if (listedEnt->s.eType == ET_NPC &&
01551                                 listedEnt->s.NPC_class == CLASS_VEHICLE)
01552                         {
01553                                 Vehicle_t *pVeh = listedEnt->m_pVehicle;
01554                                 if (pVeh && pVeh->m_pVehicleInfo->type == VH_FIGHTER)
01555                                 {
01556                     shipboundary_touch(ent, listedEnt, NULL);
01557                                 }
01558                         }
01559                 }
01560                 i++;
01561         }
01562 }

void shipboundary_touch gentity_t self,
gentity_t other,
trace_t trace
 

Definition at line 1491 of file g_trigger.c.

References gentity_s::client, DAMAGE_NO_PROTECTION, FOFS, G_Damage(), G_Error(), G_Find(), gentity_s::genericValue1, gentity_s::genericValue7, gentity_t, HYPERSPACE_TIME, playerState_s::hyperSpaceTime, gentity_s::inuse, level, Vehicle_s::m_iRemovedSurfaces, playerState_s::m_iVehicleNum, gentity_s::m_pVehicle, MAX_CLIENTS, MOD_SUICIDE, NULL, entityState_s::number, playerState_s::origin, gclient_s::ps, gentity_s::s, gentity_s::target, level_locals_t::time, trap_LinkEntity(), playerState_s::vehTurnaroundIndex, and playerState_s::vehTurnaroundTime.

Referenced by shipboundary_think(), and SP_trigger_shipboundary().

01492 {
01493         gentity_t *ent;
01494 
01495         if (!other || !other->inuse || !other->client ||
01496                 other->s.number < MAX_CLIENTS ||
01497                 !other->m_pVehicle)
01498         { //only let vehicles touch
01499                 return;
01500         }
01501 
01502         if ( other->client->ps.hyperSpaceTime && level.time - other->client->ps.hyperSpaceTime < HYPERSPACE_TIME )
01503         {//don't interfere with hyperspacing ships
01504                 return;
01505         }
01506 
01507         ent = G_Find (NULL, FOFS(targetname), self->target);
01508         if (!ent || !ent->inuse)
01509         { //this is bad
01510                 G_Error("trigger_shipboundary has invalid target '%s'\n", self->target);
01511                 return;
01512         }
01513 
01514         if (!other->client->ps.m_iVehicleNum || other->m_pVehicle->m_iRemovedSurfaces)
01515         { //if a vehicle touches a boundary without a pilot in it or with parts missing, just blow the thing up
01516                 G_Damage(other, other, other, NULL, other->client->ps.origin, 99999, DAMAGE_NO_PROTECTION, MOD_SUICIDE);
01517                 return;
01518         }
01519 
01520         //make sure this sucker is linked so the prediction knows where to go
01521         trap_LinkEntity(ent);
01522 
01523         other->client->ps.vehTurnaroundIndex = ent->s.number;
01524         other->client->ps.vehTurnaroundTime = level.time + (self->genericValue1*2);
01525 
01526         //keep up the detailed checks for another 2 seconds
01527         self->genericValue7 = level.time + 2000;
01528 }

void SiegeItemRemoveOwner gentity_t ent,
gentity_t carrier
 

Definition at line 1338 of file g_saga.c.

References gentity_s::client, ENTITYNUM_NONE, gentity_s::genericValue2, gentity_s::genericValue8, gentity_t, gclient_s::holdingObjectiveItem, gentity_s::r, SVF_BROADCAST, and entityShared_t::svFlags.

Referenced by multi_trigger(), and SiegeItemThink().

01339 {
01340         ent->genericValue2 = 0; //Remove picked-up flag
01341 
01342         ent->genericValue8 = ENTITYNUM_NONE; //Mark entity carrying us as none
01343 
01344         if (carrier)
01345         {
01346                 carrier->client->holdingObjectiveItem = 0; //The carrier is no longer carrying us
01347                 carrier->r.svFlags &= ~SVF_BROADCAST;
01348         }
01349 }

void SP_func_rotating gentity_t ent  ) 
 

Definition at line 2121 of file g_mover.c.

References entityShared_t::absmax, entityShared_t::absmin, entityState_s::apos, entityShared_t::currentAngles, entityShared_t::currentOrigin, gentity_s::damage, EF_RADAROBJECT, entityState_s::eFlags, G_SpawnInt(), G_SpawnVector(), gentity_t, gentity_s::health, entityState_s::iModelScale, InitMover(), gentity_s::model, entityState_s::origin, entityState_s::pos, gentity_s::r, gentity_s::s, SP_func_breakable(), gentity_s::spawnflags, entityState_s::speed, gentity_s::speed, TR_LINEAR, trap_LinkEntity(), trap_SetBrushModel(), trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trType, vec3_t, and VectorCopy.

Referenced by asteroid_field_think().

02121                                        {
02122         vec3_t spinangles;
02123         if ( ent->health )
02124         {
02125                 int sav_spawnflags = ent->spawnflags;
02126                 ent->spawnflags = 0;
02127                 SP_func_breakable( ent );
02128                 ent->spawnflags = sav_spawnflags;
02129         }
02130         else
02131         {
02132                 trap_SetBrushModel( ent, ent->model );
02133                 InitMover( ent );
02134 
02135                 VectorCopy( ent->s.origin, ent->s.pos.trBase );
02136                 VectorCopy( ent->s.pos.trBase, ent->r.currentOrigin );
02137                 VectorCopy( ent->s.apos.trBase, ent->r.currentAngles );
02138 
02139                 trap_LinkEntity( ent );
02140         }
02141 
02142 #ifdef _XBOX
02143         int     tempModelScale;
02144         G_SpawnInt("model2scale", "0", &tempModelScale);
02145         ent->s.iModelScale = tempModelScale;
02146 #else
02147         G_SpawnInt("model2scale", "0", &ent->s.iModelScale);
02148 #endif
02149         if (ent->s.iModelScale < 0)
02150         {
02151                 ent->s.iModelScale = 0;
02152         }
02153         else if (ent->s.iModelScale > 1023)
02154         {
02155                 ent->s.iModelScale = 1023;
02156         }
02157 
02158         if ( G_SpawnVector( "spinangles", "0 0 0", spinangles ) )
02159         {
02160                 ent->speed = VectorLength( spinangles );
02161                 // set the axis of rotation
02162                 VectorCopy( spinangles, ent->s.apos.trDelta );
02163         }
02164         else
02165         {
02166                 if ( !ent->speed ) {
02167                         ent->speed = 100;
02168                 }
02169                 // set the axis of rotation
02170                 if ( ent->spawnflags & 4 ) {
02171                         ent->s.apos.trDelta[2] = ent->speed;
02172                 } else if ( ent->spawnflags & 8 ) {
02173                         ent->s.apos.trDelta[0] = ent->speed;
02174                 } else {
02175                         ent->s.apos.trDelta[1] = ent->speed;
02176                 }
02177         }
02178         ent->s.apos.trType = TR_LINEAR;
02179 
02180         if (!ent->damage) {
02181                 if ( (ent->spawnflags&16) )//IMPACT
02182                 {
02183                         ent->damage = 10000;
02184                 }
02185                 else
02186                 {
02187                         ent->damage = 2;
02188                 }
02189         }
02190         if ( (ent->spawnflags&2) )//RADAR
02191         {//show up on Radar at close range and play impact sound when close...?  Range based on my size
02192                 ent->s.speed = Distance( ent->r.absmin, ent->r.absmax )*0.5f;
02193                 ent->s.eFlags |= EF_RADAROBJECT;
02194         }
02195 }

void SP_func_timer gentity_t self  ) 
 

Definition at line 1771 of file g_trigger.c.

References gentity_s::activator, FRAMETIME, func_timer_think(), func_timer_use(), G_Printf(), G_SpawnFloat(), gentity_t, level, gentity_s::nextthink, entityState_s::origin, gentity_s::r, gentity_s::random, gentity_s::s, gentity_s::spawnflags, SVF_NOCLIENT, entityShared_t::svFlags, gentity_s::think, level_locals_t::time, gentity_s::use, vtos(), and gentity_s::wait.

01771                                       {
01772         G_SpawnFloat( "random", "1", &self->random);
01773         G_SpawnFloat( "wait", "1", &self->wait );
01774 
01775         self->use = func_timer_use;
01776         self->think = func_timer_think;
01777 
01778         if ( self->random >= self->wait ) {
01779                 self->random = self->wait - 1;//NOTE: was - FRAMETIME, but FRAMETIME is in msec (100) and these numbers are in *seconds*!
01780                 G_Printf( "func_timer at %s has random >= wait\n", vtos( self->s.origin ) );
01781         }
01782 
01783         if ( self->spawnflags & 1 ) {
01784                 self->nextthink = level.time + FRAMETIME;
01785                 self->activator = self;
01786         }
01787 
01788         self->r.svFlags = SVF_NOCLIENT;
01789 }

void SP_target_push gentity_t self  ) 
 

Definition at line 1168 of file g_trigger.c.

References entityShared_t::absmax, entityShared_t::absmin, AimAtTarget(), entityState_s::angles, FRAMETIME, G_SetMovedir(), G_SoundIndex(), gentity_t, level, gentity_s::nextthink, gentity_s::noise_index, entityState_s::origin, entityState_s::origin2, gentity_s::r, gentity_s::s, gentity_s::spawnflags, gentity_s::speed, gentity_s::target, gentity_s::think, level_locals_t::time, gentity_s::use, Use_target_push(), VectorCopy, and VectorScale.

01168                                        {
01169         if (!self->speed) {
01170                 self->speed = 1000;
01171         }
01172         G_SetMovedir (self->s.angles, self->s.origin2);
01173         VectorScale (self->s.origin2, self->speed, self->s.origin2);
01174 
01175         if ( self->spawnflags & 1 ) {
01176                 self->noise_index = G_SoundIndex("sound/weapons/force/jump.wav");
01177         } else {
01178                 self->noise_index = 0;  //G_SoundIndex("sound/misc/windfly.wav");
01179         }
01180         if ( self->target ) {
01181                 VectorCopy( self->s.origin, self->r.absmin );
01182                 VectorCopy( self->s.origin, self->r.absmax );
01183                 self->think = AimAtTarget;
01184                 self->nextthink = level.time + FRAMETIME;
01185         }
01186         self->use = Use_target_push;
01187 }

void SP_trigger_always gentity_t ent  ) 
 

Definition at line 880 of file g_trigger.c.

References gentity_t, level, gentity_s::nextthink, gentity_s::think, level_locals_t::time, and trigger_always_think().

00880                                         {
00881         // we must have some delay to make sure our use targets are present
00882         ent->nextthink = level.time + 300;
00883         ent->think = trigger_always_think;
00884 }

void SP_trigger_asteroid_field gentity_t self  ) 
 

Definition at line 1960 of file g_trigger.c.

References asteroid_field_think(), entityShared_t::contents, gentity_s::count, gentity_t, gentity_s::health, level, gentity_s::model, gentity_s::nextthink, gentity_s::r, gentity_s::speed, gentity_s::think, level_locals_t::time, trap_LinkEntity(), and trap_SetBrushModel().

01961 {
01962         trap_SetBrushModel( self, self->model );
01963         self->r.contents = 0;
01964 
01965         if ( !self->count )
01966         {
01967                 self->health = 20;
01968         }
01969 
01970         if ( !self->speed )
01971         {
01972                 self->speed = 10000;
01973         }
01974 
01975         self->think = asteroid_field_think;
01976         self->nextthink = level.time + 100;
01977 
01978     trap_LinkEntity(self);
01979 }

void SP_trigger_hurt gentity_t self  ) 
 

Definition at line 1410 of file g_trigger.c.

References entityShared_t::contents, CONTENTS_TRIGGER, gentity_s::damage, G_SoundIndex(), gentity_t, gTrigFallSound, hurt_touch(), hurt_use(), InitTrigger(), entityShared_t::linked, gentity_s::noise_index, gentity_s::r, gentity_s::spawnflags, gentity_s::touch, trap_LinkEntity(), trap_UnlinkEntity(), and gentity_s::use.

01410                                         {
01411         InitTrigger (self);
01412 
01413         gTrigFallSound = G_SoundIndex("*falling1.wav");
01414 
01415         self->noise_index = G_SoundIndex( "sound/weapons/force/speed.wav" );
01416         self->touch = hurt_touch;
01417 
01418         if ( !self->damage ) {
01419                 self->damage = 5;
01420         }
01421 
01422         self->r.contents = CONTENTS_TRIGGER;
01423 
01424         if ( self->spawnflags & 2 ) {
01425                 self->use = hurt_use;
01426         }
01427 
01428         // link in to the world if starting active
01429         if ( ! (self->spawnflags & 1) ) {
01430                 trap_LinkEntity (self);
01431         }
01432         else if (self->r.linked)
01433         {
01434                 trap_UnlinkEntity(self);
01435         }
01436 }

void SP_trigger_hyperspace gentity_t self  ) 
 

Definition at line 1704 of file g_trigger.c.

References entityShared_t::absmax, entityShared_t::absmin, entityShared_t::contents, CONTENTS_TRIGGER, gentity_s::delay, G_Error(), G_SoundIndex(), gentity_t, hyperspace_touch(), InitTrigger(), gentity_s::r, gentity_s::target, gentity_s::target2, gentity_s::touch, and trap_LinkEntity().

01705 {
01706         //register the hyperspace end sound (start sounds are customized)
01707         G_SoundIndex( "sound/vehicles/common/hyperend.wav" );
01708 
01709         InitTrigger(self);
01710         self->r.contents = CONTENTS_TRIGGER;
01711         
01712         if (!self->target || !self->target[0])
01713         {
01714                 G_Error("trigger_hyperspace without a target.");
01715         }
01716         if (!self->target2 || !self->target2[0])
01717         {
01718                 G_Error("trigger_hyperspace without a target2.");
01719         }
01720         
01721         self->delay = Distance( self->r.absmax, self->r.absmin );//my size
01722 
01723         self->touch = hyperspace_touch;
01724 
01725     trap_LinkEntity(self);
01726 
01727         //self->think = trigger_hyperspace_find_targets;
01728         //self->nextthink = level.time + FRAMETIME;
01729 }

void SP_trigger_lightningstrike gentity_t ent  ) 
 

Definition at line 824 of file g_trigger.c.

References Com_Error(), gentity_s::damage, ERR_DROP, G_EffectIndex(), G_SpawnString(), gentity_s::genericValue1, gentity_s::genericValue2, gentity_t, InitTrigger(), level, gentity_s::nextthink, gentity_s::random, gentity_s::spawnflags, gentity_s::think, Think_Strike(), level_locals_t::time, trap_LinkEntity(), gentity_s::use, Use_Strike(), and gentity_s::wait.

00825 {
00826         char *s;
00827 
00828         ent->use = Use_Strike;
00829         ent->think = Think_Strike;
00830         ent->nextthink = level.time + 500;
00831 
00832         G_SpawnString("lightningfx", "", &s);
00833         if (!s || !s[0])
00834         {
00835                 Com_Error(ERR_DROP, "trigger_lightningstrike with no lightningfx");
00836         }
00837 
00838         //get a configstring index for it
00839         ent->genericValue2 = G_EffectIndex(s);
00840 
00841         if (ent->spawnflags & 1)
00842         { //START_OFF
00843                 ent->genericValue1 = 1;
00844         }
00845 
00846         if (!ent->wait)
00847         { //default 1000
00848                 ent->wait = 1000;
00849         }
00850         if (!ent->random)
00851         { //default 2000
00852                 ent->random = 2000;
00853         }
00854         if (!ent->damage)
00855         { //default 50
00856                 ent->damage = 50;
00857         }
00858 
00859         InitTrigger( ent );
00860         trap_LinkEntity (ent);
00861 }

void SP_trigger_multiple gentity_t ent  ) 
 

Definition at line 607 of file g_trigger.c.

References gentity_s::alliedTeam, atoi(), Com_Printf(), gentity_s::delay, FRAMETIME, G_SoundIndex(), G_SpawnInt(), G_SpawnString(), gentity_s::genericValue1, gentity_s::genericValue2, gentity_s::genericValue7, gentity_t, InitTrigger(), gentity_s::noise_index, NULL, gentity_s::random, S_COLOR_YELLOW, gentity_s::speed, gentity_s::target2, gentity_s::team, gentity_s::touch, Touch_Multi(), trap_LinkEntity(), gentity_s::use, Use_Multi(), and gentity_s::wait.

00608 {
00609         char    *s;
00610         if ( G_SpawnString( "noise", "", &s ) ) 
00611         {
00612                 if (s && s[0])
00613                 {
00614                         ent->noise_index = G_SoundIndex(s);
00615                 }
00616                 else
00617                 {
00618                         ent->noise_index = 0;
00619                 }
00620         }
00621 
00622         G_SpawnInt("usetime", "0", &ent->genericValue7);
00623 
00624         //For siege gametype
00625         G_SpawnInt("siegetrig", "0", &ent->genericValue1);
00626     G_SpawnInt("teambalance", "0", &ent->genericValue2);
00627 
00628         G_SpawnInt("delay", "0", &ent->delay);
00629 
00630         if ( (ent->wait > 0) && (ent->random >= ent->wait) ) {
00631                 ent->random = ent->wait - FRAMETIME;
00632                 Com_Printf(S_COLOR_YELLOW"trigger_multiple has random >= wait\n");
00633         }
00634 
00635         ent->delay *= 1000;//1 = 1 msec, 1000 = 1 sec
00636         if ( !ent->speed && ent->target2 && ent->target2[0] )
00637         {
00638                 ent->speed = 1000;
00639         }
00640         else
00641         {
00642                 ent->speed *= 1000;
00643         }
00644 
00645         ent->touch = Touch_Multi;
00646         ent->use   = Use_Multi;
00647 
00648         if ( ent->team && ent->team[0] )
00649         {
00650                 ent->alliedTeam = atoi(ent->team);
00651                 ent->team = NULL;
00652         }
00653 
00654         InitTrigger( ent );
00655         trap_LinkEntity (ent);
00656 }

void SP_trigger_once gentity_t ent  ) 
 

Definition at line 694 of file g_trigger.c.

References gentity_s::alliedTeam, atoi(), gentity_s::delay, G_SoundIndex(), G_SpawnInt(), G_SpawnString(), gentity_s::genericValue1, gentity_s::genericValue7, gentity_t, InitTrigger(), gentity_s::noise_index, NULL, gentity_s::team, gentity_s::touch, Touch_Multi(), trap_LinkEntity(), gentity_s::use, Use_Multi(), and gentity_s::wait.

00695 {
00696         char    *s;
00697         if ( G_SpawnString( "noise", "", &s ) ) 
00698         {
00699                 if (s && s[0])
00700                 {
00701                         ent->noise_index = G_SoundIndex(s);
00702                 }
00703                 else
00704                 {
00705                         ent->noise_index = 0;
00706                 }
00707         }
00708 
00709         G_SpawnInt("usetime", "0", &ent->genericValue7);
00710 
00711         //For siege gametype
00712         G_SpawnInt("siegetrig", "0", &ent->genericValue1);
00713 
00714         G_SpawnInt("delay", "0", &ent->delay);
00715 
00716         ent->wait = -1;
00717 
00718         ent->touch = Touch_Multi;
00719         ent->use   = Use_Multi;
00720 
00721         if ( ent->team && ent->team[0] )
00722         {
00723                 ent->alliedTeam = atoi(ent->team);
00724                 ent->team = NULL;
00725         }
00726 
00727         ent->delay *= 1000;//1 = 1 msec, 1000 = 1 sec
00728 
00729         InitTrigger( ent );
00730         trap_LinkEntity (ent);
00731 }

void SP_trigger_push gentity_t self  ) 
 

Definition at line 1112 of file g_trigger.c.

References AimAtTarget(), ET_PUSH_TRIGGER, entityState_s::eType, FRAMETIME, G_SoundIndex(), gentity_t, InitTrigger(), level, gentity_s::nextthink, gentity_s::r, gentity_s::s, gentity_s::spawnflags, gentity_s::speed, SVF_NOCLIENT, entityShared_t::svFlags, gentity_s::think, level_locals_t::time, gentity_s::touch, trap_LinkEntity(), and trigger_push_touch().

01112                                         {
01113         InitTrigger (self);
01114 
01115         // unlike other triggers, we need to send this one to the client
01116         self->r.svFlags &= ~SVF_NOCLIENT;
01117 
01118         // make sure the client precaches this sound
01119         G_SoundIndex("sound/weapons/force/jump.wav");
01120 
01121         self->s.eType = ET_PUSH_TRIGGER;
01122         
01123         if ( !(self->spawnflags&2) )
01124         {//start on
01125                 self->touch = trigger_push_touch;
01126         }
01127 
01128         if ( self->spawnflags & 4 )
01129         {//linear
01130                 self->speed = 1000;
01131         }
01132 
01133         self->think = AimAtTarget;
01134         self->nextthink = level.time + FRAMETIME;
01135         trap_LinkEntity (self);
01136 }

void SP_trigger_shipboundary gentity_t self  ) 
 

Definition at line 1571 of file g_trigger.c.

References entityShared_t::contents, CONTENTS_TRIGGER, G_Error(), G_SpawnInt(), gentity_s::genericValue1, gentity_t, InitTrigger(), level, gentity_s::nextthink, gentity_s::r, shipboundary_think(), shipboundary_touch(), gentity_s::target, gentity_s::think, level_locals_t::time, gentity_s::touch, and trap_LinkEntity().

01572 {
01573         InitTrigger(self);
01574         self->r.contents = CONTENTS_TRIGGER;
01575         
01576         if (!self->target || !self->target[0])
01577         {
01578                 G_Error("trigger_shipboundary without a target.");
01579         }
01580         G_SpawnInt("traveltime", "0", &self->genericValue1);
01581 
01582         if (!self->genericValue1)
01583         {
01584                 G_Error("trigger_shipboundary without traveltime.");
01585         }
01586 
01587         self->think = shipboundary_think;
01588         self->nextthink = level.time + 500;
01589         self->touch = shipboundary_touch;
01590 
01591     trap_LinkEntity(self);
01592 }

void SP_trigger_space gentity_t self  ) 
 

Definition at line 1481 of file g_trigger.c.

References entityShared_t::contents, CONTENTS_TRIGGER, gentity_t, InitTrigger(), gentity_s::r, space_touch(), gentity_s::touch, and trap_LinkEntity().

01482 {
01483         InitTrigger(self);
01484         self->r.contents = CONTENTS_TRIGGER;
01485         
01486         self->touch = space_touch;
01487 
01488     trap_LinkEntity(self);
01489 }

void SP_trigger_teleport gentity_t self  ) 
 

Definition at line 1236 of file g_trigger.c.

References ET_TELEPORT_TRIGGER, entityState_s::eType, G_SoundIndex(), gentity_t, InitTrigger(), gentity_s::r, gentity_s::s, gentity_s::spawnflags, SVF_NOCLIENT, entityShared_t::svFlags, gentity_s::touch, trap_LinkEntity(), and trigger_teleporter_touch().

01236                                             {
01237         InitTrigger (self);
01238 
01239         // unlike other triggers, we need to send this one to the client
01240         // unless is a spectator trigger
01241         if ( self->spawnflags & 1 ) {
01242                 self->r.svFlags |= SVF_NOCLIENT;
01243         } else {
01244                 self->r.svFlags &= ~SVF_NOCLIENT;
01245         }
01246 
01247         // make sure the client precaches this sound
01248         G_SoundIndex("sound/weapons/force/speed.wav");
01249 
01250         self->s.eType = ET_TELEPORT_TRIGGER;
01251         self->touch = trigger_teleporter_touch;
01252 
01253         trap_LinkEntity (self);
01254 }

void space_touch gentity_t self,
gentity_t other,
trace_t trace
 

Definition at line 1439 of file g_trigger.c.

References entityShared_t::absmax, entityShared_t::absmin, gentity_s::client, ENTITYNUM_NONE, g_entities, G_PointInBounds(), gentity_t, vehicleInfo_t::hideRider, INITIAL_SUFFOCATION_DELAY, gclient_s::inSpaceIndex, gclient_s::inSpaceSuffocation, gentity_s::inuse, level, playerState_s::m_iVehicleNum, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, MAX_CLIENTS, entityState_s::number, playerState_s::origin, gclient_s::ps, gentity_s::r, gentity_s::s, and level_locals_t::time.

Referenced by SP_trigger_space().

01440 {
01441         if (!other || !other->inuse || !other->client )
01442                 //NOTE: we need vehicles to know this, too...
01443                 //|| other->s.number >= MAX_CLIENTS)
01444         {
01445                 return;
01446         }
01447 
01448         if ( other->s.number < MAX_CLIENTS//player
01449                 && other->client->ps.m_iVehicleNum//in a vehicle
01450                 && other->client->ps.m_iVehicleNum >= MAX_CLIENTS )
01451         {//a player client inside a vehicle
01452                 gentity_t *veh = &g_entities[other->client->ps.m_iVehicleNum];
01453 
01454                 if (veh->inuse && veh->client && veh->m_pVehicle &&
01455                         veh->m_pVehicle->m_pVehicleInfo->hideRider)
01456                 { //if they are "inside" a vehicle, then let that protect them from THE HORRORS OF SPACE.
01457                         other->client->inSpaceSuffocation = 0;
01458                         other->client->inSpaceIndex = ENTITYNUM_NONE;
01459                         return;
01460                 }
01461         }
01462 
01463         if (!G_PointInBounds(other->client->ps.origin, self->r.absmin, self->r.absmax))
01464         { //his origin must be inside the trigger
01465                 return;
01466         }
01467 
01468         if (!other->client->inSpaceIndex ||
01469                 other->client->inSpaceIndex == ENTITYNUM_NONE)
01470         { //freshly entering space
01471                 other->client->inSpaceSuffocation = level.time + INITIAL_SUFFOCATION_DELAY;
01472         }
01473 
01474         other->client->inSpaceIndex = self->s.number;
01475 }

void Think_Strike gentity_t ent  ) 
 

Definition at line 789 of file g_trigger.c.

References Do_Strike(), gentity_s::genericValue1, gentity_t, level, gentity_s::nextthink, Q_irand(), gentity_s::random, level_locals_t::time, and gentity_s::wait.

Referenced by SP_trigger_lightningstrike().

00790 {
00791         if (ent->genericValue1)
00792         { //turned off currently
00793                 return;
00794         }
00795 
00796         ent->nextthink = level.time + ent->wait + Q_irand(0, ent->random);
00797         Do_Strike(ent);
00798 }

void Touch_Multi gentity_t self,
gentity_t other,
trace_t trace
 

Definition at line 350 of file g_trigger.c.

References entityShared_t::absmax, entityShared_t::absmin, gentity_s::alliedTeam, AngleVectors(), bgSiegeClasses, BOTH_BUTTON_HOLD, BOTH_CONSOLE1, BUTTON_ALT_ATTACK, BUTTON_ATTACK, BUTTON_USE, usercmd_s::buttons, gentity_s::client, clientPersistant_t::cmd, DotProduct, ET_NPC, entityState_s::eType, FL_INACTIVE, gentity_s::flags, playerState_s::forceHandExtend, g_gametype, G_NameInTriggerClassList(), G_PointInBounds(), G_SetAnim(), gentity_s::genericValue7, gentity_t, GT_SIEGE, gclient_s::hackingAngles, playerState_s::hackingBaseTime, playerState_s::hackingTime, HANDEXTEND_NONE, gentity_s::health, gentity_s::idealclass, vmCvar_t::integer, gclient_s::isHacking, level, MAX_CLIENTS, gentity_s::movedir, multi_trigger(), gentity_s::nextthink, gentity_s::NPC, gentity_s::NPC_targetname, NULL, entityState_s::number, playerState_s::origin, gclient_s::pers, playerState_s::pm_flags, PMF_FOLLOW, gclient_s::ps, Q_stricmp(), gentity_s::r, gentity_s::radius, gentity_s::s, gentity_s::script_targetname, gclient_s::sess, clientSession_t::sessionTeam, SETANIM_FLAG_HOLD, SETANIM_FLAG_OVERRIDE, SETANIM_TORSO, gclient_s::siegeClass, gentity_s::spawnflags, gentity_s::speed, TEAM_SPECTATOR, gentity_s::think, level_locals_t::time, playerState_s::torsoAnim, playerState_s::torsoTimer, trigger_cleared_fire(), vec3_t, VectorCopy, playerState_s::viewangles, playerState_s::viewheight, and playerState_s::weaponTime.

Referenced by SP_trigger_multiple(), and SP_trigger_once().

00351 {
00352         if( !other->client ) 
00353         {
00354                 return;
00355         }
00356 
00357         if ( self->flags & FL_INACTIVE )
00358         {//set by target_deactivate
00359                 return;
00360         }
00361 
00362         if( self->alliedTeam )
00363         {
00364                 if ( other->client->sess.sessionTeam != self->alliedTeam )
00365                 {
00366                         return;
00367                 }
00368         }
00369 
00370 // moved to just above multi_trigger because up here it just checks if the trigger is not being touched
00371 // we want it to check any conditions set on the trigger, if one of those isn't met, the trigger is considered to be "cleared"
00372 //      if ( self->e_ThinkFunc == thinkF_trigger_cleared_fire )
00373 //      {//We're waiting to fire our target2 first
00374 //              self->nextthink = level.time + self->speed;
00375 //              return;
00376 //      }
00377 
00378         if ( self->spawnflags & 1 )
00379         {
00380                 if ( other->s.eType == ET_NPC )
00381                 {
00382                         return;
00383                 }
00384         }
00385         else
00386         {
00387                 if ( self->spawnflags & 16 )
00388                 {//NPCONLY
00389                         if ( other->NPC == NULL )
00390                         {
00391                                 return;
00392                         }
00393                 }
00394 
00395                 if ( self->NPC_targetname && self->NPC_targetname[0] )
00396                 {
00397                         if ( other->script_targetname && other->script_targetname[0] )
00398                         {
00399                                 if ( Q_stricmp( self->NPC_targetname, other->script_targetname ) != 0 )
00400                                 {//not the right guy to fire me off
00401                                         return;
00402                                 }
00403                         }
00404                         else
00405                         {
00406                                 return;
00407                         }
00408                 }
00409         }
00410 
00411         if ( self->spawnflags & 2 )
00412         {//FACING
00413                 vec3_t  forward;
00414 
00415                 AngleVectors( other->client->ps.viewangles, forward, NULL, NULL );
00416 
00417                 if ( DotProduct( self->movedir, forward ) < 0.5 )
00418                 {//Not Within 45 degrees
00419                         return;
00420                 }
00421         }
00422 
00423         if ( self->spawnflags & 4 )
00424         {//USE_BUTTON
00425                 if( !( other->client->pers.cmd.buttons & BUTTON_USE ) )
00426                 {//not pressing use button
00427                         return;
00428                 }
00429 
00430                 if ((other->client->ps.weaponTime > 0 && other->client->ps.torsoAnim != BOTH_BUTTON_HOLD && other->client->ps.torsoAnim != BOTH_CONSOLE1) || other->health < 1 ||
00431                         (other->client->ps.pm_flags & PMF_FOLLOW) || other->client->sess.sessionTeam == TEAM_SPECTATOR ||
00432                         other->client->ps.forceHandExtend != HANDEXTEND_NONE)
00433                 { //player has to be free of other things to use.
00434                         return;
00435                 }
00436 
00437                 if (self->genericValue7)
00438                 { //we have to be holding the use key in this trigger for x milliseconds before firing
00439                         if (g_gametype.integer == GT_SIEGE &&
00440                                 self->idealclass && self->idealclass[0])
00441                         { //only certain classes can activate it
00442                                 if (!other ||
00443                                         !other->client ||
00444                                         other->client->siegeClass < 0)
00445                                 { //no class
00446                                         return;
00447                                 }
00448 
00449                                 if (!G_NameInTriggerClassList(bgSiegeClasses[other->client->siegeClass].name, self->idealclass))
00450                                 { //wasn't in the list
00451                                         return;
00452                                 }
00453                         }
00454 
00455                         if (!G_PointInBounds( other->client->ps.origin, self->r.absmin, self->r.absmax ))
00456                         {
00457                                 return;
00458                         }
00459                         else if (other->client->isHacking != self->s.number && other->s.number < MAX_CLIENTS )
00460                         { //start the hack
00461                                 other->client->isHacking = self->s.number;
00462                                 VectorCopy(other->client->ps.viewangles, other->client->hackingAngles);
00463                                 other->client->ps.hackingTime = level.time + self->genericValue7;
00464                                 other->client->ps.hackingBaseTime = self->genericValue7;
00465                                 if (other->client->ps.hackingBaseTime > 60000)
00466                                 { //don't allow a bit overflow
00467                                         other->client->ps.hackingTime = level.time + 60000;
00468                                         other->client->ps.hackingBaseTime = 60000;
00469                                 }
00470                                 return;
00471                         }
00472                         else if (other->client->ps.hackingTime < level.time)
00473                         { //finished with the hack, reset the hacking values and let it fall through
00474                                 other->client->isHacking = 0; //can't hack a client
00475                                 other->client->ps.hackingTime = 0;
00476                         }
00477                         else
00478                         { //hack in progress
00479                                 return;
00480                         }
00481                 }
00482         }
00483 
00484         if ( self->spawnflags & 8 )
00485         {//FIRE_BUTTON
00486                 if( !( other->client->pers.cmd.buttons & BUTTON_ATTACK ) &&
00487                         !( other->client->pers.cmd.buttons & BUTTON_ALT_ATTACK ) )
00488                 {//not pressing fire button or altfire button
00489                         return;
00490                 }
00491         }
00492 
00493         if ( self->radius )
00494         {
00495                 vec3_t  eyeSpot;
00496 
00497                 //Only works if your head is in it, but we allow leaning out
00498                 //NOTE: We don't use CalcEntitySpot SPOT_HEAD because we don't want this
00499                 //to be reliant on the physical model the player uses.
00500                 VectorCopy(other->client->ps.origin, eyeSpot);
00501                 eyeSpot[2] += other->client->ps.viewheight;
00502 
00503                 if ( G_PointInBounds( eyeSpot, self->r.absmin, self->r.absmax ) )
00504                 {
00505                         if( !( other->client->pers.cmd.buttons & BUTTON_ATTACK ) &&
00506                                 !( other->client->pers.cmd.buttons & BUTTON_ALT_ATTACK ) )
00507                         {//not attacking, so hiding bonus
00508                                 /*
00509                                 //FIXME:  should really have sound events clear the hiddenDist
00510                                 other->client->hiddenDist = self->radius;
00511                                 //NOTE: movedir HAS to be normalized!
00512                                 if ( VectorLength( self->movedir ) )
00513                                 {//They can only be hidden from enemies looking in this direction
00514                                         VectorCopy( self->movedir, other->client->hiddenDir );
00515                                 }
00516                                 else
00517                                 {
00518                                         VectorClear( other->client->hiddenDir );
00519                                 }
00520                                 */
00521                                 //Not using this, at least not yet.
00522                         }
00523                 }
00524         }
00525 
00526         if ( self->spawnflags & 4 )
00527         {//USE_BUTTON
00528                 if (other->client->ps.torsoAnim != BOTH_BUTTON_HOLD &&
00529                         other->client->ps.torsoAnim != BOTH_CONSOLE1)
00530                 {
00531                         G_SetAnim( other, NULL, SETANIM_TORSO, BOTH_BUTTON_HOLD, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0 );
00532                 }
00533                 else
00534                 {
00535                         other->client->ps.torsoTimer = 500;
00536                 }
00537                 other->client->ps.weaponTime = other->client->ps.torsoTimer;
00538         }
00539         
00540         if ( self->think == trigger_cleared_fire )
00541         {//We're waiting to fire our target2 first
00542                 self->nextthink = level.time + self->speed;
00543                 return;
00544         }
00545 
00546         multi_trigger( self, other );
00547 }

void trigger_always_think gentity_t ent  ) 
 

Definition at line 872 of file g_trigger.c.

References G_FreeEntity(), G_UseTargets(), and gentity_t.

Referenced by SP_trigger_always().

00872                                             {
00873         G_UseTargets(ent, ent);
00874         G_FreeEntity( ent );
00875 }

void trigger_cleared_fire gentity_t self  ) 
 

Definition at line 549 of file g_trigger.c.

References gentity_s::activator, crandom, G_UseTargets2(), gentity_t, level, gentity_s::nextthink, gentity_s::random, gentity_s::target2, gentity_s::think, level_locals_t::time, and gentity_s::wait.

Referenced by multi_trigger_run(), and Touch_Multi().

00550 {
00551         G_UseTargets2( self, self->activator, self->target2 );
00552         self->think = 0;
00553         // should start the wait timer now, because the trigger's just been cleared, so we must "wait" from this point
00554         if ( self->wait > 0 ) 
00555         {
00556                 self->nextthink = level.time + ( self->wait + self->random * crandom() ) * 1000;
00557         }
00558 }

void trigger_push_touch gentity_t self,
gentity_t other,
trace_t trace
 

Definition at line 901 of file g_trigger.c.

References BG_TouchJumpPad(), gentity_s::client, entityShared_t::currentOrigin, FL_INACTIVE, gentity_s::flags, gentity_t, level, NULL, entityState_s::origin2, gentity_s::painDebounceTime, PM_DEAD, PM_FREEZE, PM_NORMAL, playerState_s::pm_type, entityState_s::pos, gclient_s::ps, PUSH_LINEAR, PUSH_MULTIPLE, PUSH_RELATIVE, gentity_s::r, gentity_s::s, gentity_s::spawnflags, gentity_s::speed, level_locals_t::time, gentity_s::touch, TR_LINEAR_STOP, TR_NONLINEAR_STOP, TR_STATIONARY, trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trTime, trajectory_t::trType, vec3_t, VectorCopy, VectorNormalize(), VectorScale, VectorSubtract, playerState_s::velocity, and gentity_s::wait.

Referenced by SP_trigger_push().

00901                                                                              {
00902         if ( self->flags & FL_INACTIVE )
00903         {//set by target_deactivate
00904                 return;
00905         }
00906 
00907         if ( !(self->spawnflags&PUSH_LINEAR) )
00908         {//normal throw
00909                 if ( !other->client ) {
00910                         return;
00911                 }
00912                 BG_TouchJumpPad( &other->client->ps, &self->s );
00913                 return;
00914         }
00915 
00916         //linear
00917         if( level.time < self->painDebounceTime + self->wait  ) // normal 'wait' check
00918         {
00919                 if( self->spawnflags & PUSH_MULTIPLE ) // MULTIPLE - allow multiple entities to touch this trigger in one frame
00920                 {
00921                         if ( self->painDebounceTime && level.time > self->painDebounceTime ) // if we haven't reached the next frame continue to let ents touch the trigger
00922                         {
00923                                 return;
00924                         }
00925                 }
00926                 else // only allowing one ent per frame to touch trigger
00927                 {
00928                         return;
00929                 }
00930         }
00931 
00932         /*
00933         //???
00934         // if the player has already activated this trigger this frame
00935         if( other && !other->s.number && self->aimDebounceTime == level.time )
00936         {
00937                 return;         
00938         }
00939         */
00940         
00941         /*
00942         if( self->spawnflags & PUSH_CONVEYOR )
00943         {   // only push player if he's on the ground
00944                 if( other->s.groundEntityNum == ENTITYNUM_NONE )
00945                 {
00946                         return;
00947                 }
00948         }
00949         */
00950 
00951         /*
00952         if ( self->spawnflags & 1 )
00953         {//PLAYERONLY
00954                 if ( other->s.number >= MAX_CLIENTS )
00955                 {
00956                         return;
00957                 }
00958         }
00959         else
00960         {
00961                 if ( self->spawnflags & 8 )
00962                 {//NPCONLY
00963                         if ( other->NPC == NULL )
00964                         {
00965                                 return;
00966                         }
00967                 }
00968         }
00969         */
00970 
00971         if ( !other->client ) {
00972                 if ( other->s.pos.trType != TR_STATIONARY && other->s.pos.trType != TR_LINEAR_STOP && other->s.pos.trType != TR_NONLINEAR_STOP && VectorLengthSquared( other->s.pos.trDelta ) )
00973                 {//already moving
00974                         VectorCopy( other->r.currentOrigin, other->s.pos.trBase );
00975                         VectorCopy( self->s.origin2, other->s.pos.trDelta );
00976                         other->s.pos.trTime = level.time;
00977                 }
00978                 return;
00979         }
00980 
00981         if ( other->client->ps.pm_type != PM_NORMAL 
00982                 && other->client->ps.pm_type != PM_DEAD 
00983                 && other->client->ps.pm_type != PM_FREEZE ) 
00984         {
00985                 return;
00986         }
00987         
00988         if ( (self->spawnflags&PUSH_RELATIVE) )
00989         {//relative, dir to it * speed
00990                 vec3_t dir;
00991                 VectorSubtract( self->s.origin2, other->r.currentOrigin, dir );
00992                 if ( self->speed )
00993                 {
00994                         VectorNormalize( dir );
00995                         VectorScale( dir, self->speed, dir );
00996                 }
00997                 VectorCopy( dir, other->client->ps.velocity );
00998         }
00999         else if ( (self->spawnflags&PUSH_LINEAR) )
01000         {//linear dir * speed
01001                 VectorScale( self->s.origin2, self->speed, other->client->ps.velocity );
01002         }
01003         else
01004         {
01005                 VectorCopy( self->s.origin2, other->client->ps.velocity );
01006         }
01007         //so we don't take damage unless we land lower than we start here...
01008         /*
01009         other->client->ps.forceJumpZStart = 0;
01010         other->client->ps.pm_flags |= PMF_TRIGGER_PUSHED;//pushed by a trigger
01011         other->client->ps.jumpZStart = other->client->ps.origin[2];
01012         */
01013 
01014         if ( self->wait == -1 )
01015         {
01016                 self->touch = NULL;
01017         }
01018         else if ( self->wait > 0 )
01019         {
01020                 self->painDebounceTime = level.time;
01021                 
01022         }
01023         /*
01024         if( other && !other->s.number )
01025         {       // mark that the player has activated this trigger this frame
01026                 self->aimDebounceTime =level.time;
01027         }
01028         */
01029 }

void trigger_teleporter_touch gentity_t self,
gentity_t other,
trace_t trace
 

Definition at line 1197 of file g_trigger.c.

References entityState_s::angles, gentity_s::client, FL_INACTIVE, gentity_s::flags, G_PickTarget(), G_Printf(), gentity_t, entityState_s::origin, PM_DEAD, playerState_s::pm_type, gclient_s::ps, gentity_s::s, gclient_s::sess, clientSession_t::sessionTeam, gentity_s::spawnflags, gentity_s::target, TEAM_SPECTATOR, and TeleportPlayer().

Referenced by SP_trigger_teleport().

01197                                                                                    {
01198         gentity_t       *dest;
01199 
01200         if ( self->flags & FL_INACTIVE )
01201         {//set by target_deactivate
01202                 return;
01203         }
01204 
01205         if ( !other->client ) {
01206                 return;
01207         }
01208         if ( other->client->ps.pm_type == PM_DEAD ) {
01209                 return;
01210         }
01211         // Spectators only?
01212         if ( ( self->spawnflags & 1 ) && 
01213                 other->client->sess.sessionTeam != TEAM_SPECTATOR ) {
01214                 return;
01215         }
01216 
01217 
01218         dest =  G_PickTarget( self->target );
01219         if (!dest) {
01220                 G_Printf ("Couldn't find teleporter destination\n");
01221                 return;
01222         }
01223 
01224         TeleportPlayer( other, dest->s.origin, dest->s.angles );
01225 }

void Use_Multi gentity_t ent,
gentity_t other,
gentity_t activator
 

Definition at line 343 of file g_trigger.c.

References gentity_t, and multi_trigger().

Referenced by SP_trigger_multiple(), and SP_trigger_once().

00344 {
00345         multi_trigger( ent, activator );
00346 }

void Use_Strike gentity_t ent,
gentity_t other,
gentity_t activator
 

Definition at line 801 of file g_trigger.c.

References gentity_s::genericValue1, gentity_t, level, gentity_s::nextthink, and level_locals_t::time.

Referenced by SP_trigger_lightningstrike().

00802 {
00803         ent->genericValue1 = !ent->genericValue1;
00804 
00805         if (!ent->genericValue1)
00806         { //turn it back on
00807                 ent->nextthink = level.time;
00808         }
00809 }

void Use_target_push gentity_t self,
gentity_t other,
gentity_t activator
 

Definition at line 1138 of file g_trigger.c.

References BSET_USE, CHAN_AUTO, gentity_s::client, gentity_s::fly_sound_debounce_time, G_ActivateBehavior(), G_Sound(), gentity_t, level, gentity_s::noise_index, entityState_s::origin2, PM_FLOAT, PM_NORMAL, playerState_s::pm_type, gclient_s::ps, gentity_s::s, level_locals_t::time, VectorCopy, and playerState_s::velocity.

Referenced by SP_target_push().

01138                                                                                 {
01139         if ( !activator->client ) {
01140                 return;
01141         }
01142 
01143         if ( activator->client->ps.pm_type != PM_NORMAL && activator->client->ps.pm_type != PM_FLOAT ) {
01144                 return;
01145         }
01146 
01147         G_ActivateBehavior(self,BSET_USE);
01148 
01149         VectorCopy (self->s.origin2, activator->client->ps.velocity);
01150 
01151         // play fly sound every 1.5 seconds
01152         if ( activator->fly_sound_debounce_time < level.time ) {
01153                 activator->fly_sound_debounce_time = level.time + 1500;
01154                 if (self->noise_index)
01155                 {
01156                         G_Sound( activator, CHAN_AUTO, self->noise_index );
01157                 }
01158         }
01159 }


Variable Documentation

qboolean gSiegeRoundBegun
 

Definition at line 128 of file g_trigger.c.

int gTrigFallSound
 

Definition at line 6 of file g_trigger.c.

Referenced by SP_trigger_hurt().