static void target_relay_use( edict_t *self, edict_t *other, edict_t *activator ) { if( ( self->spawnflags & 1 ) != 0 && activator->r.client && activator->s.team != TEAM_ALPHA ) return; if( ( self->spawnflags & 2 ) != 0 && activator->r.client && activator->s.team != TEAM_BETA ) return; if( ( self->spawnflags & 4 ) != 0 ) { edict_t *target; target = G_PickTarget( self->targetname ); if( target != NULL ) G_CallUse( target, self, activator ); return; } G_UseTargets( self, activator ); }
//QUAKED target_laser (0 .5 0) (-8 -8 -8) (8 8 8) START_ON RED GREEN BLUE YELLOW ORANGE FAT //When triggered, fires a laser. You can either set a target or a direction. //-------- KEYS -------- //angles: alternate "pitch, yaw, roll" angles method of aiming laser (default 0 0 0). //target : point this to a target_position entity to set the laser's aiming direction. //targetname : the activating trigger points to this. //notsingle : when set to 1, entity will not spawn in Single Player mode //notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes. //notduel : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes. (jal: todo) //notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes. //notctf : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes. (jal: todo) //-------- SPAWNFLAGS -------- //START_ON : when set, the laser will start on in the game. //RED : //GREEN : BLUE : //YELLOW : //ORANGE : //FAT : static void target_laser_think( edict_t *self ) { edict_t *ignore; vec3_t start; vec3_t end; trace_t tr; vec3_t point; vec3_t last_movedir; int count; // our lifetime has expired if( self->delay && ( self->wait * 1000 < level.time ) ) { if( self->r.owner && self->r.owner->use ) G_CallUse( self->r.owner, self, self->activator ); G_FreeEdict( self ); return; } if( self->spawnflags & 0x80000000 ) count = 8; else count = 4; if( self->enemy ) { VectorCopy( self->moveinfo.movedir, last_movedir ); VectorMA( self->enemy->r.absmin, 0.5, self->enemy->r.size, point ); VectorSubtract( point, self->s.origin, self->moveinfo.movedir ); VectorNormalize( self->moveinfo.movedir ); if( !VectorCompare( self->moveinfo.movedir, last_movedir ) ) self->spawnflags |= 0x80000000; } ignore = self; VectorCopy( self->s.origin, start ); VectorMA( start, 2048, self->moveinfo.movedir, end ); VectorClear( tr.endpos ); // shut up compiler while( 1 ) { G_Trace( &tr, start, NULL, NULL, end, ignore, MASK_SHOT ); if( tr.fraction == 1 ) break; // hurt it if we can if( ( game.edicts[tr.ent].takedamage ) && !( game.edicts[tr.ent].flags & FL_IMMUNE_LASER ) ) { if( game.edicts[tr.ent].r.client && self->activator->r.client ) { if( !GS_TeamBasedGametype() || game.edicts[tr.ent].s.team != self->activator->s.team ) G_Damage( &game.edicts[tr.ent], self, self->activator, self->moveinfo.movedir, self->moveinfo.movedir, tr.endpos, self->dmg, 1, 0, 0, self->count ); } else { G_Damage( &game.edicts[tr.ent], self, self->activator, self->moveinfo.movedir, self->moveinfo.movedir, tr.endpos, self->dmg, 1, 0, 0, self->count ); } } // if we hit something that's not a monster or player or is immune to lasers, we're done if( !game.edicts[tr.ent].r.client ) { if( self->spawnflags & 0x80000000 ) { edict_t *event; self->spawnflags &= ~0x80000000; event = G_SpawnEvent( EV_LASER_SPARKS, DirToByte( tr.plane.normal ), tr.endpos ); event->s.eventCount = count; event->s.colorRGBA = self->s.colorRGBA; } break; } ignore = &game.edicts[tr.ent]; VectorCopy( tr.endpos, start ); } VectorCopy( tr.endpos, self->s.origin2 ); G_SetBoundsForSpanEntity( self, 8 ); GClip_LinkEntity( self ); self->nextThink = level.time + 1; }