diff options
-rw-r--r-- | src/game/g_client.c | 130 | ||||
-rw-r--r-- | src/game/g_utils.c | 2 |
2 files changed, 42 insertions, 90 deletions
diff --git a/src/game/g_client.c b/src/game/g_client.c index 39854623..1061043e 100644 --- a/src/game/g_client.c +++ b/src/game/g_client.c @@ -156,7 +156,6 @@ G_SelectNearestDeathmatchSpawnPoint Find the spot that we DON'T want to use ================ */ -#define MAX_SPAWN_POINTS 128 gentity_t *G_SelectNearestDeathmatchSpawnPoint( vec3_t from ) { gentity_t *spot; @@ -164,7 +163,6 @@ gentity_t *G_SelectNearestDeathmatchSpawnPoint( vec3_t from ) float dist, nearestDist; gentity_t *nearestSpot; - nearestDist = 999999; nearestSpot = NULL; spot = NULL; @@ -173,7 +171,7 @@ gentity_t *G_SelectNearestDeathmatchSpawnPoint( vec3_t from ) VectorSubtract( spot->s.origin, from, delta ); dist = VectorLength( delta ); - if( dist < nearestDist ) + if( !nearestSpot || dist < nearestDist ) { nearestDist = dist; nearestSpot = spot; @@ -191,31 +189,32 @@ G_SelectRandomDeathmatchSpawnPoint go to a random point that doesn't telefrag ================ */ -#define MAX_SPAWN_POINTS 128 gentity_t *G_SelectRandomDeathmatchSpawnPoint( void ) { - gentity_t *spot; + gentity_t *spot, *search; int count; - int selection; - gentity_t *spots[ MAX_SPAWN_POINTS ]; count = 0; spot = NULL; - while( ( spot = G_Find( spot, FOFS( classname ), "info_player_deathmatch" ) ) != NULL ) + while( ( search = G_Find( search, FOFS( classname ), "info_player_deathmatch" ) ) != NULL ) { - if( SpotWouldTelefrag( spot ) ) + if( SpotWouldTelefrag( search ) ) continue; - spots[ count ] = spot; count++; + // this is the nth spot; choose it with probability 1/n + // so we definitely choose the first spot, we then have a 1/2 chance of + // replacing it with the second... + // it's pretty easy to see by induction that this works for all n + if( rand( ) % count == 0 ) + spot = search; } if( !count ) // no spots that won't telefrag return G_Find( NULL, FOFS( classname ), "info_player_deathmatch" ); - selection = rand( ) % count; - return spots[ selection ]; + return spot; } @@ -304,102 +303,45 @@ gentity_t *G_SelectRandomFurthestSpawnPoint ( vec3_t avoidPoint, vec3_t origin, /* ================ -G_SelectAlienSpawnPoint - -go to a random point that doesn't telefrag -================ -*/ -gentity_t *G_SelectAlienSpawnPoint( vec3_t preference ) -{ - gentity_t *spot; - int count; - gentity_t *spots[ MAX_SPAWN_POINTS ]; - - if( level.numAlienSpawns <= 0 ) - return NULL; - - count = 0; - spot = NULL; - - while( ( spot = G_Find( spot, FOFS( classname ), - BG_Buildable( BA_A_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_A_SPAWN, NULL ) != NULL ) - continue; - - spots[ count ] = spot; - count++; - } - - if( !count ) - return NULL; - - return G_ClosestEnt( preference, spots, count ); -} - - -/* -================ -G_SelectHumanSpawnPoint +G_SelectSpawnBuildable -go to a random point that doesn't telefrag +find the nearest buildable of the right type that is +spawned/healthy/unblocked etc. ================ */ -gentity_t *G_SelectHumanSpawnPoint( vec3_t preference ) +gentity_t *G_SelectSpawnBuildable( vec3_t preference, buildable_t buildable ) { - gentity_t *spot; - int count; - gentity_t *spots[ MAX_SPAWN_POINTS ]; - - if( level.numHumanSpawns <= 0 ) - return NULL; + gentity_t *search, *spot; - count = 0; - spot = NULL; + search = spot = NULL; - while( ( spot = G_Find( spot, FOFS( classname ), - BG_Buildable( BA_H_SPAWN )->entityName ) ) != NULL ) + while( ( search = G_Find( search, FOFS( classname ), + BG_Buildable( buildable )->entityName ) ) != NULL ) { - if( !spot->spawned ) + if( !search->spawned ) continue; - if( spot->health <= 0 ) + if( search->health <= 0 ) continue; - if( !spot->s.groundEntityNum ) + if( !search->s.groundEntityNum ) continue; - if( spot->clientSpawnTime > 0 ) + if( search->clientSpawnTime > 0 ) continue; - if( G_CheckSpawnPoint( spot->s.number, spot->s.origin, - spot->s.origin2, BA_H_SPAWN, NULL ) != NULL ) + if( G_CheckSpawnPoint( search->s.number, search->s.origin, + search->s.origin2, buildable, NULL ) != NULL ) continue; - spots[ count ] = spot; - count++; + if( !spot || DistanceSquared( preference, search->s.origin ) < + DistanceSquared( preference, spot->s.origin ) ) + spot = search; } - if( !count ) - return NULL; - - return G_ClosestEnt( preference, spots, count ); + return spot; } - /* =========== G_SelectSpawnPoint @@ -425,9 +367,19 @@ gentity_t *G_SelectTremulousSpawnPoint( team_t team, vec3_t preference, vec3_t o gentity_t *spot = NULL; if( team == TEAM_ALIENS ) - spot = G_SelectAlienSpawnPoint( preference ); + { + if( level.numAlienSpawns <= 0 ) + return NULL; + + spot = G_SelectSpawnBuildable( preference, BA_A_SPAWN ); + } else if( team == TEAM_HUMANS ) - spot = G_SelectHumanSpawnPoint( preference ); + { + if( level.numHumanSpawns <= 0 ) + return NULL; + + spot = G_SelectSpawnBuildable( preference, BA_H_SPAWN ); + } //no available spots if( !spot ) diff --git a/src/game/g_utils.c b/src/game/g_utils.c index 9e53fe7d..2e08afdf 100644 --- a/src/game/g_utils.c +++ b/src/game/g_utils.c @@ -770,7 +770,7 @@ Test a list of entities for the closest to a particular point gentity_t *G_ClosestEnt( vec3_t origin, gentity_t **entities, int numEntities ) { int i; - float nd, d = 1000000.0f; + float nd, d; gentity_t *closestEnt = NULL; for( i = 0; i < numEntities; i++ ) |