/* =========== G_SelectTremulousSpawnPoint Chooses a player start, deathmatch start, etc ============ */ gentity_t *G_SelectTremulousSpawnPoint( team_t team, vec3_t preference, vec3_t origin, vec3_t angles ) { gentity_t *spot = NULL; if( team == TEAM_ALIENS ) { if( level.numAlienSpawns <= 0 ) return NULL; spot = G_SelectSpawnBuildable( preference, BA_A_SPAWN ); } else if( team == TEAM_HUMANS ) { if( level.numHumanSpawns <= 0 ) return NULL; spot = G_SelectSpawnBuildable( preference, BA_H_SPAWN ); } //no available spots if( !spot ) return NULL; if( team == TEAM_ALIENS ) G_CheckSpawnPoint( spot->s.number, spot->s.origin, spot->s.origin2, BA_A_SPAWN, origin ); else if( team == TEAM_HUMANS ) G_CheckSpawnPoint( spot->s.number, spot->s.origin, spot->s.origin2, BA_H_SPAWN, origin ); VectorCopy( spot->s.angles, angles ); angles[ ROLL ] = 0; return spot; }
/* ================ 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 ) 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; }
/* =========== SelectTremulousSpawnPoint Chooses a player start, deathmatch start, etc ============ */ gentity_t *SelectTremulousSpawnPoint( team_t team, vec3_t preference, vec3_t origin, vec3_t angles ) { gentity_t *spot = NULL; if( team == TEAM_ALIENS ) spot = SelectAlienSpawnPoint( preference ); else if( team == TEAM_HUMANS ) spot = SelectHumanSpawnPoint( preference ); //no available spots if( !spot ) return NULL; if( team == TEAM_ALIENS ) G_CheckSpawnPoint( spot->s.number, spot->s.origin, spot->s.origin2, BA_A_SPAWN, origin ); else if( team == TEAM_HUMANS ) G_CheckSpawnPoint( spot->s.number, spot->s.origin, spot->s.origin2, BA_H_SPAWN, origin ); VectorCopy( spot->s.angles, angles ); angles[ ROLL ] = 0; return spot; }
/* ================ 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 = NULL; gentity_t *spot = NULL; while ( ( search = G_IterateEntitiesOfClass( search, 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; }
/* ================ 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 ); }