/* ================ G_SelectSpawnBuildable find the nearest buildable of the right type that is spawned/healthy/unblocked etc. ================ */ static gentity_t *G_SelectSpawnBuildable( vec3_t preference, buildable_t buildable ) { gentity_t *search, *spot; search = spot = NULL; while ( ( search = G_Find( search, FOFS( classname ), BG_Buildable( buildable )->entityName ) ) != NULL ) { if ( !search->spawned ) { continue; } if ( search->health <= 0 ) { continue; } if ( search->s.groundEntityNum == ENTITYNUM_NONE ) { continue; } if ( search->clientSpawnTime > 0 ) { continue; } if ( G_CheckSpawnPoint( search->s.number, search->s.origin, search->s.origin2, buildable, NULL ) != NULL ) { continue; } if ( !spot || DistanceSquared( preference, search->s.origin ) < DistanceSquared( preference, spot->s.origin ) ) { spot = search; } } return spot; }
/* ================== CheckAlmostCapture ================== */ void CheckAlmostCapture( gentity_t *self, gentity_t *attacker ) { gentity_t *ent; vec3_t dir; char *classname; // if this player was carrying a flag if ( self->player->ps.powerups[PW_REDFLAG] || self->player->ps.powerups[PW_BLUEFLAG] || self->player->ps.powerups[PW_NEUTRALFLAG] ) { // get the goal flag this player should have been going for if ( g_gametype.integer == GT_CTF ) { if ( self->player->sess.sessionTeam == TEAM_BLUE ) { classname = "team_CTF_blueflag"; } else { classname = "team_CTF_redflag"; } } else { if ( self->player->sess.sessionTeam == TEAM_BLUE ) { classname = "team_CTF_redflag"; } else { classname = "team_CTF_blueflag"; } } ent = NULL; do { ent = G_Find(ent, FOFS(classname), classname); } while (ent && (ent->flags & FL_DROPPED_ITEM)); // if we found the destination flag and it's not picked up if (ent && !(ent->r.svFlags & SVF_NOCLIENT) ) { // if the player was *very* close VectorSubtract( self->player->ps.origin, ent->s.origin, dir ); if ( VectorLength(dir) < 200 ) { self->player->ps.persistant[PERS_PLAYEREVENTS] ^= PLAYEREVENT_HOLYSHIT; if ( attacker->player ) { attacker->player->ps.persistant[PERS_PLAYEREVENTS] ^= PLAYEREVENT_HOLYSHIT; } } } } }
//------------------------------------------ void fx_target_beam_link( gentity_t *ent ) { gentity_t *target = NULL; vec3_t dir; target = G_Find( target, FOFS(targetname), ent->target ); if ( !target ) { Com_Printf( "bolt_link: unable to find target %s\n", ent->target ); G_FreeEntity( ent ); return; } ent->attackDebounceTime = level.time; if ( !target->classname || Q_stricmp( "info_null", target->classname ) ) {//don't want to set enemy to something that's going to free itself... actually, this could be bad in other ways, too... ent pointer could be freed up and re-used by the time we check it next G_SetEnemy( ent, target ); } VectorSubtract( target->s.origin, ent->s.origin, dir );//er, does it ever use dir? VectorNormalize( dir );//er, does it use len or dir? vectoangles( dir, ent->s.angles );//er, does it use s.angles? VectorCopy( target->s.origin, ent->s.origin2 ); if ( ent->spawnflags & 1 ) { // Do nothing ent->e_ThinkFunc = thinkF_NULL; } else { if ( !(ent->spawnflags & 8 )) // one_shot, only calls when used { // switch think functions to avoid doing the bolt_link every time ent->e_ThinkFunc = thinkF_fx_target_beam_think; ent->nextthink = level.time + FRAMETIME; } } ent->e_UseFunc = useF_fx_target_beam_use; gi.linkentity( ent ); }
/* ============== Use_Target_Lock ============== */ void Use_Target_Lock(gentity_t *ent, gentity_t *other, gentity_t *activator) { gentity_t *t = 0; while ((t = G_Find(t, FOFS(targetname), ent->target)) != NULL) { // G_Printf("target_lock locking entity with key: %d\n", ent->count); t->key = ent->key; if (t->key) { G_SetAASBlockingEntity(t, AAS_AREA_DISABLED); } else { G_SetAASBlockingEntity(t, AAS_AREA_ENABLED); } } }
/* ================= G_ScriptAction_Trigger syntax: trigger <aiName/scriptName> <trigger> Calls the specified trigger for the given ai character or script entity ================= */ qboolean G_ScriptAction_Trigger( gentity_t *ent, char *params ) { gentity_t *trent; char *pString, name[MAX_QPATH], trigger[MAX_QPATH], *token; int oldId; // get the cast name pString = params; token = COM_ParseExt( &pString, qfalse ); Q_strncpyz( name, token, sizeof(name) ); if (!name[0]) { G_Error( "G_Scripting: trigger must have a name and an identifier\n" ); } token = COM_ParseExt( &pString, qfalse ); Q_strncpyz( trigger, token, sizeof(trigger) ); if (!trigger[0]) { G_Error( "G_Scripting: trigger must have a name and an identifier\n" ); } // trent = AICast_FindEntityForName( name ); trent = NULL; if (trent) { // we are triggering an AI //oldId = trent->scriptStatus.scriptId; // AICast_ScriptEvent( AICast_GetCastState( trent->s.number ), "trigger", trigger ); return qtrue; } // look for an entity trent = G_Find( &g_entities[MAX_CLIENTS], FOFS(scriptName), name ); if (trent) { oldId = trent->scriptStatus.scriptId; G_Script_ScriptEvent( trent, "trigger", trigger ); // if the script changed, return false so we don't muck with it's variables return ((trent != ent) || (oldId == trent->scriptStatus.scriptId)); } G_Error( "G_Scripting: trigger has unknown name: %s\n", name ); return qfalse; // shutup the compiler }
void misc_viper_bomb_use (edict_t *self, edict_t *other, edict_t *activator) { edict_t *viper; self->solid = SOLID_BBOX; self->svflags &= ~SVF_NOCLIENT; self->s.effects |= EF_ROCKET; self->use = NULL; self->movetype = MOVETYPE_TOSS; self->prethink = misc_viper_bomb_prethink; self->touch = misc_viper_bomb_touch; self->activator = activator; viper = G_Find (NULL, FOFS(classname), "misc_viper"); VectorScale (viper->moveinfo.dir, viper->moveinfo.speed, self->velocity); self->timestamp = level.time; VectorCopy (viper->moveinfo.dir, self->moveinfo.dir); }
//================= //================= void Tag_PostInitSetup (void) { edict_t *e; vec3_t origin, angles; // automatic spawning of tag token if one is not present on map. e = G_Find (NULL, FOFS(classname), "dm_tag_token"); if(e == NULL) { e = G_Spawn(); e->classname = "dm_tag_token"; SelectSpawnPoint (e, origin, angles); VectorCopy(origin, e->s.origin); VectorCopy(origin, e->s.old_origin); VectorCopy(angles, e->s.angles); SP_dm_tag_token (e); } }
/* * G_ChooseNextMap */ static edict_t *G_ChooseNextMap( void ) { edict_t *ent = NULL; const char *next; if( *level.forcemap ) { return CreateTargetChangeLevel( level.forcemap ); } if( !( *g_maplist->string ) || g_maplist->string[0] == '\0' || g_maprotation->integer == 0 ) { // same map again return CreateTargetChangeLevel( level.mapname ); } else if( g_maprotation->integer == 1 ) { next = G_MapRotationNormal(); // not in the list, we go for the first one ent = CreateTargetChangeLevel( next ? next : level.mapname ); return ent; } else if( g_maprotation->integer == 2 ) { next = G_MapRotationRandom(); ent = CreateTargetChangeLevel( next ? next : level.mapname ); return ent; } if( level.nextmap[0] ) // go to a specific map return CreateTargetChangeLevel( level.nextmap ); // search for a changelevel ent = G_Find( NULL, FOFS( classname ), "target_changelevel" ); if( !ent ) { // the map designer didn't include a changelevel, // so create a fake ent that goes back to the same level return CreateTargetChangeLevel( level.mapname ); } return ent; }
void target_speaker_multiple (gentity_t *ent) { gentity_t *vis_dummy = NULL; if (!(ent->target)) { G_Error( "target_speaker missing target at pos %s", vtos( ent->s.origin ) ); } vis_dummy = G_Find (NULL, FOFS(targetname), ent->target); if(vis_dummy) { ent->s.otherEntityNum = vis_dummy->s.number; } else G_Error( "target_speaker cant find vis_dummy_multiple %s", vtos( ent->s.origin ) ); }
void teleporter_touch(edict_t * self, edict_t * other, cplane_t * plane, csurface_t * surf) { edict_t * dest; int i; if (!other->client) return; dest = G_Find(NULL, FOFS(targetname), self->target); if (!dest) { gi.dprintf("Couldn't find destination\n"); return; } // unlink to make sure it can't possibly interfere with KillBox gi.unlinkentity(other); VectorCopy(dest->s.origin, other->s.origin); VectorCopy(dest->s.origin, other->s.old_origin); other->s.origin[2] += 10; // clear the velocity and hold them in place briefly VectorClear(other->velocity); other->client->ps.pmove.pm_time = 160 >> 3; // hold time other->client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT; // draw the teleport splash at source and on the player self->owner->s.event = EV_PLAYER_TELEPORT; other->s.event = EV_PLAYER_TELEPORT; // set angles for (i = 0; i < 3; i++) other->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(dest->s.angles[i] - other->client->resp.cmd_angles[i]); VectorClear(other->s.angles); VectorClear(other->client->ps.viewangles); VectorClear(other->client->v_angle); // kill anything at the destination KillBox(other); gi.linkentity(other); }
void DropPortalSource( gentity_t *player ) { gentity_t *ent; gentity_t *destination; vec3_t snapped; // create the portal source ent = G_Spawn(); ent->s.modelindex = G_ModelIndex( "models/powerups/teleporter/tele_enter.md3" ); VectorCopy( player->s.pos.trBase, snapped ); SnapVector( snapped ); G_SetOrigin( ent, snapped ); VectorCopy( player->r.mins, ent->r.mins ); VectorCopy( player->r.maxs, ent->r.maxs ); ent->classname = "hi_portal source"; ent->s.pos.trType = TR_STATIONARY; ent->r.contents = CONTENTS_CORPSE | CONTENTS_TRIGGER; ent->takedamage = qtrue; ent->health = 200; ent->die = PortalDie; trap_LinkEntity( ent ); ent->count = player->client->portalID; player->client->portalID = 0; // ent->spawnflags = player->client->ps.persistant[PERS_TEAM]; ent->nextthink = level.time + 1000; ent->think = PortalEnable; // find the destination destination = NULL; while( (destination = G_Find(destination, FOFS(classname), "hi_portal destination")) != NULL ) { if( destination->count == ent->count ) { VectorCopy( destination->s.pos.trBase, ent->pos1 ); break; } } }
//================== void DBall_SelectSpawnPoint (edict_t *ent, vec3_t origin, vec3_t angles) { edict_t *bestspot; float bestdistance, bestplayerdistance; edict_t *spot; char *spottype; char skin[512]; strcpy(skin, Info_ValueForKey (ent->client->pers.userinfo, "skin")); if(!strcmp(dball_team1_skin->string, skin)) spottype = "dm_dball_team1_start"; else if(!strcmp(dball_team2_skin->string, skin)) spottype = "dm_dball_team2_start"; else spottype = "info_player_deathmatch"; spot = NULL; bestspot = NULL; bestdistance = 0; while ((spot = G_Find (spot, FOFS(classname), spottype)) != NULL) { bestplayerdistance = PlayersRangeFromSpot (spot); if (bestplayerdistance > bestdistance) { bestspot = spot; bestdistance = bestplayerdistance; } } if (bestspot) { VectorCopy (bestspot->s.origin, origin); origin[2] += 9; VectorCopy (bestspot->s.angles, angles); return; } // if we didn't find an appropriate spawnpoint, just // call the standard one. SelectSpawnPoint(ent, origin, angles); }
void camTrack_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { edict_t *player; edict_t *nextTarget; if (!plane) return; player = &g_edicts[1]; // Gotta be, since this is SP only //delete bullet model. G_FreeEdict(self->child); //hit wall. //if no next target, then abort. if (!self->owner->target) { camera_off(player); //fire targets. FireTarget2(self->owner); return; } //fire targets. FireTarget2(self->owner); nextTarget = G_Find(NULL,FOFS(targetname), self->owner->target); if (!nextTarget) { camera_off(player); return; } FirePathTarget(nextTarget); WarpToNextPoint(self, nextTarget); }
void camera_cam_firstthink( gentity_t *ent ) { gentity_t *target = NULL; vec3_t dang; vec3_t vec; if ( ent->track ) { target = G_Find( NULL, FOFS( targetname ), ent->track ); } if ( target ) { VectorSubtract( target->s.origin, ent->r.currentOrigin, vec ); vectoangles( vec, dang ); G_SetAngle( ent, dang ); } if ( ent->target ) { ent->nextthink = level.time + ( FRAMETIME / 2 ); ent->think = Think_SetupTrainTargets; } }
/* =========== SelectInitialSpawnPoint Try to find a spawn point marked 'initial', otherwise use normal spawn selection. ============ */ gentity_t *SelectInitialSpawnPoint( vec3_t origin, vec3_t angles ) { gentity_t *spot; spot = NULL; while ((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL) { if ( spot->spawnflags & 1 ) { break; } } if ( !spot || SpotWouldTelefrag( spot ) ) { return SelectSpawnPoint( vec3_origin, origin, angles ); } VectorCopy (spot->s.origin, origin); origin[2] += 9; VectorCopy (spot->s.angles, angles); return spot; }
//========================================== // AI_AddNode_Teleporter // Drop two nodes, one at trigger and other // at target entity //========================================== int AI_AddNode_Teleporter( edict_t *ent ) { vec3_t v1,v2; edict_t *dest; if (nav.num_nodes + 1 > MAX_NODES) return INVALID; dest = G_Find ( NULL, FOFS(targetname), ent->target ); if (!dest) return INVALID; //NODE_TELEPORTER_IN nodes[nav.num_nodes].flags = (NODEFLAGS_TELEPORTER_IN|NODEFLAGS_SERVERLINK); VectorCopy( ent->maxs, v1 ); VectorCopy( ent->mins, v2 ); nodes[nav.num_nodes].origin[0] = (v1[0] - v2[0]) / 2 + v2[0]; nodes[nav.num_nodes].origin[1] = (v1[1] - v2[1]) / 2 + v2[1]; nodes[nav.num_nodes].origin[2] = ent->mins[2]+32; nodes[nav.num_nodes].flags |= AI_FlagsForNode( nodes[nav.num_nodes].origin, ent ); nav.num_nodes++; //NODE_TELEPORTER_OUT nodes[nav.num_nodes].flags = (NODEFLAGS_TELEPORTER_OUT|NODEFLAGS_SERVERLINK); VectorCopy( dest->s.origin, nodes[nav.num_nodes].origin ); if ( ent->spawnflags & 1 ) // droptofloor nodes[nav.num_nodes].flags |= NODEFLAGS_FLOAT; else AI_DropNodeOriginToFloor( nodes[nav.num_nodes].origin, NULL ); nodes[nav.num_nodes].flags |= AI_FlagsForNode( nodes[nav.num_nodes].origin, ent ); // link from teleport_in AI_AddLink( nav.num_nodes-1, nav.num_nodes, LINK_TELEPORT ); nav.num_nodes++; return nav.num_nodes -1; }
/* ================= G_ScriptAction_AlertEntity syntax: alertentity <targetname> Arnout: modified to target multiple entities with the same targetname Martin - dumped from 1.4 to maybe fix the dam/tram bugs...3/20/08 ================= */ qboolean G_ScriptAction_AlertEntity( gentity_t *ent, char *params ) { gentity_t *alertent = NULL; qboolean foundalertent = qfalse; if (!params || !params[0]) { G_Error( "G_Scripting: alertentity without targetname\n" ); } // find this targetname while(1) { alertent = G_Find( alertent, FOFS(targetname), params ); if (!alertent ) { if( !foundalertent ) G_Error( "G_Scripting: alertentity cannot find targetname \"%s\"\n", params ); else break; } foundalertent = qtrue; if (alertent->client) { // call this entity's AlertEntity function if (!alertent->AIScript_AlertEntity) { G_Error( "G_Scripting: alertentity \"%s\" (classname = %s) doesn't have an \"AIScript_AlertEntity\" function\n", params, alertent->classname ); } alertent->AIScript_AlertEntity (alertent); } else { if (!alertent->use) { G_Error( "G_Scripting: alertentity \"%s\" (classname = %s) doesn't have a \"use\" function\n", params, alertent->classname ); } alertent->use (alertent, NULL, NULL); } } return qtrue; } // ********** END MARTIN 1.4 DUMP
void GetNextTrack( gentity_t *ent ) { gentity_t *track = NULL; gentity_t *next; gentity_t *choice[MAXCHOICES]; int num_choices = 0; int rval; next = ent->nextTrain; if ( !( next->track ) ) { G_Printf( "NULL track name for %s on %s\n", ent->classname, next->targetname ); return; } while ( 1 ) { track = G_Find( track, FOFS( targetname ), next->track ); if ( !track ) { break; } choice[num_choices++] = track; if ( num_choices == MAXCHOICES ) { break; } } if ( !num_choices ) { G_Printf( "GetNextTrack didnt find a track\n" ); return; } rval = rand() % num_choices; ent->nextTrain = NULL; ent->target = choice[rval]->targetname; }
/*QUAKED target_script_trigger (1 .7 .2) (-8 -8 -8) (8 8 8) must have an aiName must have a target when used it will fire its targets */ void target_script_trigger_use(gentity_t *ent, gentity_t *other, gentity_t *activator) { // START Mad Doctor I changes, 8/16/2002 qboolean found = qfalse; // for all entities/bots with this ainame gentity_t *trent = NULL; // Are we using ainame to find another ent instead of using scriptname for this one? if (ent->aiName) { // Find the first entity with this name trent = G_Find(trent, FOFS(scriptName), ent->aiName); // Was there one? if (trent) { // We found it found = qtrue; // Play the script G_Script_ScriptEvent(trent, "trigger", ent->target); } // if (trent)... } // if (ent->aiName)... // Use the old method if we didn't find an entity with the ainame if (!found) { if (ent->scriptName) { G_Script_ScriptEvent(ent, "trigger", ent->target); } } G_UseTargets(ent, other); }
void target_lightramp_use (edict_t *self, edict_t *other, edict_t *activator) { if (!self) { return; } if (!self->enemy) { edict_t *e; // check all the targets e = NULL; while (1) { e = G_Find (e, FOFS(targetname), self->target); if (!e) break; if (strcmp(e->classname, "light") != 0) { gi.dprintf("%s at %s ", self->classname, vtos(self->s.origin)); gi.dprintf("target %s (%s at %s) is not a light\n", self->target, e->classname, vtos(e->s.origin)); } else { self->enemy = e; } } if (!self->enemy) { gi.dprintf("%s target %s not found at %s\n", self->classname, self->target, vtos(self->s.origin)); G_FreeEdict (self); return; } } self->timestamp = level.time; target_lightramp_think (self); }
/*QUAKED target_kill (.5 .5 .5) (-8 -8 -8) (8 8 8) kill_user_too Kills the activator. (default) If targets, they will be killed when this is fired "kill_user_too" will still kill the activator when this ent has targets (default is only kill targets, not activator) */ void target_kill_use(gentity_t *self, gentity_t *other, gentity_t *activator) { gentity_t *targ = NULL; if(self->spawnflags & 1) // kill usertoo { G_Damage(activator, NULL, NULL, NULL, NULL, 100000, DAMAGE_NO_PROTECTION, MOD_TELEFRAG); } while((targ = G_Find(targ, FOFS(targetname), self->target)) != NULL) { if(targ->aiCharacter) // (SA) if it's an ai character, free it nicely { targ->aiInactive = qtrue; } else { // make sure it isn't going to respawn or show any events targ->nextthink = 0; if(targ == activator) { continue; } // RF, script_movers should die! if(!Q_stricmp(targ->classname, "script_mover") && targ->die) { targ->die(targ, self, self, targ->health, 0); continue; } trap_UnlinkEntity(targ); targ->use = 0; targ->touch = 0; targ->nextthink = level.time + FRAMETIME; targ->think = G_FreeEntity; } } }
//--------------------------------------------------------- void WP_FireDetPack( gentity_t *ent, qboolean alt_fire ) //--------------------------------------------------------- { if ( !ent || !ent->client ) { return; } if ( alt_fire ) { if ( ent->client->ps.eFlags & EF_PLANTED_CHARGE ) { gentity_t *found = NULL; // loop through all ents and blow the crap out of them! while (( found = G_Find( found, FOFS( classname ), "detpack" )) != NULL ) { if ( found->activator == ent ) { VectorCopy( found->currentOrigin, found->s.origin ); found->e_ThinkFunc = thinkF_WP_Explode; found->nextthink = level.time + 100 + random() * 100; G_Sound( found, G_SoundIndex( "sound/weapons/detpack/warning.wav" )); // would be nice if this actually worked? AddSoundEvent( NULL, found->currentOrigin, found->splashRadius*2, AEL_DANGER ); AddSightEvent( NULL, found->currentOrigin, found->splashRadius*2, AEL_DISCOVERED, 100 ); } } ent->client->ps.eFlags &= ~EF_PLANTED_CHARGE; } } else { WP_DropDetPack( ent, wpMuzzle, wpFwd ); ent->client->ps.eFlags |= EF_PLANTED_CHARGE; } }
/* ================ G_SelectHumanSpawnPoint go to a random point that doesn't telefrag ================ */ gentity_t *G_SelectHumanSpawnPoint( vec3_t preference ) { gentity_t *spot; int count; gentity_t *spots[ MAX_SPAWN_POINTS ]; if( level.numHumanSpawns <= 0 ) return NULL; count = 0; spot = NULL; while( ( spot = G_Find( spot, FOFS( classname ), BG_Buildable( BA_H_SPAWN )->entityName ) ) != NULL ) { if( !spot->spawned ) continue; if( spot->health <= 0 ) continue; if( !spot->s.groundEntityNum ) continue; if( spot->clientSpawnTime > 0 ) continue; if( G_CheckSpawnPoint( spot->s.number, spot->s.origin, spot->s.origin2, BA_H_SPAWN, NULL ) != NULL ) continue; spots[ count ] = spot; count++; } if( !count ) return NULL; return G_ClosestEnt( preference, spots, count ); }
/* * The ugly as hell coop spawnpoint fixup function. * While coop was planed by id, it wasn't part of * the initial release and added later with patch * to version 2.00. The spawnpoints in some maps * were SNAFU, some have wrong targets and some * no name at all. Fix this by matching the coop * spawnpoint target names to the nearest named * single player spot. */ void SP_FixCoopSpots(edict_t *self) { edict_t *spot; vec3_t d; if (!self) { return; } spot = NULL; while (1) { spot = G_Find(spot, FOFS(classname), "info_player_start"); if (!spot) { return; } if (!spot->targetname) { continue; } VectorSubtract(self->s.origin, spot->s.origin, d); if (VectorLength(d) < 550) { if ((!self->targetname) || (Q_stricmp(self->targetname, spot->targetname) != 0)) { self->targetname = spot->targetname; } return; } } }
void misc_weapon_shooter_aim( gentity_t *self ) { //update my aim if ( self->target ) { gentity_t *targ = G_Find( NULL, FOFS(targetname), self->target ); if ( targ ) { self->enemy = targ; VectorSubtract( targ->currentOrigin, self->currentOrigin, self->client->renderInfo.muzzleDir ); VectorCopy( targ->currentOrigin, self->pos1 ); vectoangles( self->client->renderInfo.muzzleDir, self->client->ps.viewangles ); SetClientViewAngle( self, self->client->ps.viewangles ); //FIXME: don't keep doing this unless target is a moving target? self->nextthink = level.time + FRAMETIME; } else { self->enemy = NULL; } } }
/* ================== FindIntermissionPoint This is also used for spectator spawns ================== */ void FindIntermissionPoint( void ) { gentity_t *ent, *target; vec3_t dir; // find the intermission spot ent = G_Find (NULL, FOFS(classname), "info_player_intermission"); if ( !ent ) { // the map creator forgot to put in an intermission point... SelectSpawnPoint ( vec3_origin, level.intermission_origin, level.intermission_angle, qfalse ); } else { VectorCopy (ent->s.origin, level.intermission_origin); VectorCopy (ent->s.angles, level.intermission_angle); // if it has a target, look towards it if ( ent->target ) { target = G_PickTarget( ent->target ); if ( target ) { VectorSubtract( target->s.origin, level.intermission_origin, dir ); vectoangles( dir, level.intermission_angle ); } } } }
void target_laser_start(gentity_t *self) { gentity_t *ent; self->s.eType = ET_BEAM; if(self->target) { ent = G_Find(NULL, FOFS(targetname), self->target); if(!ent) { G_Printf("%s at %s: %s is a bad target\n", self->classname, vtos(self->s.origin), self->target); } self->enemy = ent; } else { G_SetMovedir(self->s.angles, self->movedir); } self->use = target_laser_use; self->think = target_laser_think; if(!self->damage) { self->damage = 1; } if(self->spawnflags & 1) { target_laser_on(self); } else { target_laser_off(self); } }
void EAVYSpawnTeamNearFlag(edict_t *flag) { edict_t *spot = NULL; float dist; vec3_t v; while(spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) { VectorSubtract (spot->s.origin, flag->s.origin, v); dist = VectorLength (v); if (EAVY_RESTRICTED_RADIUS > dist) { if (!strcmp(flag->classname, "item_flag_team1")) spot->classname = "info_player_team1"; if (!strcmp(flag->classname, "item_flag_team2")) spot->classname = "info_player_team2"; spot->svflags |= SVF_NOCLIENT; spot->solid = SOLID_NOT; ED_CallSpawn (spot); } } }
gentity_t *SelectNearestDeathmatchSpawnPoint( vec3_t from ) { gentity_t *spot; vec3_t delta; float dist, nearestDist; gentity_t *nearestSpot; nearestDist = 999999; nearestSpot = NULL; spot = NULL; while ((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL) { VectorSubtract( spot->s.origin, from, delta ); dist = VectorLength( delta ); if ( dist < nearestDist ) { nearestDist = dist; nearestSpot = spot; } } return nearestSpot; }
static void target_teleporter_use( edict_t *self, edict_t *other, edict_t *activator ) { edict_t *dest; if( !G_PlayerCanTeleport( activator ) ) return; if( ( self->s.team != TEAM_SPECTATOR ) && ( self->s.team != activator->s.team ) ) return; if( self->spawnflags & 1 && activator->r.client->ps.pmove.pm_type != PM_SPECTATOR ) return; dest = G_Find( NULL, FOFS( targetname ), self->target ); if( !dest ) { if( developer->integer ) G_Printf( "Couldn't find destination.\n" ); return; } G_TeleportPlayer( activator, dest ); }