[quake3-commits] r1726 - trunk/code/game
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Tue Nov 3 08:28:53 EST 2009
Author: thilo
Date: 2009-11-03 08:28:52 -0500 (Tue, 03 Nov 2009)
New Revision: 1726
Modified:
trunk/code/game/g_active.c
trunk/code/game/g_client.c
trunk/code/game/g_local.h
trunk/code/game/g_main.c
trunk/code/game/g_team.c
trunk/code/game/g_team.h
Log:
Fix bug where game freezes in infinite loop because it doesn't find a spawn point on maps with many bot/human-only spawnpoints. Thanks Pan for reporting this
Modified: trunk/code/game/g_active.c
===================================================================
--- trunk/code/game/g_active.c 2009-11-02 16:17:10 UTC (rev 1725)
+++ trunk/code/game/g_active.c 2009-11-03 13:28:52 UTC (rev 1726)
@@ -625,7 +625,7 @@
}
}
#endif
- SelectSpawnPoint( ent->client->ps.origin, origin, angles );
+ SelectSpawnPoint( ent->client->ps.origin, origin, angles, qfalse );
TeleportPlayer( ent, origin, angles );
break;
Modified: trunk/code/game/g_client.c
===================================================================
--- trunk/code/game/g_client.c 2009-11-02 16:17:10 UTC (rev 1725)
+++ trunk/code/game/g_client.c 2009-11-03 13:28:52 UTC (rev 1726)
@@ -140,7 +140,7 @@
================
*/
#define MAX_SPAWN_POINTS 128
-gentity_t *SelectRandomDeathmatchSpawnPoint( void ) {
+gentity_t *SelectRandomDeathmatchSpawnPoint(qboolean isbot) {
gentity_t *spot;
int count;
int selection;
@@ -149,11 +149,19 @@
count = 0;
spot = NULL;
- while ((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL) {
- if ( SpotWouldTelefrag( spot ) ) {
+ while((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL && count < MAX_SPAWN_POINTS)
+ {
+ if(SpotWouldTelefrag(spot))
continue;
+
+ if(((spot->flags & FL_NO_BOTS) && isbot) ||
+ ((spot->flags & FL_NO_HUMANS) && !isbot))
+ {
+ // spot is not for this human/bot player
+ continue;
}
- spots[ count ] = spot;
+
+ spots[count] = spot;
count++;
}
@@ -172,49 +180,68 @@
Chooses a player start, deathmatch start, etc
============
*/
-gentity_t *SelectRandomFurthestSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles ) {
+gentity_t *SelectRandomFurthestSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles, qboolean isbot ) {
gentity_t *spot;
vec3_t delta;
float dist;
- float list_dist[64];
- gentity_t *list_spot[64];
+ float list_dist[MAX_SPAWN_POINTS];
+ gentity_t *list_spot[MAX_SPAWN_POINTS];
int numSpots, rnd, i, j;
numSpots = 0;
spot = NULL;
- while ((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL) {
- if ( SpotWouldTelefrag( spot ) ) {
+ while((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL)
+ {
+ if(SpotWouldTelefrag(spot))
continue;
+
+ if(((spot->flags & FL_NO_BOTS) && isbot) ||
+ ((spot->flags & FL_NO_HUMANS) && !isbot))
+ {
+ // spot is not for this human/bot player
+ continue;
}
+
VectorSubtract( spot->s.origin, avoidPoint, delta );
dist = VectorLength( delta );
- for (i = 0; i < numSpots; i++) {
- if ( dist > list_dist[i] ) {
- if ( numSpots >= 64 )
- numSpots = 64-1;
- for (j = numSpots; j > i; j--) {
+
+ for (i = 0; i < numSpots; i++)
+ {
+ if(dist > list_dist[i])
+ {
+ if (numSpots >= MAX_SPAWN_POINTS)
+ numSpots = MAX_SPAWN_POINTS - 1;
+
+ for(j = numSpots; j > i; j--)
+ {
list_dist[j] = list_dist[j-1];
list_spot[j] = list_spot[j-1];
}
+
list_dist[i] = dist;
list_spot[i] = spot;
+
numSpots++;
- if (numSpots > 64)
- numSpots = 64;
break;
}
}
- if (i >= numSpots && numSpots < 64) {
+
+ if(i >= numSpots && numSpots < MAX_SPAWN_POINTS)
+ {
list_dist[numSpots] = dist;
list_spot[numSpots] = spot;
numSpots++;
}
}
- if (!numSpots) {
- spot = G_Find( NULL, FOFS(classname), "info_player_deathmatch");
+
+ if(!numSpots)
+ {
+ spot = G_Find(NULL, FOFS(classname), "info_player_deathmatch");
+
if (!spot)
G_Error( "Couldn't find a spawn point" );
+
VectorCopy (spot->s.origin, origin);
origin[2] += 9;
VectorCopy (spot->s.angles, angles);
@@ -238,8 +265,8 @@
Chooses a player start, deathmatch start, etc
============
*/
-gentity_t *SelectSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles ) {
- return SelectRandomFurthestSpawnPoint( avoidPoint, origin, angles );
+gentity_t *SelectSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles, qboolean isbot ) {
+ return SelectRandomFurthestSpawnPoint( avoidPoint, origin, angles, isbot );
/*
gentity_t *spot;
@@ -278,19 +305,25 @@
use normal spawn selection.
============
*/
-gentity_t *SelectInitialSpawnPoint( vec3_t origin, vec3_t angles ) {
+gentity_t *SelectInitialSpawnPoint( vec3_t origin, vec3_t angles, qboolean isbot ) {
gentity_t *spot;
spot = NULL;
- while ((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL) {
- if ( spot->spawnflags & 1 ) {
+
+ while ((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL)
+ {
+ if(((spot->flags & FL_NO_BOTS) && isbot) ||
+ ((spot->flags & FL_NO_HUMANS) && !isbot))
+ {
+ continue;
+ }
+
+ if((spot->spawnflags & 0x01))
break;
- }
}
- if ( !spot || SpotWouldTelefrag( spot ) ) {
- return SelectSpawnPoint( vec3_origin, origin, angles );
- }
+ if (!spot || SpotWouldTelefrag(spot))
+ return SelectSpawnPoint(vec3_origin, origin, angles, isbot);
VectorCopy (spot->s.origin, origin);
origin[2] += 9;
@@ -1050,6 +1083,8 @@
index = ent - g_entities;
client = ent->client;
+ VectorClear(spawn_origin);
+
// find a spawn point
// do it before setting health back up, so farthest
// ranging doesn't count this client
@@ -1061,34 +1096,26 @@
spawnPoint = SelectCTFSpawnPoint (
client->sess.sessionTeam,
client->pers.teamState.state,
- spawn_origin, spawn_angles);
- } else {
- do {
- // the first spawn should be at a good looking spot
- if ( !client->pers.initialSpawn && client->pers.localClient ) {
- client->pers.initialSpawn = qtrue;
- spawnPoint = SelectInitialSpawnPoint( spawn_origin, spawn_angles );
- } else {
- // don't spawn near existing origin if possible
- spawnPoint = SelectSpawnPoint (
- client->ps.origin,
- spawn_origin, spawn_angles);
- }
-
- // Tim needs to prevent bots from spawning at the initial point
- // on q3dm0...
- if ( ( spawnPoint->flags & FL_NO_BOTS ) && ( ent->r.svFlags & SVF_BOT ) ) {
- continue; // try again
- }
- // just to be symetric, we have a nohumans option...
- if ( ( spawnPoint->flags & FL_NO_HUMANS ) && !( ent->r.svFlags & SVF_BOT ) ) {
- continue; // try again
- }
-
- break;
-
- } while ( 1 );
+ spawn_origin, spawn_angles,
+ !!(ent->r.svFlags & SVF_BOT));
}
+ else
+ {
+ // the first spawn should be at a good looking spot
+ if ( !client->pers.initialSpawn && client->pers.localClient )
+ {
+ client->pers.initialSpawn = qtrue;
+ spawnPoint = SelectInitialSpawnPoint(spawn_origin, spawn_angles,
+ !!(ent->r.svFlags & SVF_BOT));
+ }
+ else
+ {
+ // don't spawn near existing origin if possible
+ spawnPoint = SelectSpawnPoint (
+ client->ps.origin,
+ spawn_origin, spawn_angles, !!(ent->r.svFlags & SVF_BOT));
+ }
+ }
client->pers.teamState.state = TEAM_ACTIVE;
// always clear the kamikaze flag
Modified: trunk/code/game/g_local.h
===================================================================
--- trunk/code/game/g_local.h 2009-11-02 16:17:10 UTC (rev 1725)
+++ trunk/code/game/g_local.h 2009-11-03 13:28:52 UTC (rev 1726)
@@ -572,7 +572,7 @@
int TeamLeader( int team );
team_t PickTeam( int ignoreClientNum );
void SetClientViewAngle( gentity_t *ent, vec3_t angle );
-gentity_t *SelectSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles );
+gentity_t *SelectSpawnPoint (vec3_t avoidPoint, vec3_t origin, vec3_t angles, qboolean isbot);
void CopyToBodyQue( gentity_t *ent );
void respawn (gentity_t *ent);
void BeginIntermission (void);
Modified: trunk/code/game/g_main.c
===================================================================
--- trunk/code/game/g_main.c 2009-11-02 16:17:10 UTC (rev 1725)
+++ trunk/code/game/g_main.c 2009-11-03 13:28:52 UTC (rev 1726)
@@ -934,7 +934,7 @@
// 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 );
+ 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);
Modified: trunk/code/game/g_team.c
===================================================================
--- trunk/code/game/g_team.c 2009-11-02 16:17:10 UTC (rev 1725)
+++ trunk/code/game/g_team.c 2009-11-03 13:28:52 UTC (rev 1726)
@@ -977,7 +977,7 @@
/*
================
-SelectRandomDeathmatchSpawnPoint
+SelectRandomTeamSpawnPoint
go to a random point that doesn't telefrag
================
@@ -1033,13 +1033,13 @@
============
*/
-gentity_t *SelectCTFSpawnPoint ( team_t team, int teamstate, vec3_t origin, vec3_t angles ) {
+gentity_t *SelectCTFSpawnPoint ( team_t team, int teamstate, vec3_t origin, vec3_t angles, qboolean isbot ) {
gentity_t *spot;
spot = SelectRandomTeamSpawnPoint ( teamstate, team );
if (!spot) {
- return SelectSpawnPoint( vec3_origin, origin, angles );
+ return SelectSpawnPoint( vec3_origin, origin, angles, isbot );
}
VectorCopy (spot->s.origin, origin);
Modified: trunk/code/game/g_team.h
===================================================================
--- trunk/code/game/g_team.h 2009-11-02 16:17:10 UTC (rev 1725)
+++ trunk/code/game/g_team.h 2009-11-03 13:28:52 UTC (rev 1726)
@@ -79,7 +79,7 @@
void Team_InitGame(void);
void Team_ReturnFlag(int team);
void Team_FreeEntity(gentity_t *ent);
-gentity_t *SelectCTFSpawnPoint ( team_t team, int teamstate, vec3_t origin, vec3_t angles );
+gentity_t *SelectCTFSpawnPoint ( team_t team, int teamstate, vec3_t origin, vec3_t angles, qboolean isbot );
gentity_t *Team_GetLocation(gentity_t *ent);
qboolean Team_GetLocationMsg(gentity_t *ent, char *loc, int loclen);
void TeamplayInfoMessage( gentity_t *ent );
More information about the quake3-commits
mailing list